460 likes | 580 Views
An Introduction to C. Muhammed Al-Mulhem. Jan. 2008. Goals of this tutorial. To introduce the basics of imperative programming using the C programming language To prepare you for basic imperative programming To prepare you for better understanding of the other parts of the course. Overview.
E N D
An Introduction to C Muhammed Al-Mulhem Jan. 2008
Goals of this tutorial • To introduce the basics of imperative programming using the C programming language • To prepare you for basic imperative programming • To prepare you for better understanding of the other parts of the course
Overview • Basic types in C • Some simple programs • Format specifiers • More example programs
C Programs: General Form preprocessor directives int main(){ variable declarations; statements; } Example: #include <stdio.h> int main(){ int x = 1; printf(“Salaam Shabab\n”); printf(“This is program %d\n”, x); return 0; }
Basic Data Types (some) • int • char • double • short • Basic pointer types (associated with each basic type)
Format Specifiers (some) Variable typeConversion Specifiers char %c Int %d Float %f Double %lf String %s
Format Specifiers (some) #include <stdio.h> int main(){ char ch = 's'; int i = 3; float f = 3; char *name = "ICS 410"; printf("Your values are:\n"); printf("A char: %c\n", ch); printf("A char: %d\n", ch); printf("An int: %d\n", i); printf("A float: %f\n", f); printf("A string: %s\n", name); printf("Mixed: %f\t%d\t%c\n", i,f,ch); return 0; } Your values are: A char: s A char: 115 An int: 3 A float: 3.000000 A string: ICS 313 Mixed: 0.000000 1074266112 s
Operators • Arithmetic • int i = i+1; i++; i--; i *= 2; • +, -, *, /, %, • Relational and Logical • <, >, <=, >=, ==, != • &&, ||, &, |, ! • Control structure • if ( ) { } else { } • while ( ) { } • do { } while ( ); • for(i=1; i <= 100; i++) { } • switch ( ) {case 1: … } • continue; break;
Example • #include <stdio.h> • #define DANGERLEVEL 5 /* like Java ‘final’ */ • int main() • { • float level=1; • if (level <= DANGERLEVEL) • printf(“Low on gas!\n”); • else printf(“Good driver !\n”); • return 0; • }
Overview • Introduction to pointers • Arrays and pointers • Strings in C • Pointers as function parameters
Pointers in C: An Introduction • A pointer is an address in memory of some ordinary data • There is a pointer type associated with every type Example 1: #include <stdio.h> int main(){ int x = 1; int *xp; xp = &x; printf(“x = %d\n”, x); printf(“*xp = %d\n”, *xp); return 0; }
any float f fp ? ? ? any address 4300 4304 f fp ? 4300 4300 4304 Pointers: A Pictorial View float f; float *fp; fp = &f;
f fp 3.2 1.3 4300 4300 4300 4304 f fp 4300 4304 Pointers: A Pictorial View (cont’d) *fp = 3.2; /* indirection operator */ float g=*fp; /* indirection: g is now 3.2 */ f = 1.3;
Example 2:Dereferencing Pointers #include <stdio.h> int main(){ int i=3, j=7, *ip; ip = &i; *ip = 5; ip = &j; *ip += 11; i += *ip; printf("i = %d\n", i); printf("j = %d\n", j); printf("*ip = %d\n", *ip); return 0; }
Example 3: Pointer Compatibility #include <stdio.h> int main(){ int x = 3, *xp, *xp2; float f = 7, *fp; void *vp; /* generic pointer: no arithmetic no dereferencing */ xp = &x; fp = &f; fp = xp; vp = xp; fp = vp; xp2 = vp; (*xp)++; printf("x = %d\n", *xp); printf("*vp = %d\n", *fp); printf("*vp = %d\n", *xp2); return 0; }
Arrays and Pointers • Arrays in C are not objects: no methods, no ‘length’ field • The name of an array is a constant pointer
Example 4: Arrays and pointers #include <stdio.h> int main(){ int i, j, *ip, myArray[5] = {2,3,5,7,11}; ip = &myArray[2]; for(i= 0; i<5; i++) printf("myArray[%d] = %d\n", i, *(myArray+i)); *(ip+1) = 4; *(ip-1) += 11; j = *(ip-2); for(i=0; i<5; i++) printf("myArray[%d] = %d\n", i, *(myArray+i)); printf("j = %d\n", j); return 0; }
Example 5: Dynamic Arrays #include <stdio.h> int main(){ int i, j, size, *ip, *myArray; printf("Enter array size:"); scanf("%d", &size); myArray = (int *)malloc(size*sizeof(int)); printf("Enter the %d elements (separated by space: ",size); for(i=0;i<size; i++){ scanf("%d", myArray+i); } ip = &myArray[2]; *(ip+1) = 4; *(ip-1) += 11; j = *(ip-2); for(i=0; i<5; i++) printf("myArray[%d] = %d\n", i, *(myArray+i)); printf("j = %d\n", j); return 0;
Example 6: File I/O #include <stdio.h> int main(){ int i,n,hours; long id; float rate, wage; char name[50], n2[50]; FILE *inputFile, *outputFile; inputFile = fopen("employeeData.txt","r"); outputFile = fopen("employeeWage.txt","w"); if (inputFile) printf("File succesfully opened for reading!\n"); else { printf(“File not opened\n”); exit(1); }
Example 6: File I/O printf("How many employees do you have>"); scanf("%d", &n); for(i=0;i<n;i++){ fscanf(inputFile, "%[0-9]%[^0-9]%d%f", &id,name,&hours,&rate); wage = hours*rate; fprintf(outputFile, "%ld\t%d\tSR%5.2f\t\tSR%5.2f\n", id,hours,rate,wage); } fclose(inputFile);fclose(outputFile); return 0; }
Strings in C • Java strings are objects of classjava.lang.Stringor java.lang.StringBuffer,and represent sequences of characters • Strings in C are just arrays of, or pointers to, char • Functions that handle strings typically assume that strings are terminated with a null character ‘\0’, rather than being passed a length parameter • Utilities for handling character strings are declared in <string.h>. For example: • strcpy, strncpy, strcmp, strncmp, strcat, strncat, strstr,strchr
Example 7: Strings in C #include <stdio.h> int main(){ char name[] = {'i', 'c', 's', ‘4', '1', ‘0', '\0'}; char *dept = "ICS, KFUPM"; int i = 0; printf("Course name = %s\n", name); for(; i<6; i++) printf("%c", *(name+i)); printf("\n"); for(i=0; i<10; i++) printf("%c", *(dept+i)); printf("\n"); return 0; }
Example 8: Strings Processing #include <stdio.h> #include <string.h> int main() { char first[80], second[80]; printf("Enter a string: "); gets(first); strcpy(second, first); printf("first: %s, and second: %s\n", first, second); if (strcmp(first, second)) puts("The two strings are equal"); else puts("The two strings are not equal"); return 0; }
Pointers and Functions • What is the parameter passing method in Java? • Passing arguments to functions • By value • By address • Returning values from functions • By value • By address
Example 9:Pass By Value #include <stdio.h> int sum(int a, int b); /* function prototype at start of file */ int main(){ int a=4,b=5; int total = sum(a,b); printf("The sum of 4 and 5 is %d\n", total); return 0; } int sum(int a, int b){ /* function definition */ return (a+b); }
Example 10: Pass By Address #include <stdio.h> int sum(int *a, int *b); int main(void){ int a=4, b=5; int *ptr = &b; int total = sum(&a,ptr); printf("The sum of 4 and 5 is %d\n", total); return 0; } int sum(int *pa, int *pb){ return (*pa+*pb); }
Example 11: Pass By Value #include <stdio.h> void swap(int, int); int main() { int num1 = 5, num2 = 10; swap(num1, num2); printf("num1 = %d and num2 = %d\n", num1, num2); return 0; } void swap(int n1, int n2) { /* passed by value */ int temp; temp = n1; n1 = n2; n2 = temp; printf("num1 = %d and num2 = %d\n", n1, n2); }
Example 12: Pass By Address #include <stdio.h> void swap(int *, int *); int main() { int num1 = 5, num2 = 10; swap(&num1, &num2); printf("num1 = %d and num2 = %d\n", num1, num2); return 0; } void swap(int *n1, int *n2) { /* passed and returned by reference */ int temp; temp = *n1; *n1 = *n2; *n2 = temp; printf("num1 = %d and num2 = %d\n", *n1, *n2); }
One-Dimensional Arrays #include <stdio.h> int main(){ int number[12]; int index, sum = 0; /* Always initialize array before use */ for (index = 0; index < 12; index++) { number[index] = index; } for (index = 0; index < 12; index = index + 1) { printf("number[%d] = %d\n", index,number[index]); sum += number[index]; } printf("The sum is: %d\n", sum); printf("The sum is: %d\n", number[12]); return 0; }
Overview • Storage classes • Structures • Type aliasing via typedef • enum types • struct types • union types
Storage Classes: An Introduction • For any variable declared in a program (e.g., int x = 11;), the compiler is told the following information about the variable: its • type (preceded by an optional qualifier, e.g., long int x;) • name • cell size (with an implicit address) • storage class • A storage class indicates the degree of the life span of a variable. • A variable can either have an extern, an auto, a register or a static storage class. • A register, auto and a local static variable has a temporary, local scope. • A global extern and a global static variable has a permanent, global scope.
Storage Classes: An Introduction • In functions other than main(), make a variable static if its value must be retained between calls to the function. • If a variable is used by most or all of the program's functions, define it with the extern storage class. • auto is the default storage class for local variables. auto can only be used within functions, i.e. local variables. • register is used to define local variables that should be stored in a register instead of RAM. • This means that the variable has a maximum size equal to the register size (usually one word) and can’t have the unary `&' operator applied to it (as it does not have a memory location). • register should only be used for variables that require quick access - such as counters.
Storage Classes: An Introduction • static is the default storage class for global variables. static can also be defined within a function. If this is done, the variable is initialized at compilation time and retains its value between calls. • Because it is initialized at compilation time, the initialization value must be a constant. • extern defines a global variable that is visible to ALL object modules. • An extern variable cannot be initialized because all extern does is point the variable name at a storage location that has been previously defined.
Example 1: Storage Classes #include <stdio.h> int x = 71; /* Equivalently, static int x = 71; */ void func1(void) { extern int x; /* Illegal to initialize! */ printf("In func1(), x = %d\n", x); } int main() { auto x = 23; /* Equivalently, auto int x = 23; */ printf("In main(), x = %d\n", x); func1(); return 0; }
Example 2: Storage Classes #include <stdio.h> void func1(void); /* function declaration */ static count=10; /* Global variable - static is the default */ main() { while (count--) func1(); return 0; } void func1(void) { /* 'x' is local to 'func1' - it is * only initialized at run time. Its value * is NOT reset on every invocation of * 'func1' */ static x=5; x++; printf(" x is %d and count is %d\n", x, count); }
Example 3: Storage Classes #include <stdio.h> char *f(void); int main() { char *result; result = f(); printf("%s",result); return 0; } char *f(void) { char name[13]="Amr Ali"; return name; }
Structures: Motivations • Our programs so far used only the basic data types provided by C, i.e., char, int, float, void and pointers. • Programmers can define their own data types using structures • Structures can be used to conveniently model things that would otherwise be difficult to model using arrays • Arrays versus structures: • arrays elements and structure components are contiguously laid out in memory • arrays are homogeneous, structures can be heterogeneous • arrays are passed to functions by reference while structures have to be explicitly passed by reference • arrays (of the same type, of course!) cannot be assigned to each other (why?) while structures can • array identifiers can be compared while structure identifiers cannot • Different structures (in the same program) can have the same component name. A structure component name can also be the same as an ordinary variable name
Creating Structures: the Tools • the typedef specifier • the enum specifier • the struct specifier • the union specifier
Creating Structures: Examples typedef struct date { int day; int month; int year; } DATE; enum Days {SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY}; struct date { int day; int month; int year; }; union mixed { char c; float num; int age; };
Creating Structures: Examples typedef is a mechanism, which allows a type to be explicitly associated with an identifier. Some examples are typedef char * string; typedef int INCHES, FEET, YARDS; typedef float vector [10]; In each of these type definitions the named identifiers can be used later to declare variables or functions in the same way ordinary types can be used. Thus INCHES length, width; String s1 = "abc", s2 = "xyz", vector x;
Example 4: Structures #include <stdio.h> struct date { int day; int month; int year; }; main() { struct date today; today.day = 17; today.month = 11; today.year = 1998; printf("Todays date is %d/%d/%d.\n", today.month, today.day, today.year ); return 0 }
Example 5: Structures #include <stdio.h> struct date {int day, month, year;}; void modify_date(struct date *yaum) { yaum->month = 3; yaum->year = 1999; printf("The date is %d/%d/%d.\n", yaum->day, yaum->month, yaum->year ); } main() { struct date *today; today->day = 16; today->month = 7; today->year = 1998; printf("The date is %d/%d/%d.\n", today->day, today->month, today->year ); modify_date(today); printf("The date is %d/%d/%d.\n", today->day, today->month, today->year ); }
Creating Union A union, like a structure, is a derived type. Unions follow the same syntax as structures but have members that share storage. A union type defines a set of alternative values that may be stored in a shared portion of memory. The programmer is responsible for interpreting the stored values correctly. Consider the declaration union int_or_float { int i; float f;}; In this declaration union is a keyword, int_or_float is the union tag name, and the variables i and f are members of the union. This declaration creates the derived data type union int_or_float. The declaration can be thought of as a template; it creates the type, but no storage is allocated. The tag name, along with the keyword union, can now be used to declare variables of this type. union int_or_float a, b, c; This declaration allocates storage for the identifiers a, b, and c. For each variable the compiler allocates a piece of storage that can accommodate the largest of the specified members.
Creating Union Example: tpedef union int_or_float {int i; float f;} number; main ( ) { number n; n.i = 4444; printf("i: %10d f: %16.10e\n", n.i, n.f); n.i = 4444.0; printf("i: %10d f: %16.10e\n", n.i, n.f); } This little experiment demonstrates how your system overlays an int and a float. The output of this program is system dependent. Here is what is printed on our system: i: 444 f: 0.6227370375e-41 i: 1166729216 f: 4.4440000000e+03