REVIEW

  
#include<stdio.h>

int main(void) {

 /* requests two numbers 
    and prints sum */
     
  int a,b,c;

  printf("enter two numbers:\t");
  scanf("%d %d",&a,&b);
  c = a + b;
  printf("the sum is %d\n",c);
}

Preprocessor

preprocessor:
#include<math.h> /* provides M_PI */
#define C 3.0   
int main() {
  float r, A;
  r = 0.3;
  A_over_C = (r*r * M_PI) / C;
} 

DEMONSTRATION

CONTROL FLOW STATEMENTS

Expressions and Operators

Our example programs already used some operators. C has operators for arithmetic operations, comparisons, boolean operations and assignments, etc. Here are some examples of expressions using some operators. Each expression evaluates to a value.

Arithmetic Operators

Each operator has a precedence and a certain associativity. The precedence determines the order in which operators are evaluated:
a + b * c is evaluated as a + (b*c) .

We say an operator op is left-to-right associative if

e_1 op e_2 ... op e_n == (...((e_1 op e_2) op e_3) ... op e_n).
Otherwise an operator is right-to-left associative, meaning
e_1 op e_2 ... op e_n == (e_1 op (e_2 op (e3 op (...))))

It's good to be aware of the associativity of the operators. Arithmetic operators are usually left-to-right associative:

6/3/2 == ((6/3)/2) != (6/(3/2))

Relations

We can compare values using relational operators. The value of an expression e is either What are the values of the following expressions?

Comparisons

Shortcuts, Assignments and some Confusion

Operators take one or two values and evaluate the result. There are two types of operators:

Some operators also change the value of the operands like the assignment operator:

a = b assigns the value of b to the variable a . The value of this expression is b. This property allows you to write code as below. Question: What's the associativity rule for the assignment operator?

int a, b, c, d, e;
a = b = c = d = e = 0

Here's another example: assume, b has value 1. The expression (a = b) + 1 evaluates to 2. As a side effect, a gets the value 1.

C has many more operators, perhaps the most useful operators are increment operators: The expression ++a increments a by one, and returns the result. However, the expression a++ increments a , but it returns the non-incremented (original) value.

Using these operators, one can write very compactly code - however, the semantic isn't always that obvious. Have a look at the following examples. Consider the initialization of a and b :

int a, b;
a = 1; b = 2;

What are the values of the following expressions? How does an expression change a and b?

Conditional statements

Program 1

#include<stdio.h>

int main() {

  /* The if statement has the syntax:
   *    if conditional_expression 
   *      statement1
   *    else
   *      statement2
   */

  char c;     /* character variable */
  c = 'b';    /* assign c the character 'b' */

  if (c == 'a') 
    printf("c == 'a'"); 
  else
    printf("c != 'a'");
}

Program 2

#include<stdio.h>

int main() {

  /* the else-branch of the an if statement 
   * can be omitted. What does this program
   * do? 
   */

  char c;
  c = 'b';

  if (c == 'a') 
    printf("c == 'a'"); 

}

Program 3

#include<stdio.h>

int main() {

  /* we can write group a sequence of statements
   * as a compound using "{", "}". That way we have
   * multiple statements in the if/else branches.
   */
 
  int x, y;
  x = 1;
  y = 0;

  if (x == 1) {
    y = !x;
    printf("x == 1");
  } else {
    y = x;
    printf("x != 0");
  }

}

Program 4

#include<stdio.h>

int main() {

  /* we can nest several if statements?
   * for which values of a and b is the
   * output XXX, resp. YYY? 
   * is there a case when nothing is printed?
   */

  int a;
  int b;
  
  a = 0;
  b = 3;

  if (a == 0)
    if (b == 1)
      printf("XXX\n");
    else
      printf("YYY\n");
}

Program 5

#include<stdio.h>

int main() {

  /* for which values of a and b is the
   * output XXX, resp. YYY?
   */

  int a = 0;
  int b = 3;

  if (a == 0) {
    if (b == 1)
      printf("XXX\n");
  } else {
    printf("YYY\n");
  }
}

Loops

Program 1

#include<stdio.h>

