Syntax sheet
Programming 1 on one page, module by module. The middle column is what the syntax does; the right-hand column is the mistake that particular line invites.
The basic structure
Module 3a · in this order
| /* … */ | documentation section: the header comment — what, who, when | Comments are never compiled; a program runs the same without them. |
| #include <stdio.h> | link section: headers whose functions the program uses | stdio.h declares printf and scanf. |
| #define PI 3.14159 | definition section: symbolic constants (macros) | No = and no ; — the preprocessor pastes 3.14159 wherever PI appears. |
| int total = 0; | global declaration section: usable in every function | Declared outside every function, above main. |
| int add(int a, int b); | function prototype declaration section | A prototype ends with ; — a definition has a body instead. |
| int main() { … } | the main function: a declaration part, then an execution part | Every statement in both parts ends with ;. |
| int add(int a, int b) { … } | user-defined function definitions, after main | Called from main; the prototype above lets main call it first. |
From prog.c to the screen
Module 3a · execution flow
| prog.c → preprocessor → prog.i | #include and #define are expanded | The preprocessor runs before the compiler ever sees the code. |
| prog.i → compiler → prog.s | C becomes assembly code | Syntax errors stop the program here — nothing runs. |
| prog.s → assembler → prog.obj | assembly becomes object code | |
| prog.obj → linker → prog.exe | linked with the library functions | |
| prog.exe → loader → memory | loaded and run; output goes to the console |
Output
Module 3b · printf
| printf("text"); | prints exactly the text — nothing more | No newline unless the string holds \n. |
| printf("%s\n", name); | the usual way to print a line | The \n is yours to write — printf adds none. |
| puts("text"); putchar('A'); | side notes: a string plus a newline, and one character | Neither takes placeholders. Use printf everywhere. |
| return 0; | main ends; 0 tells the system it succeeded | Execution starts at main, wherever main is written. |
Escape sequences
Module 3b · the execution character set
| \n | newline | \n is one character, not two. |
| \t | tab — to the next stop, every 8 columns | Name:\tJuan lines up at column 9, not 4 spaces on. |
| \\ \" \' | a backslash, a double quote, a single quote | "\" never ends: its closing quote is escaped. |
| \0 | the null character, code 0 — ends every string | Printing stops at the first \0. |
| %% | a percent sign, inside printf's format | % is not an escape; a lone % starts a placeholder. |
Format specifiers
Module 3b · printf and scanf
| %d %i | int | %d given a double prints garbage — printf never converts. |
| %f | float or double, 6 decimals by default | %f given an int prints garbage. Cast: (double) n. |
| %.2f | 2 decimals, rounded | %2f is width 2, not 2 decimals. |
| %c | char — the character with that code | %d of a char prints its code: 'A' is 65. |
| %s | string — chars up to the \0 | %s given a char crashes. Use %c. |
| %5d %-5d %05d | width 5: right-aligned, left-aligned, zero-padded | Width is a minimum; longer values are never cut. |
| %.3s | at most 3 characters of the string | Precision on %s truncates; width on %s pads. |
| %e %g %x %u | scientific, shortest, hexadecimal, unsigned | %g drops trailing zeros: 2.50 prints as 2.5. |
Input
Module 3b · scanf
| scanf("%d", &n); | reads an int into n | The & is required: scanf needs where n lives. |
| scanf("%f", &x); | reads a float | For a double, scanf needs %lf. (printf is fine with %f.) |
| scanf("%s", name); | reads one word into a char array | No & for an array. Stops at the first space. |
| scanf(" %c", &c); | skips spaces and newlines, then reads a char | Without the space, %c reads the newline Enter left behind. |
| scanf("%[^\n]", line); | reads the rest of the line, spaces included | Stops before the newline — which is still waiting. |
| fgets(line, 30, stdin); | side note: the other way to read a line, at most 29 chars | Unlike scanf, it keeps the \n at the end. |
| scanf's return | how many values it stored; EOF when input ran out | while (scanf(…) == 1) loops until input fails. |
Variables and data types
Module 3b
| int %d | 4 bytes, a whole number | -2,147,483,648 to 2,147,483,647. |
| float %f double %lf | 4 and 8 bytes, with a fractional part | scanf needs %lf for a double; printf takes %f or %lf. |
| char %c | 1 byte, one character | 'A' is a char constant; "A" is a string constant. |
| local variable | declared inside a function or block; lives there only | Holds garbage until it is given a value. |
| global variable | declared outside every function | Every function can read and change it. |
| static int y = 10; | keeps its value between calls | Initialized once, not on every call. |
| identifiers | letters, digits, _ ; not starting with a digit | No spaces, no # or $, no keyword. Case-sensitive: Total ≠ total. |
Functions
Module 4
| int calcSum(int x, int y); | declaration (prototype): name, parameter types, return type | Ends with ; and comes before main. |
| total = calcSum(a, b); | call: a and b are the arguments (actual parameters) | The call's arguments must match the parameter list in type, order and number. |
| int calcSum(int x, int y) { … } | definition: the header, then the body; x and y are formal parameters | A non-void function must return a value of its return type. |
| void f(void) | receives nothing, returns nothing | Called as f(); on its own line — there is no value to store. |
| void f(int a) · int f() · int f(int a) | the other three designs | Only a non-void function's call can sit on the right of =. |
| pass-by-copy | the argument's value is copied into the parameter | Changing the parameter never changes the caller's variable. |
Selection and jumps
Module 5a
| if (c) … | runs when c is non-zero | if (x = 0) stores 0 and is always false. |
| if (c); … | the ; is the whole if — the next line always runs | Never put ; straight after if (…). |
| if … else if … else | the first true branch runs, then the chain ends | Check the highest range first: 90, then 80, then 75. |
| else | belongs to the nearest if that has none | Indentation doesn't decide it. Use braces. |
| switch (x) { case 1: … break; } | jumps to the matching case, runs until break | No break: it falls into the next case's code. |
| case 1: case 7: | stacked cases share code | case labels are constants — no ranges, no variables. |
| switch (expression) | the expression must be an integer type | A char works — it is a small integer. A double or a string doesn't. |
| c ? a : b | the ternary operator: a if c is true, else b | From the exam coverage list. It is an expression — it gives a value. |
| goto label; | jumps to label: anywhere in the function | The slides say to avoid it; a loop or an if does the job. |
| return expr; | ends the function, handing expr to the caller | Nothing after a return in the same block runs. |
Loops
Module 5b
| while (c) { … } | checks first — may run zero times | Update the loop variable, or it never ends. |
| do { … } while (c); | runs once, then checks | Needs the ; after while (c). |
| for (init; c; update) | init once, check, body, update, check… | for (…); with a ; runs an empty body. |
| i < n vs i <= n | n rounds from 0; n rounds from 1 | The off-by-one: count the rounds for a tiny n. |
| for ( ; ; ) | an infinite loop: no condition means always true | Something inside must break out, or it never ends. |
| break (Module 5a) | leaves the innermost loop or switch | In nested loops, only the inner one ends. |
| continue (Module 5a) | skips to the next round | In a for, the update still runs; in a while, an update below it is skipped. |
| after the loop | the variable keeps the value that failed the test | for (i = 0; i < 5; i++) leaves i at 5. |
Pointers
Module 7
| int *p; | declares p, a pointer to an int | The * here declares; it doesn't follow anything yet. |
| p = &x; | referencing: p holds x's address | &x is the address of x, not its value. |
| y = *p; | dereferencing: the value at the address p holds | The pointer and what it points to must be the same type. |
| *p = 20; | changes x itself, through p | p = 20 would store 20 as the address instead — gcc warns, and the program breaks. |
| printf("%p", p); | prints an address | Different on every run; never the same as the value. |
Functions, part 2
Module 8
| void swap(int *a, int *b) | pass-by-reference: the parameters hold addresses | Called as swap(&d, &e) — the & is required. |
| tmp = *a; *a = *b; *b = tmp; | swaps the caller's variables | swap(int a, int b) swaps its own copies and changes nothing outside. |
| recursion | a function that calls itself | From the exam coverage list: it needs a base case that doesn't recurse. |
| if (n <= 1) return 1; | the base case: where the calls stop | Without one the calls never end — a runtime error, not a compile error. |
Arrays
Module 9 · one-dimensional
| int a[5]; | five ints, a[0] to a[4] | a[5] is past the end. C won't stop you. |
| int a[5] = {1, 2}; | 1, 2, 0, 0, 0 — the rest are zeroed | With no initializer at all, the values are garbage. |
| int a[] = {4, 8, 15}; | length taken from the list: 3 | sizeof(a) / sizeof(a[0]) counts elements. |
| for (i = 0; i < n; i++) | the traversal: every element once | Start a max at a[0], never at 0. |
| int a[1000] = {0}; | every element 0 | Only 0 spreads like this; {5} gives 5, 0, 0, … |
| &a[i] a + i | elements sit side by side: a float array's addresses go up by 4 | If mark[0] is at 2120, mark[2] is at 2128. |
| void f(int arr[], int size) | an array parameter: the array itself, not a copy | Changes made inside f stay in the caller's array. Pass the size too. |
| insert at the front | shift right, starting from the last element | Shifting from the front copies one value over everything. |
| remove from the front | shift left, starting from the first element | Then take one off the count. |
Extra practice — not in the slides
Operators
Extra practice · highest precedence first
| () [] x++ x-- | grouping, indexing, post-increment | x++ hands over the old value, then adds 1. |
| ++x --x ! ~ - (type) sizeof | unary, right to left | (float) a / b casts a, then divides. |
| * / % | multiply, divide, remainder | 7 / 2 is 3 with ints. -7 % 3 is -1: the sign follows the left side. |
| + - | add, subtract | a - b - c is (a - b) - c. |
| << >> | shift bits left, right | x << 1 doubles; x >> 1 halves, dropping the remainder. |
| < <= > >= | relational — gives 1 or 0 | 18 <= age <= 59 is always 1. Use && . |
| == != | equal, not equal | = assigns; == compares. |
| & ^ | | bitwise and, xor, or | Below == : x & 1 == 0 means x & (1 == 0). |
| && || | logical and, or — stop early | The right side may never run: y++ inside it may not happen. |
| ? : | condition ? if true : if false | Both branches should have the same type. |
| = += -= *= /= %= &= |= ^= <<= >>= | assignment, right to left | x *= 2 + 3 is x = x * (2 + 3). |
Typecasting
Extra practice · what a value becomes
| int / int | an int — the fraction is dropped | (80 + 85) / 2 is 82 even when stored in a float. |
| int op double | the int becomes a double first | Make one side a double: / 2.0, or (double) sum / n. |
| (int) 9.99 | 9 — truncated, never rounded | (int) -9.99 is -9. To round: (int) (x + 0.5) for x ≥ 0. |
| int n = 3.7; | n is 3 — assignment converts silently | No warning at run time; the fraction is simply gone. |
| 'A' + 2 | 67 — a char is a small int | %c prints it as C; %d prints 67. |
| char c = 300; | c is 44 — only the low 8 bits fit | A char holds -128 to 127. |
Built-in libraries
Extra practice · include the header, or it won't compile
| <ctype.h> | isalpha isdigit isalnum isspace isupper islower ispunct — toupper tolower | is… returns non-zero for true, not 1. Test with if (isdigit(c)). |
| strlen(s) | characters before the \0 | strlen("hi") is 2; sizeof a char s[] = "hi" is 3. |
| strcpy(d, s) strcat(d, s) | copy s into d; append s to d | d must have room for it all plus the \0. |
| strncpy(d, s, n) | copy at most n characters | Adds no \0 when s is n characters or longer. |
| strcmp(a, b) | 0 if equal; negative if a comes first; positive if after | Never a == b. "Z" comes before "a"; "10" before "9". |
| <math.h> | sqrt pow fabs ceil floor round fmod — all return double | printf a math.h result with %f, not %d. |
| ceil floor round | up, down, nearest (halves away from zero) | floor(-2.5) is -3.0; ceil(-2.5) is -2.0. |
| abs(n) <stdlib.h> | absolute value of an int | For a double use fabs, from math.h. |
Two-dimensional arrays
Extra practice
| int m[2][3]; | 2 rows × 3 columns — m[row][col] | Outer loop rows, inner loop columns. |
| char w[3][10] = {"one", …}; | an array of strings: 3 rows, each up to 9 chars | w[i] is a whole string; w[i][j] is one char. |