520 likes | 591 Views
C Tutorial. Adapted from Wei Qian’s C tutorial slides. What we do. Hello World Program Data Types & Variables printf() Arithmetic & Logical Operations Conditionals Loops Arrays & Strings. Pointers Functions Command-Line Argument Data Structure Memory Allocation Programming Tips.
E N D
C Tutorial Adapted from Wei Qian’s C tutorial slides.
What we do • Hello World Program • Data Types & Variables • printf() • Arithmetic & Logical Operations • Conditionals • Loops • Arrays & Strings
Pointers • Functions • Command-Line Argument • Data Structure • Memory Allocation • Programming Tips
Hello World Program • How to compile $ gcchello.c –o hello gcc is the GNU C compiler; gcc is the compiling command. hello.c is the source file, and hello is compiler-generated executable file. • The source code #include <stdio.h> int main() { printf("Hello World\n"); return(0); } • How to execute $ ./hello “./ ” indicates the following file “hello” resides under the current execution directory.
Data Types & Variables • Data Types char -> character variable 1 bytes int -> integer variable 4 short -> short integer 2 long -> long integer 4 float -> single precision real number 4 double -> double precision real variable 8 unsigned -> can’t be used with float and double type. unsigned variables can not represent negative values.
Variable Declaration int length = 100; char num = ‘9’; //The actual value is 57 float deposit = 240.5; unsigned short ID = 0x5544; Try the following statements, and see what happens unsigned char value = -1; printf(“The value is %d \n”, value); unsignedchar value = 300; printf(“The value is %d \n”, value);
unsigned char value = -1; printf(“The value is %d \n”, value); The value is 255. unsignedchar value = 300; printf(“The value is %d \n”, value); The value is 44.
Local variable Local variables are declared within the body of a function, and can only be used within that function. • Static variable Another class of local variable is the static type. It is specified by the keyword static in the variable declaration. The most striking difference from a non-static local variable is, a static variable is not destroyed on exit from the function. • Global variable A global variable declaration looks normal, but is located outside any of the program's functions. So it is accessible to all functions.
An example int global = 10; //global variable int func (int x) { static int stat_var; //static local variable int temp; //(normal) local variable int name[50]; //(normal) local variable …… }
printf() The printf() function can be instructed to print integers, floats and string properly. • The general syntax is printf( “format”, variables); • An example int stud_id = 5200; char * name = “Mike”; printf(“%s ‘s ID is %d \n”, name, stud_id);
Format Identifiers %d decimal integers %x hex integer %c character %f float and double number %s string %p pointer • How to specify display space for a variable printf(“The student id is %5d \n”, stud_id); The value of stud_id will occupy 5 characters space in the print-out.
Why “\n” It introduces a new line on the terminal screen. • More about printf() man printf
Arithmetic Operations • Arithmetic operators int i = 10; int j = 15; int add = i + j; int diff = j – i; int product = i * j; int quotient = j / i; Int residual = j % i; i++; //Increase by 1 i--; //Decrease by 1
Comparing them int i = 10; int j = 15; float k = 15.0; j / i = ? j % i = ? k / i = ? k % i = ? • The Answer j / i = 1; j % i = 5; k / i = 1.5; k % i It is illegal.
int grade[2]; // A=4, B=3, C=2, D=1, F=0 int hour[2]; // credit hour int total_grade = grade[0]*hour[0] + grade[1]*hour[1]; int total_hour = hour[0] + hour[1]; float gpa = total_grade / total_hour; • What’s wrong with the following code: • Always gets an integer GPA. E.g. if grades are A and B, and hours are 3 and 2. correct gpa = (4*3+3*2) / 5 = 3.6, but the above program generates gpa=3.0 • How to fix? float gpa = total_grade * 1.0 / total_hour;
Logical Operations • What is “true” and “false” in C In C, there is no specific data type to represent “true” and “false”. C uses value “0” to represent “false”, and uses non-zero value to stand for “true”. • Logical Operators A && B => A and B A || B => A or B A == B => Is A equal to B? A != B => Is A not equal to B?
A > B => Is A greater than B? A >= B => Is A greater than or equal to B? A < B => Is A less than B? A <= B => Is A less than or equal to B? • Don’t be confused && and || have different meanings from & and |. & and | are bitwise operators. • Some practices Please compute the value of the following logical expressions?
inti = 10; int j = 15; int k = 15; int m = 0; if( i < j && j < k) => if( i != j || k < j) => if( j<= k || i > k) => if( j == k && m) => if(i) => if(m || j && i ) => inti = 10; int j = 15; int k = 15; int m = 0; if( i < j && j < k) => false if( i != j || k < j) => true if( j<= k || i > k) => true if( j == k && m) => false if(i) => true if(m || j && i ) => true Did you get the correct answers?
Conditionals • if statement Three basic formats, if (expression){ statement … } if (expression) { statement … }else{ statement … } if (expression) { statement… }else if (expression) { statement… }else{ statement… }
The switch statement switch (expression) { case item1: statement; break; case item2: statement; break; default: statement; break; } • An example if(score >= 90){ a_cnt ++; }else if(score >= 80){ b_cnt++; }else if(score >= 70){ c_cnt++; }else if (score>= 60){ d_cnt++ }else{ f_cnt++ }
What does Func( ‘B’ ) return? intFunc( char c ) int grade; switch ( c ) { case ‘A’: grade = 4; case ‘B’: grade = 3; case ‘C’: grade = 2; } return grade; } • Answer: 2! • Reason: ‘case’ is a label. Jumps to a location inside switch and executes sequentially. • Solution: break!
Correct version: int Func( char c ) int grade; switch ( c ) { case ‘A’: grade = 4; break; case ‘B’: grade = 3; break; case ‘C’: grade = 2; break; } return grade; } • What’s wrong with the code? • If c is not A or B or C, return an arbitrary integer. • Solution: default!
int Func( char c ) int grade; switch ( c ) { case ‘A’: grade = 4; break; case ‘B’: grade = 3; break; case ‘C’: grade = 2; break; default: grade = 0; // or assert(false) or anything you like } return grade; }
Loops • for statement for (expression1; expression2; expression3){ statement… } expression1 initializes; expression2 is the terminate test; expression3 is the modifier • An example int x; for (x=0; x<3; x++) { printf("x=%d \n",x); }
The while statement while (expression) { statement … } while loop exits only when the expression is false. • An example int x = 0; while (x<3) { printf("x=%d \n",x); x++; }
Arrays & Strings • Arrays int ids[50]; char name[100]; inttable_of_num[30][40]; • Accessing an array ids[0] = 40; i = ids[1] + j; table_of_num[3][4] = 100; Note: In C (and Java) Array subscripts start at 0 and end one less than the array size. • A common mistake: int ids[50]; ids[50] = 98; // ERROR: array out of bound!!!
Strings Strings are defined as arrays of characters. The only difference from a character array is, a symbol “\0” is used to indicate the end of a string. For example, suppose we have a character array, char name[8], and we store into it a string “Dave”. Note: the length of this string 4, but it occupies 5 bytes.
Functions Functions are easy to use; they allow complicated programs to be broken into small blocks, each of which is easier to write, read, and maintain. • How a function looks like returntype function_name(parameters…) { localvariables declaration; functioncode; return result; }
Sample function int addition(int x, int y) { int add; add = x + y; return add; } • How to make a call? int main() { int result; inti = 5, j = 6; result = addition(i, j); return 0; }
Pointers Pointer is the most beautiful part of C, but also brings most trouble to C programmers. Over 90% bugs in the C programs came from pointers. • What is a pointer A pointer is a variable which contains the address in memory of another variable. In C we have a specific type for pointers. Either it is a “int*”, “char*”, “void*”, it all occupy 4 bytes. But first study memory layout...
0 4 8 Memory word 0 word 1 word 2 • A sequential list of words, starting from 0. • 32bit architecture (e.g. Win32 programming): each word is 4 bytes. • A 256MB RAM has about 64 million words. • Number each word using its smallest byte number. Stack Heap
Memory +0 +1 +2 +3 • Local variables are stored in stack, growing upwards. • Multiple-byte variable’s address is the smallest byte number. • Complete/half word req. 900 904 908 V4 912 V3 V2 916 V1 920 924 928 932 936 940 944
What’s the print out? +0 +1 +2 +3 int main() { int d; char c; short s; int* p; int arr[2]; printf(“%p,%p,%p,%p,%p\n”, &d,&c,&s,&p,arr); return 0; } // suppose &d=920 (in practice a // 4-byte hex number such as // 0x22FC3A08) 900 904 arr 908 912 p s c 916 d 920 924 928 932 936 940 Solution: 920, 919, 916, 912, 904 944 Note: according to a bug in gcc, the address of arr will be 900 instead of 904.
Usage of pointer +0 +1 +2 +3 p = &d; *p = 10; c = (char)1; p = arr; *(p+1) = 5; p[0] = d; *( (char*)p + 1 ) = c; 900 904 arr[0] 908 arr[1] 912 = 920 p = 1 s c 916 = 10 d 920 924 928 932 936 940 944 Note: according to a bug in gcc, the address of arr will be 900 instead of 904.
Usage of pointer +0 +1 +2 +3 p = &d; *p = 10; c = (char)1; p = arr; *(p+1) = 5; // int* p; p[0] = d; *( (char*)p + 1 ) = c; Q: arr[0] = ? 900 904 arr[0] = 10 908 = 5 arr[1] 912 = 904 p = 1 s c 916 = 10 d 920 924 928 932 936 940 A: 266! 944 Note: according to a bug in gcc, the address of arr will be 900 instead of 904.
Pass pointer parameters into function void swap(int *px, int *py) { int temp; temp = *px; *px = *py; *py = temp; } int a = 5; int b = 6; swap(&a, &b); • What will happen int * a; int * b; swap(a, b); You will have a running error. If the code happens inside the kernel, you might crash the system. Note: never read/write the content of a uninitialized pointer.
Dynamic memory allocation • Allows the program determine how much memory it needs at run time, and allocate exactly the right amount of storage. • The region of memory where dynamic allocation and deallocation of memory can take place is called the heap. • Note: the program has the responsibility to free the dynamic memory it allocated. • Functions for the dynamic memory allocation • void *malloc(size_t number_of_bytes); • allocates dynamic memory • size_t sizeof(type); • returns the number of bytes of type • void free(void * p) • releases dynamic memory allocation • An example of dynamic memory allocation int * ids; //id arrays int num_of_ids = 40; ids = malloc( sizeof(int) * num_of_ids); …….. Processing …... free(ids);
Usage of pointer +0 +1 +2 +3 p = (int*) malloc(sizeof(int)*3); p[2] = arr[1] * 3; s = (short)( *(p+2) ); free( p ); 900 904 arr[0] = 266 908 = 5 arr[1] 912 = 904 p = 1 s c 916 = 10 d 920 924 928 932 936 940 944 Note: according to a bug in gcc, the address of arr will be 900 instead of 904.
Usage of pointer +0 +1 +2 +3 p = (int*) malloc(sizeof(int)*3); p[2] = arr[1] * 3; s = (short)( *(p+2) ); free( p ); 900 904 arr[0] = 266 908 = 5 arr[1] Q: what if you say p[2]=0 afterwards? 912 = 932 p = 15 = 1 s c 916 A: run time error. = 10 d 920 Q: what if you do not call free(p)? 924 928 A: memory leak. 932 936 p[2] = 15 940 944 Note: according to a bug in gcc, the address of arr will be 900 instead of 904.
Data Structure • A data structure is also a data type struct stud_record my_record; struct stud_record * pointer; pointer = & my_record; • Accessing a field inside a data structure my_record.id = 10; or pointer->id = 10; A data structure is a collection of one or more variables, possibly of different types. • An example of student record struct stud_record{ char name[50]; int id; int age; int major; …… }; • Allocating a data structure instance struct stud_record * pointer; pointer = malloc(sizeof(struct stud_record)); pointer->id = 10; Never calculate the size of data structure yourself. Give it to sizeof() function. • Note: can use typedef, e.g. typedef struct stud_record { ..... } Record;
Case Study: Linked List void DeleteAll( Node* head ) { while ( head != NULL ) { Node* current = head; head = head->next; free( current ); } } int main() { Node* head = NULL; Insert( head, 1234 ); Insert( head, 4567 ); DeleteAll( head ); return 0; } #include <stdio.h> typedef struct tmpNode{ int ssn; struct tmpNode * next; } Node; void Insert( Node* head, int ssn ) { Node* node = (Node*)malloc(sizeof(Node)); node->ssn = ssn; node->next = head; head = node; } Flawed!
Case Study: Linked List void DeleteAll( Node* head ) { while ( head != NULL ) { Node* current = head; head = head->next; free( current ); } } int main() { Node* head = NULL; Insert( &head, 1234 ); Insert( &head, 4567 ); DeleteAll( head ); return 0; } #include <stdio.h> typedef struct tmpNode{ int ssn; struct tmpNode * next; } Node; void Insert( Node** phead, int ssn ) { Node* node = (Node*)malloc(sizeof(Node)); node->ssn = ssn; node->next = *phead; *phead = node; } Correct version!
Command-Line Argument In C you can pass arguments to main() function. • Main() prototype int main(int argc, char * argv[]); argc indicates the number of arguments argv is an array of input string pointers. • How to pass your own arguments ./hello 10
What value is argc and argv? Let’s add two printf statement to get the value of argc and argv. #include <stdio.h> int main(int argc, char * argv[]);) { int i=0; printf("Hello World\n"); printf(“The argc is %d \n”, argc); for(i=0; i < argc; i++){ printf(“The %dth element in argv is %s\n”,i,argv[i]); } return(0); }
The output The argc is 2 The 0th element in argv is ./hello The 1th element in argv is 10 The trick is the system always passes the name of the executable file as the first argument to the main() function. • How to use your argument Be careful. Your arguments to main() are always in string format. Taking the above program for example, the argv[1] is string “10”, not a number. You must convert it into a number before you can use it.
Programming Tips • Replacing numbers in your code with macros #define MAX_NAME_LEN 50; char name[MAX_NAME_LEN]; • Avoiding global variables • Giving variables and functions a nice name • Don’t repeat your code • Don’t let the function body to exceed one screen
Indenting your code if(expression) { if(expression) { …… } } • Commenting your code • Don’t rush into coding. Plan first. • Printing out more debugging information • Using debugger
C vs. C++ • C++ is a superset of C • C++ has all the characteristics of C • Object-oriented! • Using g++ to compile your source code