the c language
BY SA
1972 by Ken Thompson and Dennis Ritchie
developed concurrently with Unix C++ and Objective-C in 1980’s ANSI C89, C90, and C99 GCC (Gnu Compiler Collection) MSVC (Microsoft Visual C++)
imperative/procedural statically typed weakly typed
control of memory explicitly manipulate individual bytes “portable assembly” compact data manual allocation
calling convention assembly from C C from assembly (how functions are called in machine code)
systems programming (operating systems, device drivers) performance-sensitive code (games, media players)
basic data types char 1-byte signed integer int n-byte signed integer float single-precision floating- point double double-precision floating-point
declarations type name; int monkey; float zebra;
functions returnType name(parameters) {body}
int square(int n) { return n * n; } int cube(int n) { return square(n) * n; }
char foo(int a, float b, float c) { … }
casting (type) expression int x = 35; foo((char) x);
!0// 1 !1// 0 !0.6// 0 !3// 0 !-76.5// 0
void roger(int x) { if (x == 3) { int z = 9; foo(z); } else { bar(z); // z does not exist } ack(z); // z does not exist }
int main() { printf(“Hello, world!”); return 0; }
value variables float a = 9.3;
pointers (a data type representing an address) int *foo; double *bar; char *ack;
reference operator &lvalue int i; int *p; p = &i; char c; int *p; p = &c; // error
reference operator &lvalue int i; int *p; p = &i;
dereference operator *pointer int i = 3; int *p; p = &i; i = *p + 2;
int i; int *p; p = &i; *p = 6;
pointer arithmetic int i; int *p; p = &i + 2; i = *p;
can subtract a pointer from a pointer can’t add a pointer to a pointer
char *p; p = (char *) 0xB000FFFF; char c = *p;
int *p; p = 0; if (p) { … } // false
pointer comparisons == != > < >= <= !
weak typing (can violate data types) float f; f = 98.6; f = f – 2; char *p; p = (char *)&f + 2; *p = 1;
memory allocation malloc free
void *p; p = malloc(5); float *f; f = malloc(13); … free(p); free(f);
sizeof operator sizeof type sizeof int sizeof double sizeof(float *)
int *p; p = malloc(7 * sizeof(int)); *(p + 6) = 35; … free(p);
int *p; p = malloc(7 * (sizeof int)); if (p == 0) { … // allocation failed } else { … // allocation succeeded free(p); }
array (a stack-allocated contiguous block of memory) type name[size]; float jack[8]; char jill[200];
int i[32]; char c[11]; int *p; p = i; *i = -6; *(i + 1) = 8; *(c + 7) = (char) 5;
int sum(int *arr, int n) { int i = 0; int sum = 0; while (i < n) { sum = *(arr + i) + sum; i = i + 1; } return sum; }
int a[30]; … int sumA = sum(a, 30); int *b = malloc(20 * sizeof(int)); … int sumB = sum(b, 20);
char *fred() { char c[30]; return c; }
char *fred() { char *c = malloc(30 * sizeof(char)); return c; } char *foo = fred(); … free(foo);
strings char *s = “abc”; char b = *(s + 1); int i = strlen(s);
structure (a programmer-defined compound data type) struct typeName {members}; struct typeName name; instance.member
struct cat { char *name; int age; }; // semi-colon! struct cat mittens; mittens.name = “Mittens”; mittens.age = 5;
struct cat mittens; struct cat fluffy; … mittens = fluffy; struct cat *p = &fluffy; mittens == fluffy // illegal
struct cat cats[8]; (*cats).name = “Oscar”; (*(cats + 1)).name = “Kitty”;
struct cat *cats = malloc(8 * (sizeof struct cat));