Difference between revisions of "Coding In C"

From FreeSpace Wiki
Jump to: navigation, search
m (category)
(Tutorial One - Baby Steps)
 
Line 115: Line 115:
  
  
<pre>!#include <stdio.h></pre>
+
<pre>#include <stdio.h></pre>
  
 
This line puts the contents of the file "stdio.h" into the current source code file after it's loaded into memory but before it's compiled. The '<' and '>' tell the compiler that it's a library file - that is, it's not part of the current program but in the compiler's own file list. We need this file to get the function declaration for puts().
 
This line puts the contents of the file "stdio.h" into the current source code file after it's loaded into memory but before it's compiled. The '<' and '>' tell the compiler that it's a library file - that is, it's not part of the current program but in the compiler's own file list. We need this file to get the function declaration for puts().

Latest revision as of 05:02, 6 May 2019

Note: While the following guide is a starter, the book The C Programming Language, Second Edition by Brian W. Kernighan and Dennis M. Ritchie, is considered one of the best books on the C language.

File types

There are two main types of file types in C/C++; .c/.cpp files, and .h files. .c/.cpp files are the meat of the source code; they contain the actual function and variable definitions. When a program is built, it is compiled to create machine-readable code. To form a complete program, the machine code is linked with other compiled .c/.cpp files to form the complete program (the .exe).

.h files contain code, such as class, function, or struct definitions, that is used in multiple files but usually doesn't really do anything when the program is built.

Comments

Anything after // is considered a comment and ignored. Also, anything between a /* and a */ is considered as well (This is called a block comment). You may not put block comments inside of each other, although you can put pretty much anything else in them.

Note that comments are not ignored if they are inside strings (read on to find out what strings are!).

Comments Example

//I'm a comment!
/* So am I.*/
/* Look, you can do //this and //this! */
char String[] = "//I look like a comment but I'm really a string.";

Variables

C and C++ have a number of different types of variables; these are slices of memory that hold information. Because all variables are stored in binary, they are interchangeable, to a degree. All variables are case sensitive

For example, an int is an integer, or a number without any fractions or decimals; -2,-1,0,1,2,3,4,5...etc. An integer is 4 bytes, or 32-bits, long.

Another important type of variable is char. A char is one byte (8 bits) in size. It's essentially a shorter int, except it's most commonly used to represent a character, that is, letters and numbers and such. This means that any given letter is also a number; 'A' is 65, for example. This text->number conversion is called ASCII. Single quotation marks are used to denote a character. For example, 'A'

A collection of characters is called a string; this isn't really a variable, however, it is standard. A string is a series of characters followed by a null character, or a char with a value of 0. (NOT the character '0'; that would be 48). Double quotation marks are used to denote a string. So, "This is a string". 'This is not a string'.

If you want to use decimals or fractions you'll have to use a float or a double. A float is the same size as an int, except it can be fractions. A double is twice as large as an int (8 bytes) but can be much more accurate than a float.

Finally, all the above integers can be prefixed with unsigned; this means that the variable only contains positive values. The extern prefix indicates that the variable exists, but is in some other file, so the compiler should let it be used. (The linker will complain if it doesn't really exist). const means that the variable can't be changed by the program after it's built, which lets addtional optimizations be performed. Some other prefixes are short and long - look them up if you're interested.

Variable example

int i;                   //Create the variable i.
i = 42;                  //Set i equal to 42
int j = 94;              //Create the variable j and set it to 94
j = -1 * (i * j + 1138); //You can also use arithmetic signs - Now j is -5086!

Arrays

An array is a series of the same type of variable. So, a string would be an array of chars. An individual variable in an array is usually called an element

Array example

int Array[2];               //Create an integer array with two integers
Array~[0] = 42;              //Set the first integer to 42
Array~[1] = 94;              //Set the second integer to 94
char String[] = "Hello!";   //Create an array of chars (a string) and autosize it to whatever size the given string is

Pointers

Pointers are difficult to grasp and work with, to say the least, but they're worth it. A pointer is basically the address of a particular variable (sometimes a function). Think of them as the address to a house, or the URL to a site - they aren't the actual house or site, but they let you get to it.

There are two important characters with pointers - & and *. & is used to change a variable to the address of a variable. So, &variable would give you the address of a variable.

The asterisk is the reverse of &. It means the variable at the address given. In other words, *(&variable) is the same thing as variable.

However, the asterisk can also be used to declare a pointer, a special type of variable. Confused yet? Here's an example:

Pointer example

int i = 42;         //Our favorite integer, i
int *integerptr;    //This defines a pointer to an integer.
integerptr = &i;    //integerptr now points to i
(*integerptr) = 94; //We just changed the value of i!

Functions

A function is a collection of instructions (usually other functions). Every function has a return type - even if it doesn't. A function with no return type has a return type of void. Otherwise, a function may return with any of the above variable types (A function can't really return a string or array, although it can return a pointer to one).

Functions can also be given arguments, so one function can be used in different places. These arguments can be the same types as a function's return types. This means you can take the return of one function and plug it into another function's arguments.

There are two steps to creating a function. Actually writing the function, and optionally declaring it. Thus, you can declare a function in a header file and use that function through your entire project, but only have the meat of it in one spot. You must declare or write out the function before you use it.

Note that the arguments to a function are not really the variables that are plugged into them. So, if you want to change a variable from inside a function , you will probably have to use a pointer. This is called passing by reference