int main() {

  /* the while statement is repeating the statements
   * repeats the statements in the loop-body as long
   * as the loop-condition is fulfilled (evaluates to
   * != 0)
   *
   * which values are printed during the iteration?
   * what's the value of x after the loop?
   */

  int x;
  x = 0;
  while (x < 10) {
    printf("%d ",x);
    x++;
  }
  printf("\nafter loop %d",x);
}

Program 2

#include<stdio.h>

int main() {

  /* the do statement is similar to the if statement
   * but the condition is checked after the execution
   * of the loop.
   *
   * is the output the same as for the program above?
   */

  int x;
  x = 0;
  do {
    printf("%d ",x);
    x++;
  } while (x < 10);
  printf("\nafter loop %d",x);
}

Program 3

#include<stdio.h>

int main() {
  
  /* what is printed in this case? */

  int x;
  x = 11;
  while (x < 10) {
    printf("%d ",x);
    x++;
  }
  printf("\nafter loop %d",x);
}

Program 4

#include<stdio.h>

int main() {

  /* do you now see the difference
   * between do and while loops?
   */

  int x;
  x = 11;
  do {
    printf("%d ",x);
    x++;
  } while (x < 10);
  printf("\nafter loop %d",x);
}

Program 5

#include<stdio.h>

int main() {

  /* a for-loop takes expressions for initialization, 
   * loop-condition, and update after each iteration.
   *
   * Before the first iteration, the variables are initialized.
   * At each iteration the condition is checked. If it evaluates
   * to 1, the body of the loop is executed. After each single 
   * iteration the update operation is evaluated.
   *
   * What is the output of this program?
   */

  int i;
  for (i = 0; i < 10; i++) {
    printf("%d ",i);
  }
  printf("\nafter loop %d",i);
}

How to turn while-loops into do-loops:

while (cond) {
  statements
}
is equivalent to
if (cond) {
  do {
    statements
  } while (e)
}

... and the other way around:

do {
  statements
} while (cond)
is equivalent to
statements
while (cond) {
  statements
}

Program 6

#include<stdio.h>

int main() {

  /* sum numbers 0 through 9
   * do you know a closed form expression for this?
   */

  int sum;
  int i;

  sum = 0;
  for (i = 0; i < 10; i++) {
    sum += i;
  }
  printf("sum:\t%d\n",sum);
}

Program 7

#include<stdio.h>

int main() {
  
  /* compute the Fibonacci function
   *   a(0) = 0  
   *   a(1) = 1
   *   a(n) = f(n-1) + f(n-2),   for n >= 1
   * do you know any function which is growing
   * fast or faster than the Fibonacci function?
   */

  int n;
  int i;
  int a_i, a_i_minus_1;
  int tmp;

  n = 10;

  a_i_minus_1 = 0;
  a_i = 1;  
  i = 1;

  for (i = 1; i < n; i++) {
    /* maintains invariance:
       a_i  == a(i)
       a_i_minus_1 == a(i-1)
       */

    tmp = a_i;
    a_i = a_i + a_i_minus_1;
    a_i_minus_1 = tmp;
  }

  printf("a(%d) = %d\n",i,a_i);

}

Program 8

#include<stdio.h>

int main() {

  /* sum user input
   * enter 0 to indicate end of input
   *
   * what do you need to change to archive the following:
   *   the end-of-input should be indicated by 99.
   *   i.e the output should be 4 for input 1 2 1 99?
   */

  float sum;
  float number;

  sum = 0.0;

  do {
    printf("\n number:\t");
    scanf("%f",&number);
    sum += number;
  } while (number != 0.0);

  printf("sum:\t%f\n",sum);

}

Program 9

#include<stdio.h>

int main() {

  /* count a's, b'c and c's 
   * in input string.
   *
   * terminate input by typing ctrl-d to mark 
   * the end of input  (EOF = end of file) 
   * when using unix.
   */

  char c;  /* character variable */

  int a_count, b_count, c_count; 

  a_count = b_count = c_count = 0; 


  /* we're using getchar to read a single character */

  while ((c=getchar()) != EOF) {

    /* compare c to character 'a' rather than 
     * one-character string "a" and increment
     * counters
     */

    if (c == 'a')     ++a_count;  
    else if (c == 'b') ++b_count;
    else if (c == 'c') ++c_count;  

  }
  printf("\n #a's: %d\t #b's: %d\t #c's: %d\n",
	 a_count, b_count, c_count);
}

Practice

FUNCTIONS