Programming in C

Fast Track to C Syntax for Programmers

Gerald Senarclens de Grancy

Compiling a Basic Program

#include <stdio.h>

/* Hello World program written in C. */
int main(void) {
printf("Hello, World!\n"); // output some text
return 0; // 0 means success
}

Download hello.c

Compilation can be done with either clang or gcc (part of the GNU Compiler Collection, GCC).

clang $INFILE -o $PROGRAM_NAME
gcc $INFILE -o $PROGRAM_NAME

I/O

Writing to Standard Output

#include <stdio.h>

/* Hello World program written in C. */
int main(void) {
printf("Hello, World!\n"); // output some text
return 0; // 0 means success
}

Visualize execution

Reading Input

#include <stdio.h>

int main(void) {
char line[20];
int number = 0; // safer to initialize values
printf("Enter an integer between 1 and 6 (inclusive): ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%d", &number);
printf("You've entered the number %d.\n", number);
return 0;
}

Download input.c

Variables and Data Types

#include <stdio.h>
#include <stdbool.h>

int main() {
bool b1 = true, b2 = false; // bool, true and false require <stdbool.h>
char c1 = 'x', c2 = 115; // 115 is the ASCII code for 's'
int i = -5;
unsigned int u = 210;
long int l = 12345689;
float f = 1.23;
double d = 1.2345;
printf("b1=%d b2=%d\n", b1, b2);
printf("c1=%c c2=%c c2=%d\n", c1, c2, c2);
printf("i=%d u=%u l=%ld\n", i, u, l);
printf("f=%f d=%lf\n", f, d);
return 0;
}

Visualize execution

Block Scope

Identifiers are only valid in their defining block

#include <stdio.h>

int main() {
{
int number = 3;
}
// printf("%d", number); // error: number not declared in this scope
return 0;
}

Download block_scope.c

Conditional Execution

if and else

if (expression) {
// block
} else if (expression) {
// block
} else {
block
}

The ternary operator provides a shorthand

Type result = condition ? value_if_true : value_if_false;

Example: if and else

#include <stdio.h>

int main(void) {
int guess = 3; // entered by the user
if (guess == 4) { // guaranteed random guess, used a die
printf("You won!\n");
} else {
printf("Better luck next time, loser!\n");
}
return 0;
}

Visualize execution

switch

The C switch statement jumps to the block of code matching the value of an expression.
It executes one or multiple code blocks among many alternatives.

switch (expression){
case constant1:
// statements
break; // without break, execution of the following blocks continues
case constant2:
// statements
break;
// ...
default:
// statements
}

Example: switch

#include <stdio.h>
int main(int argc, char* argv[]) {
switch (argc) { // switch evaluates an expression: (argc)
case 1: // if the result of the expression evaluates to 1, jump here
printf("Only the command was entered.\n");
break; // break - jump out of the 'switch' block to avoid falltrough
case 2:
printf("Command plus one argument.\n");
break;
case 3:
printf("Command plus two arguments.\n");
break;
default: // any other value of the expression jumps here
printf("Command plus %d arguments.\n", argc-1); break;
}
return 0;
}

Visualize execution

while Loops

while (expression) {
// block
}

do ... while: run code block at least once regardless of the expression

do {
// block
} while (expression);

Example

#include <stdio.h>

int main(void) {
int n = 10;
while (n > 0) { // execute block while expression evaluates to `true`
printf("%d, ", n);
--n; // avoid side effects in statement above
}
printf("FIRE!\n");
return 0;
}

Visualize execution

Example: Execute a block of code at least once

#include <stdio.h>

int main() {
int condition = 0;
do {
printf("Do this at least once.\n");
} while (condition);
printf("FIRE!\n");
return 0;
}

Visualize execution

for Loops

for (initialization; condition; update_statement) {
// block
}

initialization and update_statement are optional

Every for loop can be expressed as while loop

// initialization
for (; condition; ) {
// block
// update_statement;
}

// initialization
while (condition) {
// block
// update_statement
}

Example

#include <stdio.h>

int main() {
int user_input = 3; // skipping actual input code
for (int i = 0; i < user_input; ++i) {
printf("counting up: %d\n", i);
}
for (int j = user_input; j >= 0; --j) {
printf("counting down: %d\n", j);
}
for (int j = 0; j < 10; j += user_input) {
printf("counting with step != 1: %d\n", j);
}
return 0;
}

Visualize execution

Function Signature

aka. type signature or type annotation

Defines the data types of the parameters and return value

For example, a function that returns the sum of two integers:

(int)(int, int)

Function Declaration

aka. function prototype or function interface

  • Specifies the function name and type signature, but omits the body
  • Required for using functions that are defined elsewhere
  • Promise to the compiler that the function will exist when linking

For example, a function that returns the sum of two integers:

int sum(int a, int b);

The parameter names are optional:

int sum(int, int);

Function Definition

  • Adds the function body to the declaration
  • The signature and name must exactly match the declaration
Type function_name(Type parameter1, Type parameter2, ...) { body }

For example, a function that returns the sum of two integers:

int sum(int a, int b) {
return a + b;
}

Pass by Value

By default, C copies argument values to function parameters

#include <stdio.h>

void pass_by_value(int i) {
i = 5;
printf("i: %d (at the end of the called function)\n", i);
}

int main() {
int i = 3;
printf("i: %d\n", i);
pass_by_value(i);
printf("i: %d (after returning from function)\n", i);
return 0;
}

Visualize execution

Questions
and feedback...