Princeton University COS 333: Advanced Programming Techniques A Subset of C90 Program Structure /* Print "hello, world" to stdout. Return 0. */ { printf("hello, world\n"); ----------------------------------------------------------------------------------- int sqr(int i) { return i * i; { printf("%d\n", sqr(5)); ----------------------------------------------------------------------------------- int sqr(int i); { printf("%d\n", sqr(5)); int sqr(int i) { return i * i; ----------------------------------------------------------------------------------- Compiler must see definition or declaration of function before call of function. Building and Running gcc -Wall -ansi -pedantic program.c -o program program Terminal I/O Reading from stdin: ivaluesread = scanf("%d %lf", &i, &d); Writing to stdout: icharswritten = printf("%d %f", i, d); Page 1 of 7
Writing to stderr: icharswritten = fprintf(stderr, "%d %f", i, d); Keywords auto, break, case, char, const, continue, default, do, double, else, enum, extern, float, for, goto, if, int, long, register, return, short, signed, sizeof, static, switch, typedef, union, unsigned, void, volatile Primitive Data Types char 1 byte (char)-128, (char)127, 'a', '\n', '\t', '\0' unsigned char 1 byte (unsigned char)0, (unsigned char)256 short 2? bytes (short)-32768, (short)32767 unsigned short 2? bytes (unsigned short)0, (unsigned short)65535 int 4? bytes -2147483648, 2147483647 unsigned int 4? bytes 0U, 4294967295U, 0123, 0x123 long 4? bytes -2147483648L, 2147483647L unsigned long 4? bytes 0UL, 4294967295UL, 0123L, 0x123L float 4? bytes 123.456F double 8? bytes 123.456 long double 12? bytes 123.456L Use sizeof operator to determine sizes on your system. Variables must be declared before used. Operators fun(params) (1) function call (parameters passed by value) a[i] (1) array element selector s.f (1) structure field selector ps->f (1) structure dereference and field selector (type) (2) typecast *p, &x (2) dereference, address of i++, ++i, i-, --i (2) increment, decrement +x, -x (2) unary positive, unary negative ~i (2) bitwise NOT!i (2) logical NOT sizeof(type) (2) sizeof (performed at compile-time) x*y, x/y, i%j (3) multiplication, division, remainder x+y, x-y (4) addition, subtraction i<<j, i>>j (5) left-shift right-shift x<y, x>y, x<=y, x>=y (6) obvious x==y, x!=y (7) equality, inequality i&j (8) bitwise AND i^j (9) bitwise EXCLUSIVE OR i j (10) bitwise OR i&&j (11) logical AND i j (12) logical OR i?x:y (13) conditional expression x=y (14) assignment x+=y, x-=y, x*=y, x/=y, i%=j (14) assignment i&=j, i^=j, i =j (14) assignment i<<=j, i>>=j (14) assignment x,y (15) sequence Page 2 of 7
Statements Expression statement: expr; Declaration statement: modifiers datatype var [= expr][, var [= expr]]...; Common modifiers: const, static Compound statement: { statement; statement;... Selection statements: if (intorptrexpr) statement else statement Note: 0 or NULL pointer => false; anything else => true switch (intexpr) { case (intvalue1): statement;...; break; case (intvalue2): statement;...; break;... default: statement;...; Iteration statements: while (intorptrexpr) statement; do statement while (expr); for (initexpr; intorptrexpr; increxpr) statement; Note: 0 or NULL pointer => false; anything else => true break; continue; Return statement: return; return expr; Classes, Objects, and Object References None! But can use the opaque pointer pattern. File myclass.h: #ifndef MYCLASS_INCLUDED #define MYCLASS_INCLUDED Page 3 of 7
typedef struct MyClass *MyClass; MyClass MyClass_new(int i); void MyClass_free(MyClass obj); int MyClass_get(MyClass obj); void MyClass_set(MyClass obj, int i); int MyClass_equals(MyClass obj, MyClass objother); void MyClass_print(MyClass obj, FILE *psfile); #endif File myclass.c: #include "myclass.h" #include <stdlib.h> struct MyClass { int i; ; MyClass MyClass_new(int i) { MyClass obj = (MyClass)malloc(sizeof(struct MyClass)); if (obj == NULL) return NULL; obj->i = i; return obj; void MyClass_free(MyClass obj) { free(obj); int MyClass_get(MyClass obj) { return obj->i; void MyClass_set(MyClass obj, int i) { obj->i = i; int MyClass_equals(MyClass obj, MyClass objother) { return obj->i == objother->i; void MyClass_print(MyClass obj, FILE *psfile) { fprintf(psfile, "%d", obj->i); /*--------------------------------------------------------------------*/ #ifdef TEST_MYCLASS { MyClass obj1; MyClass obj2; obj1 = MyClass_new(5); if (obj1 == NULL) { fprintf(stderr, "Memory is exhausted.\n"); exit(exit_failure); Page 4 of 7
MyClass_set(obj1, 10); printf("%d\n", MyClass_get(obj1)); MyClass_print(obj1, stdout); printf("\n"); obj2 = MyClass_new(10); if (obj2 == NULL) { fprintf(stderr, "Memory is exhausted.\n"); exit(exit_failure); if (MyClass_equals(obj1, obj2)) printf("equal\n"); if (! MyClass_equals(obj1, obj2)) printf("not equal\n"); MyClass_free(obj2); MyClass_free(obj1); #endif Data Structures Arrays int a[5]; int a[] = {1,2,3; The name of an array is a constant pointer. Pointers int *p; NULL (the NULL pointer) is defined in stddef.h. Arrays and pointers a is the same as &a[0] a[i] is the same as *(a+i) Pointer arithmetic strides over an array. Structures struct S {int i; double d; ; /* Defines a structure type. */ struct S s; /* Defines a structure. */ Enumerations enum E {CONST1, CONST2, ; /* Defines an enumeration type. */ enum E e; /* Defines an enumeration. */ Dynamic data structures #include <stdlib.h> p = malloc(ibytes); p = calloc(ielements, ibytesperelement); p = realloc(p, inewbytes); free(p); Strings Page 5 of 7
A string is an array of chars terminated with '\0' "abc" denotes a string #include <string.h> i = strlen(pcstr); strcpy(pcdest, pcsrc); strncpy(pcdest, pcsrc, ilen); strcat(pcdest, pcsrc); strncat(pcdest, pcsrc, ilen); i = strcmp(pcfirst, pcsecond); i = strncmp(pcfirst, pcsecond, ilen); pc = strstr(pchaystack, pcneedle); Files FILE *psfile; psfile = fopen("filename", "mode"); /* mode: r, w, a, r+, w+, a+ */ fclose(psfile); Write/read a char: istatus = fputc(i, psfile); /* Returns i or EOF. */ istatus = putc(i, psfile); /* Returns i or EOF. */ istatus = putchar(i); /* Returns i or EOF. */ i = fgetc(psfile); /* Returns char within i, or EOF. */ i = getc(psfile); /* Returns char within i, or EOF. */ i = getchar(); /* Returns char within i, or EOF. */ Write/read a string: istatus = fputs(pcstr, psfile); /* Does not write trailing '\n'. */ istatus = puts(pcstr); /* Writes trailing '\n' */ pcstatus = fgets(pcstr, ibufsize, psfile); /* Reads trailing '\n'. Returns pcstr or NULL. */ pcstatus = gets(pcstr); /* Discards trailing '\n'. Returns pcstr or NULL. DANGEROUS!!! */ Write/read formatted data: icharswritten = fprintf(psfile, "%d", i); icharswritten = printf("%d", i); ivaluesread = fscanf(psfile, "%d", &i); ivaluesread = scanf("%d", &i); Command-Line Arguments The argv parameter of main() is an array of strings. argv[0] is the name of the program. argv[1], argv[2],... are command-line arguments. #include <stdlib.h> Page 6 of 7
int main(int argc, char *argv[]) {... if (argc!= 3) { fprintf(stderr, "Usage: %s arg1 arg2\n", argv[0]); exit(exit_failure);... Preprocessor Directives and Macros #include <somefile.h> /* Search system directories. */ #include "somefile.h" /* Search my directories first. */ #define name value #ifdef name... #endif #ifndef name... #endif assert(expr); Debugging To use the gdb debugger: gcc -Wall -ansi -pedantic -g program.c -o program emacs <Esc>x gdb<enter>program<enter> Debugger commands: help break function break filename:linenum run list next step continue print expr where quit Etc. Common commands have abbreviations: h, b r, l, n, s, c, p, q. Blank line means repeat the same command. We'll cover other features of C throughout the course as necessary. Copyright 2011 by Robert M. Dondero, Jr. Page 7 of 7