Function example

void func1(int a, float b);  //Declare func1
int func2()                  //Define func2
{
	return 1;            //func2 returns integer 1;
}
int func3(int c)             //Define func3
{
	func1(c, c + .5);    //execute func1
	return c;            //return c;
}

void func1(int a, float b)     //Define func1. It doesn't do anything, basically.
{
	float z = a + b;       //Make a new variable and add up a and b in it
}

void Execute()                 //You can't execute a function except from inside another.
{
	func1(func2(), func3(func2())); //What will z be?
}

Tutorial One - Baby Steps

To start out, I'll give a classic example - a "Hello, World!" program written in C. Are you ready? Here it is...

#include <stdio.h>

int main(int argc, char** argv)
{
	puts("Hello, world!");
	return 0;
}

That wasn't too bad, was it? Here's what each line does:


#include <stdio.h>

This line puts the contents of the file "stdio.h" into the current source code file after it's loaded into memory but before it's compiled. The '<' and '>' tell the compiler that it's a library file - that is, it's not part of the current program but in the compiler's own file list. We need this file to get the function declaration for puts().

The entire line is called a preprocessor directive; that's what the '#' is for. The preprocessor does everything before the code is compiled, adding or replacing source code before it's sent off to the compiler. It's useful if you want to make it easy to completely remove a feature from a program.

int main(int argc, char** argv)

This defines the main function, which is where execution in a C program always starts. Argc is the number of command-line arguments, argv is the array of command-line arguments. (ie argv[0] might be "-fps")

{

Starts the main function's code block

puts("Hello, world!");

This function writes "Hello, world!" to the command-line, or console if you're on Linux.

return 0;

This can return pretty much anything you like, as long as it's an integer.

}

Ends the function block

That's it! A working C program!

Scope

The scope of a variable is the area you can get at it. A variable created inside a function only exists inside that function. Basically, anywhere you see brackets like { or } defines a code block. Any time you see these, variables created inside them will only exist inside of them.

Scope Example

int a = 1;
void func1()
{
	//You can access a here, but not c or d
	int b;
}

void func2()
{
	//You can access a here, but not b or d
	if(a)
	{
		int d = 2;
	}
}

Flow control - If statement

If the code in the parentheses is true, or a nonzero value, then the code statement immediately after it or inside the code block immediately after it is executed. After if, else if may be used to define an alternate option. Or, else may be used to define if none of the else or else if blocks are true

If example

int a = 1;
int b = 2;
if(a == 0)
{
	//Do something fun if a is 0
}
else if(a == 1)
{
	//Do something else if a is 1
}
else if(a == 1 && b == 2)
{
	//If a is 1, and b is 2, do something here.
	//With the above values, this is what would happen.
}
else
{
	//Otherwise, do this.
}

Flow control - while statement.

While the code in the parentheses is true or a nozero value, then the code statement immediately after it or inside the code block immediately after it is executed.

While example

int i;         //Create the variable i
void DoStuff();//Declare teh function DoStuff

i = 0;         //Make i be 0
while(i < 42)  //While this is true, do whatever's after this
{
	DoStuff();
	i++;   //++ is shorthand for "Add 1 to the variable after this line of code".
	//++i; //This would be shorthand for "Add 1 to the variable before this line of code"
               //Replace with -- for "Subtract one from"
}

Flow control - for statement

Usually used to go through array values; essentially a variant of the while loop

For example

//This does the same thing as the while example
int i;
void DoStuff();

for(i = 0; i < 42; i++)
{
	DoStuff();
}

Flow control - switch

Execute the code after the case statement that matches the value in the parentheses.

Switch example

//Declare some functions
void DoFunStuff();
void DoSadStuff();
void DoOtherStuff();

//Give ourselves a variable
int a = 2;

switch(a)
{
	case 0:        		//If a is 0...
		DoFunStuff();	//...Do fun stuff!
		break;		//We're done, jump to the end of the code block.
	case 1:        		//If a is 1...
		DoSadStuff();	//...aww, crap, we gotta do sad stuff.
		break;
	default:		//If none of the above match...
		DoOtherStuff();	//...Do some other stuff.
				//Since a IS 2, we'll be doing this other stuff.
		break;
}

Structs

Structs are a block of different types of variables. They help organize code, since then you can group similar variables together. For example:

Struct Example

struct Person
{
	char name[128];     //Name can *only* be 128 letters long, including spaces
	unsigned int age;   //Granted, ints range from -2,147,483,648 to 2,147,483,648 - but just in case...
	unsigned int weight;//Who has negative weight?

}; //<-- this little semicolon is important. Remember him.

//Now we have a function that takes a Person as an argument.
int CarlEatClone(Person poor_fellow)
{
	for(;poor_Fellow.weight > 0; poor_fellow.weight--);     //Simulate this poor fellow being digested.

	//Note that no one is actually harmed, because the poor_fellow is actually a copy.
	//Also note how "weight" inside poor_fellow is referenced
}
//Use like this:
//CarlEatClone(TerranGuy);

//In this function, poor_fellow must be a pointer
int CarlEat(Person *poor_fellow)
{
	for(;poor_fellow->weight > 0; poor_fellow->weight--);

	//Note again how weight is referenced, now that poor_fellow is a pointer
	//No cloning is involved here...poor guy.
}
//Use like this:
//CarlEat(&TerranGuy);

Written by WMCoolmon