1 / 164

# - PowerPoint PPT Presentation

Composed for SE 115 C programming Faculty of Engineering & Computer Sciences Izmir University of Economics. Assoc. Prof. Dr. Süleyman Kondakci Suleyman.kondakci@ieu.edu.tr http://homes.ieu.edu.tr/skondakci. Summary of C Operations. Arithmetic : int i = i+1; i++; i--; i *= 2;

I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.

## PowerPoint Slideshow about '' - nellis

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
Composed for SE 115 C programmingFaculty of Engineering & Computer Sciences Izmir University of Economics

Assoc. Prof. Dr. Süleyman Kondakci

Suleyman.kondakci@ieu.edu.tr

http://homes.ieu.edu.tr/skondakci

• Arithmetic:

• int i = i+1; i++; i--; i *= 2;

• +, -, *, /, %,

• Relational and Logical:

• <, >, <=, >=, ==, !=

• &&, ||, &, |, !

• Flow Control:

• if ( ) { } else { }

• while ( ) { }

• do { } while ( );

• for(i=1; i <= 100; i++) { }

• switch ( ) {case 1: … }

• continue; break;

• Relational Operator:

Less than: <

Greater than: >

Less than or equal: <=

Greater than or equal: >=

EqualityOperators:

Equal: ==

Not equal: !=

Logical Operators:

Negation: !

Logical and: &&

Logical or: ||

int main()

{

int x=0, y=10, w=20, z, T=1, F=0;

z = (x == 0); /*** logical operator; result --> 0 or 1 ***/

z = (x = 0); /*** assignment operator; result --> ***/

z = (x == 1);

z = (x = 15);

z = (x != 2);

z = (x < 10);

z = (x <= 50);

z = ((x=y) < 10); /*** performs assignment, compares with 10 ***/

z = (x==5 && y<15);

z = (x==5 && y>5 && w==10);

z = (x==5 || y>5 && w==10);

z = (T && T && F && x && x); /*** ==> F; ***/

z = (F || T || x || x); /*** ==> T; ***/

/*** value of x doesn't matter ***/

return 0;

}

Input: scanf ("format specifier", variable)

Output: printf ("format specifier", variable)

Format specifiers

%c = as a character

%d = as a decimal integer

%e = as a floating-point number in scientififc notation

%f = as a floating-point number

%g = in the e-format or f-format, whichever is shorter

%s = as a string of characters

#include <stdio.h>

int main()

{

printf("Hello world!\n");

return 0;

}

On the screen

Hello world!

\f

\b

bell

backspace

formfeed

\\

\v

\t

horizontal tab

vertical tab

backslash

\'

\"

\ooo

single quote

double quote

octal number

\xhh

\?

\n

newline

question mark

\r

carriage return

Escape Sequences

Escaped characters produce visual and audible effects

Argument Type; Printed As

d, I

int; decimal number

o

int; unsigned octal number (without a leading zero)

x, X

int; unsigned hexadecimal number (without a leading Ox or OX, using abcdef or ABCDEF for 10,...,15)

u

int; unsigned decimal number

c

int; single character

s

char; print characters from the string until a '\0' or the number of charachters given by the precision

f

double; [-]m.dddddd, where the number of d's is given by the precision (default is 6)

e, E

double; [-]m.dddddde ± xx or [-]m.ddddddE ± xx where the number of d's is given by the precision (default is 6)

g, G

double; use %e or %E if the exponent is less than -4 or greater than or equal to the precision; otherwise use %f; trailing zeros and a trailing decimal point are not printed

p

void *; pointer (implementation-dependent representation)

%

no argument is converted; print a %

The Output Function (printf)

Input Data; Argument Type

d

decimal integer; int *

I

integer; int * ; the integer may be in octal (leading 0) or hexadecimal (leading 0x or 0X)

o

octal intger (with or without leading zero); int *

u

unsigned decimal integer; unsigned int *

x

hexadecimal number (with or without a leading 0x or 0X); int *

c

characters; char *. The next input characters (default 1) are placed at the indicated spot. The normal skip over white space is suppressed; to read the next non-white space character, use %1s

s

character string (not quoted); char * ; pointing to an array of characters large enough for the string and a terminating `\0' that will be added

e, f, g

floating-point number with optional sign, optional decimal point, and optional exponent; float *

%

literal %; no assignment is made

The Input Function (scanf)

/*fahr.c (several versions) - convert Fahrenheit to Celsius. */

int main()

{

int fahr = 42, cels;

cels = 5*(fahr-32)/9;

printf("%d degrees Fahrenheit is %d degrees Celsius\n", fahr, cels);

return 0;

}

Control Structures

The if statement has two forms:

if(expression 1)

statement1;

else if (expression 2)

statement 2;

else statement 3

if (expression) {

if (expression) {

statements

if (expression) {

statements

}

}

} else {

statements

}

The ?: operator

expression1?expression2:expression3

Same as

if(expression1) expression2

else expression3

Example: The ? and : operators

X = 12;

y = (x < 5) ? 5 : 10;

Same as

if (x < 5) y = 5;

else

y = 10;

single block

{

Statements

}

{

{

... {

}

}

}

outer block

inner block

Multiple nested block structure

for (i=0; i<=10; i++) {

printf("index is: %d", i);

}

if (a == b && a <= c || c >0)

printf("Aha!! \a\a");

You can aslo write like this:

if (a == b && a <= c || c >0)

{

printf("Aha!!\a\a");

}

Or

if (a == b && a <= c || c >0) printf("Aha!!\a\a");

int a=2; int b=30; int c=11;

if(a==b){

if( b<=c && c >10){

c= a-b;

while (a <=10) {

printf("Value of a: %d", a);

B = a*c;

}

a = a-1;

}

}else{

printf("That is all folks!");

}

/* Uses scanf() to get input */

/* Uses printf() to shw the result */

#include <stdio.h>

int main()

{

int fahr, cels;

printf("How many degrees? ");

scanf("%d", &fahr);

cels = 5*(fahr-32)/9;

printf("%d degrees Fahrenheit is %d degrees Celsius\n", fahr, cels);

return 0;

}

/*same, but with reals instead of integers*/

#include <tdio.h>

int main()

{

double fahr, cels;

printf("How many degrees? ");

scanf("%lf", &fahr);

cels = 5.0*(fahr-32.0)/9.0;

printf("%.3f degrees Fahrenheit is %.3f degrees Celsius\n", fahr, cels);

return 0;

}

/*fahrcels.c (several versions) - use a conditional statement to select one of

two calculations.*/

#include <stdio.h>

int main()

{

double fahr, cels;

int unit; /*'C' for Celsius input, 'F' for Fahrenheit*/

/*get input type*/

printf("Type C to convert Celsius to Fahrenheit, or F to go the other way: ");

unit = getchar();

/*get input, and do the appropriate calculation*/

printf("degrees? ");

if(unit == 'C')

{

scanf("%lf", &cels);

fahr = 9.0*cels/5.0+32.0;

}

else

{

scanf("%lf", &fahr);

cels = 5.0*(fahr-32.0)/9.0;

}

printf("%.3f degrees Fahrenheit is %.3f degrees Celsius\n", fahr, cels);

return 0;

}

/*uses logical OR to handle lowercase*/

#include <stdio.h>

int main(){

double fahr, cels;

int unit; /*'C' for Celsius input, 'F' for Fahrenheit*/

/*get input type*/

printf("Type C to convert Celsius to Fahrenheit, or F to go the other way: ");

unit = getchar();

/*get input, and do the appropriate calculation*/

printf("degrees? ");

if((unit == 'C') || (unit == 'c')) {

scanf("%lf", &cels);

fahr = 9.0*cels/5.0+32.0;

} else {

scanf("%lf", &fahr);

cels = 5.0*(fahr-32.0)/9.0;

}

printf("%.3f degrees Fahrenheit is %.3f degrees Celsius\n", fahr, cels);

return 0;

}

/*uses a conditional expression as well as a conditional statement*/

#include <stdio.h>

#include <ctype.h>

int main()

{

double fahr, cels;

int unit; /*'C' for Celsius input, 'F' for Fahrenheit*/

/*get input type*/

printf("Type C to convert Celsius to Fahrenheit, or F to go the other way: ");

unit = toupper(getchar());

/*get input, and do the appropriate calculation*/

printf("degrees? ");

scanf("%lf", (unit=='C')? &cels: &fahr);

if(unit == 'C')

fahr = 9.0*cels/5.0+32.0;

else

cels = 5.0*(fahr-32.0)/9.0;

printf("%.3f degrees Fahrenheit is %.3f degrees Celsius\n", fahr, cels);

return 0;

}

#include <stdio.h>

#include <ctype.h>

int main() {

double fahr, cels;

int unit; /*'C' for Celsius input, 'F' for Fahrenheit*/

/*get input type*/

printf("Type C to convert Celsius to Fahrenheit, or F to go the other way: ");

unit = toupper(getchar());

/*get input, and do the appropriate calculation*/

printf("degrees? ");

if(unit == 'C') {

scanf("%lf", &cels);

fahr = 9.0*cels/5.0+32.0;

} else {

scanf("%lf", &fahr);

cels = 5.0*(fahr-32.0)/9.0;

}

printf("%.3f degrees Fahrenheit is %.3f degrees Celsius\n", fahr, cels);

return 0;

}

Loops (Iterations)

The for Loop Syntax

for (initialize; check; update) {

statements

}

Example: forLoop

#include <stdio.h>

#include <stdlib.h>

int main(){

int i;

for(i = 0; i <= 10; i++){

// Inside the loop

printf("loop count = %d\n", i);

}

// End of the loop

return 0;

}

The while Loop Syntax

while(expression)

Statement;

Or like this!

while(expression) {

Statements

}

Example: while Loop

include <stdio.h>

#include <stdlib.h>

int main(){

int input_c;

/* The Classic Bit */

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

}

return 0;

}

The do-while Loop Syntax

do {

statements

} while(expression);

while(expression) {

statements

}

Example: forand while Loops

#include <stdio.h>

#include <stdlib.h>

int main(){

int i;

i = 0;

while(i <= 10){

printf("%d\n", i);

i++;

}

return 0;

}

#include <stdio.h>

#include <stdlib.h>

int main(){

int i;

for(i = 0; i <= 10; i++){

printf("%d\n", i);

}

return 0;

}

Example: do-while Loop

#include <stdio.h>

#include <stdlib.h>

int main(){

int i; i = 0;

/* check */

do {

printf("%d\n", i);

/* increment i */

i++;

} while(i <= 10);

return 0;

}

The switch Statement

expression = some_value; /* can be the result of another expression or a user defined value. */

some_value can be const1, const2,..., const100 or else

switch (expression){

case const1: statements ; break;

case const2: statements; break;

...

case const100: statements; break

default: statements; break;

}

Example: switch Statement

#include <stdio.h>

#include <stdlib.h>

int main(){

int i;

for(i = 0; i <= 3; i++){

switch(i){

case 1: printf("1 \n");

break;

case 2: printf("2 \n");

break;

case 3: printf("3 \n");

break;

default: printf("default\n");

break;

}

}

return 0;

}

#include <stdio.h>

#include <stdlib.h>

int main(){

int i;

for(i = 0; i <= 3; i++){

if (i == 1) printf("1 \n");

else if (i == 2) printf("2 \n");

else if (== 3) printf("3 \n");

else printf("default\n");

}

return 0;

}

The break statemet

#include <stdio.h>

#include <stdlib.h>

int main(){

int i;

for(i = 0; i < 100000000; i++){

printf("Press s to stop");

if(getchar() == 's')

break;

printf("%d\n", i);

}

return 0;

}

The continue Statement

#include <stdio.h>

int main(){

int i;

for(i = -10; i < 10; i++){

if(i == 0 || i==6 || i == 9 )

// do not print 0, 6, and 9, continue with others

continue;

printf("%d \n", i);

// Other statements .....

}

return 0;

}

Functions

Modularization – easier to

code

debug

Code reuse

Passing arguments to functions

By value

By reference

Returning values from functions

By value

By reference

Functions - why and how ?

#include <stdio.h>

#include <stdlib.h>

/** function prototype declarations start here**/

int GetPosinteger(void); // or just int GetPosinteger();

/** End of function prototype declarations **/

int main()

{

int x, y, z;

x = GetPosinteger();

y = GetPosinteger();

printf("%d + %d = %d\n", x, y, add(x,y));

return 0;

}

return a+b;

}

int GetPosinteger(void)

{

int a;

do

{

printf("Enter a positive integer: ");

scanf("%d", &a);

} while (a <= 0);

return a;

}

Functions are subprograms!

• The syntax for declaring a function:

• return-type function-name (argument declarations){local variable declarationsStatements

• }

• Signature (or prototype) of a function:

• return-type function-name (argument list)

Void in void out

voidprint_message(void) // Inputs are void!

{

// Here void means no input parameter and no return value

printf("hello"); // No return

}

intadd(int a, int b) // We have two int inputs a & b

{

int sum;

sum = a + b;

return sum; // This is the output

}

Functions – Call by Value

• #include <stdio.h>

• int sum(int a, int b);

• /* function prototype at start of file */

• void main(void){

• int total = sum(4,5); /* call to the function */

• printf("The sum of 4 and 5 is %d", total);

• }

• int sum(int a, int b){ /* the function itself

• - arguments passed by value*/

• return (a+b); /* return by value */

• }

Functions- Call by Reference(later!!)

#include <stdio.h>

/* function prototype at start of the code */

int sum(int *pa, int *pb); // Pointer references as input

void main(void){

int a=4, b=5;

int *ptr = &b; int total;

total = sum(&a,ptr); /* call to the function */

printf("The sum of 4 and 5 is %d", total);

}

int sum(int *pa, int *pb){

/* the function definition here

- arguments passed by reference */

return (*pa+*pb); /* return by ref */

}

User Interface

{

printf("The following options\n");

printf("R ==> Register a book\n ");

printf("D ==> Display data about all books\n "); printf("F ==> Find and show a book\n ");

printf("Enter [R,D,F] or [Q] to Quit: ");

}

void main(void)

{

char opt;

opt=getchar();

do {

switch (opt) {

case 'r'| R': Register(); break;

case 'f'|'F': Find(); break;

case 'd'|'D': Show_data(); break;

case 'd'|'D': break();

}

}while (opt != 'q' && opt != 'Q');

}

# include<stdio.h>

# typedef enum {worse=-1, bad=0, good=1, best=2} credit;

/* Some global constant definitions, if required ... */

/* Start of function defs */

void register();void list();void find_disp();

void delete();void change();int get_option();

// End of function Defs

/* End of function Defs */

/* Start of main(), Action definitions */

int main() {

/* Some local variable and constant defs */

short int opt;

do {

opt=get_option();

switch(opt)

{

case 1: register(); break;

case 2: list(); break;

case 3: find_disp(); break;

case 4: delete(); break;

case 5: change(); break;

case 6: exit(); /* exit the loop, hence the program */

}

} while(1); /* End of while */

return 0;

} /* End of main() */

Recursive Functions

Recursion = a function calls itself as a function for unknown times. We call this recursive call

for (i = 1 ; i <= n-1; i++) sum++;

int sum(int n) {

if (n <= 1)

return 1

else

return (n + sum(n-1));

}

int f( int x )

{

if( x == 0 )

return 0;

else

return 2 * f( x - 1 ) + x * x;

}

Calculate factorial (n!) of a positive integer:

n! = n(n-1)(n-2)...(n-n-1), 0! = 1! = 1

int factorial(int n) {

if (n <= 1)

return 1;

else

return (n * factorial(n-1));

}

Kth Fibonacci Numbers

kth Fibonacci Numbers

Binary recursion

int BinaryFib(k) {

// Input: An integer k

// Output: The kth Fibonacci number

if (k <= 1) then

return k ;

else

return BinaryFib(k-1)+BinaryFib(k-2);

}

int x=0, y=10, w=20, z, T=1, F=0;

z = (x == 0); /*** logical operator; result --> 0 or 1 ***/

z = (x = 0); /*** assignment operator; result --> ***/

z = (x == 1);

z = (x = 15);

z = (x != 2);

z = (x < 10);

z = (x <= 50);

z = ((x=y) < 10); /*** performs assignment, compares with 10 ***/

z = (x==5 && y<15);

z = (x==5 && y>5 && w==10);

z = (x==5 || y>5 && w==10);

z = (T && T && F && x && x); /*** ==> F; ***/

z = (F || T || x || x); /*** ==> T; ***/

/*** for && and !!, order is specified, stops when result is known, ***/

/*** value of x doesn't matter ***/

Summary of the C Operations

• Operators same as in C++ and Java:

• Arithmetic

• int i = i+1; i++; i--; i *= 2;

• +, -, *, /, %,

• Relational and Logical

• <, >, <=, >=, ==, !=

• &&, ||, &, |, !

• Syntax same as in C++ and Java:

• if ( ) { } else { }

• while ( ) { }

• do { } while ( );

• for(i=1; i <= 100; i++) { }

• switch ( ) {case 1: … }

• continue; break;

Arrays & Pointers

One-Dimensional Arrays

#include <stdio.h>

void main(void)

{

int number[12]; /* 12 cells, one cell per element */

int index, sum = 0;

/* Always initialize arrays before use! */

for (index = 0; index < 12; index++) {

// cells are numbered from 0 to 11 not from 1 to 12!

number[index] = index;

}

for (index = 0; index < 12; index = index + 1) {

sum += number[index]; /* sum array elements */

}

return;

}

int i[10] = { 1,2,3,4,5,6,7,8,9,10 };

Character arrays that hold strings allow shorthand initializations, like

char str[9] = "I like C";

which is the same as:

char str[9] = { 'I',' ','l','i','k','e',' ','C','\0' };

col1 col2 col3 col4 ...

row1: matrix[0][0] matrix[0][1] matrix[0][2] matrix[0][3] ...

row2: matrix[1][0] matrix[1][1] matrix[1][2] matrix[1][3] ...

row3: matrix[2][0] matrix[2][1] matrix[2][2] matrix[2][3] ...

... ... ... ... ...

rowM: matrix[M][0] matrix[M][1] matrix[M][2] matrix[M][3] ...

void fillTable ()

{ int row, col, maxRow, maxCol;

int matrix [maxRow][maxCol];

for (int row = 0; row < maxRow; row++)             for (int col = 0; col < maxCol; col++)                 matrix [row][col] = row + col; }

void fillTable ()

{ int row, col, maxRow, maxCol;

int matrix [maxRow][maxCol];

for (int row = 0; row < maxRow; row++)         for (int col = 0; col < maxCol; col++)              matrix [row][col] = row + col; }

Outer loop executes (with row = 0) first, the inner loop fills in the values in the first row of matrix, namely:

matrix[0][0] = row + col,

matrix[0][1] = row + col,

matrix[0][2] = row + col,

and matrix[0][3] = row + col.

The next round of the outer loop fills in the second row of matrix.

The third and final round of the outer loop fills in the final row of matrix.

void displayTable ()     { int row, col;

for ( row = 0; row < maxRow; row ++)         {             for (col = 0; col < maxCol; col ++) {printf("%d\n",matrix [row][col]);

}printf("\n");         } }

Initialization of Two-dimensional Arrays

Two-dimensional arrays are initialized in the same way as the one-dimensional arrays, e.g.,

int myArray[6][2] =

{

1,1,

2,4,

3,9,

4,16,

5,25,

6,36

};

• Array of Strings

• char name[6];

• name = {‘C’,’S’,’4’,’1’,’4’,’\0’}; /* ’\0’= end of string */

• printf("%s", name); /* print until ‘\0’ */

• Functions to operate on strings

• strcpy, strncpy, strcmp, strncmp, strcat, strncat, etc...

• #include <strings.h> at program start

• Multi-dimensional arrays

• int points[3][4];

• points [1][3] = 12; /* NOT points[3,4] */

• printf("%d", points[1][3]);

#include <stdio.h>

int main() {

char msg[10]; /* array of 10 chars */

char *p; /* pointer to a char */

char msg2[]="Hello"; /* msg2 = ‘H’,’e’,’l’,’l’,’o’,’\0’ */

msg = "Hello"; /* ERROR. msg has a const address.*/

p = "Hello"; /* address of "Merhaba" goes into p */

msg = p; /* ERROR. Message has a constant address. */

/* cannot change it. */

p = msg; /* OK */

p[0] = ‘H’, p[1] = ‘i’,p[2]=‘\0’;

/* *p and msg are now "Hi" */

return 0;

}

int IterativeLinearSum(A,n) {

// Input: An integer array A and an integer n (size)

// Output: The sum of the first n integers

if (n == 1) return A[0];

else

while (n != 0){

sum = sum + A[n];

n = n – 1;

}

return sum;

}

int LinearSum(A,n) {

// Input: An integer array A and an integer n (size)

// Output: The sum of the first n integers

if (n == 1) return A[0];

else

return LinearSum(A,n-1) + A[n-1];

}

void IterativeReverseArray(A,i,n) {

// Input: An integer array A and an integers i and n

// Output: The reversal of n integers in A starting at index i

while (n > 1) {

swap (A[i], A[i+n-1]);

i =i +1;

n = n-2;

}

return;

}

void ReverseArray(A,i,n) {

// Input: An integer array A and an integers i and n

// Output: The reversal of n integers in A starting at index i

if (n > 1) {

swap (A[i], A[i+n-1]);

ReverseArray(A, i+1, n-2);

}

return;

}

Making recursive calls more than a single call at a time.

int BinarySum(A,i,n) {

// Input: An integer array A and an integers i and n

// Output: The sum of n integers in A starting at index i

if (n == 1) {

return A[i];

return BinarySum(A,i,[n/2])+BinarySum(A,i+[n/2],[n/2]);

}

2

10

25

11

34

22

int score[5]

1

i

tmp

max=score[i];

for (i = 0; i < CLASS_SIZE; ++i) {

if (max <= score[i] ) {

max = score[i];

}

}

#include "stdafx.h"

#include <stdio.h>

#define CLASS_SIZE 10

int main(void)

{

int i, score[CLASS_SIZE], max;

printf("Input %d How many scores: ", CLASS_SIZE);

for (i = 0; i < CLASS_SIZE; ++i) {

scanf("%d", &score[i]);

}

max=score[i];

for (i = 0; i < CLASS_SIZE; ++i) {

if (max <= score[i] ) {

max = score[i];

}

}

printf("\nMax is: %d\n\n", max);

return 0;

}

void string_sort(char *s[]){

char tmp; int i, j, length;

length=string_length(s);

for(i=0; i<length-1; i++) {

for (j=i+1; j<length; j++) {

if (strcmp(*s[i], *s[j]) == 0)

{

tmp=s[i]; s[i]=s[j]; s[j]=tmp;

}

}

}

}

int string_length(char str[]){

int i;

for(i=0; i<80; i++)

{

if(str[i]=='\0') return(i);

}

}

2

10

25

11

34

22

int score[5]

3

i

j-1

j

tmp

1

for (i = 0; i < CLASS_SIZE - 1; ++i)

for (j = CLASS_SIZE - 1; j > i; --j)

if (score[j-1] < score[j]) {

tmp = score[j-1];

score[j-1] = score[j];

score[j] = tmp;

}

#include <stdio.h>

#define CLASS_SIZE 5

int main(void)

{

int i, j, score[CLASS_SIZE], sum = 0, tmp;

printf("Input %d scores: ", CLASS_SIZE);

for (i = 0; i < CLASS_SIZE; ++i) {

scanf("%d", &score[i]);

sum += score[i];

}

for (i = 0; i < CLASS_SIZE - 1; ++i) /* bubble sort */

for (j = CLASS_SIZE - 1; j > i; --j)

if (score[j-1] < score[j]) { /* check the order */

tmp = score[j-1];

score[j-1] = score[j];

score[j] = tmp;

}

printf("\nOrdered scores:\n\n");

for (i = 0; i < CLASS_SIZE; ++i)

printf(" score[%d] =%5d\n", i, score[i]);

printf("\n%18d%s\n%18.1f%s\n\n",

sum, " is the sum of all the scores",

(double) sum / CLASS_SIZE, " is the class average");

return 0;

}

void main(void){

char word[32]; /* work space keeps only one word*/

char *w[N]; /* an array of pointers to store words*/

int n; /* number of words to be sorted */

int i;

printf("Enter words\n");

for (i = 0; scanf("%s", word) == 1 ; ++i) {

if (i >= N) break;

if (strlen(word) >= 32) break;

w[i] = (char *)calloc(strlen(word) + 1, sizeof(char));

/* w[i] = new char[strlen(word) + 1]; */

if (w[i] == NULL) printf ("Empty Word ...\n");

strcpy(w[i], word);

}

n = i;

for (i = 0; i < n; ++i) printf("%s\n", w[i]); /* Display words */

}

void sort_words(char *w[], int n) /* sort n words */

{

int i, j;

for (i = 0; i < n; ++i)

for (j = i + 1; j < n; ++j)

if (strcmp(w[i], w[j]) > 0)

swap(&w[i], &w[j]);

}

void swap(char **p, char **q){

char *tmp;

tmp = *p;

*p = *q;

*q = tmp;

}

Pointers!!!!

(&x) 1000

(&x) 1000

x = 10

x = 5

y = 7

y = 7

(&y) 1004

(&y) 1004

1000

ptr = &x = 1000

(&ptr) 1200

(&ptr) 1200

• Pointer = variable containing address of another variable

• intx = 5; /* data variable */

• int y = 7; /* data variable */

• int *ptr = &x; /* & = address operator */

5

7

1200

ptr

x

y

*ptr = 10;

7

10

1200

y

ptr

x

Pointers - 1

any float

f

?

?

?

4300

4304

f

?

4300

4300

4304

float f; /* data variable */

float *f_addr; /* pointer variable */

f

3.2

1.3

4300

4300

4300

4304

f

4300

4304

*f_addr = 3.2; /* indirection operator */

float g=*f_addr; /* indirection:g is now 3.2 */

f = 1.3;

An array name by itsels is an address or pointer value!

#define N 100

int a[N], i, *p, *q, sum = 0;

p = a; /* is equivalent to p = &a[0] */;

p = a + 1; /* is equivalent to p = &a[1] */;

int a[i] /* is equivalent to *(a + i) */;

Here *(a + i) is the dereferencing of the expressin a + i that points i elements positions past in a

p = a; /* points to the base of array a */

q = p + 1; /* equivalent to q =&a[1] */

printf("%d\n", q – p);

printf("%d\n", (int) q - (int) p);

for (p = a; p <&a[N]; ++p) sum += *p;

for (i = 0; i < N; ++i) sum += *(a + i);

• int main(int argc, char* argv[]){

• double a[2], *p, *q;

• p = a; /* points to the base of array a */

• q = p + 1; /* equivalent to q =&a[1] */

• printf("=============================\n");

• printf(" p = %d", p);

• printf("\n q = %d", q );

• printf("\n q - p = %d", q - p);

• printf("\n q - p = %d\n", (int) q - (int) p);

• printf(" &a[0] = %d", &a[0] );

• printf("\n &a[1] = %d &a[1] );

• }

• #include <stdio.h>

void main(void) {

int j;

int *ptr;

ptr=&j; /* initialize ptr before using it */

/* *ptr=4 does NOT initialize ptr */

*ptr=4; /* j <- 4 assign 4 to j*/

j=*ptr; /* j <- ??? Ask students*/

}

• int a = 10, b = 2, *p;

• p = &a; // p is assigned address of a

• b = *p; // b is assigned the value pointed by p

• b = *p; is equivalent to b = a;

• An array name is an address or a pointer value

• Arrays and pointers can be subscripted:

• int A[10], *p; int i = 0; A[0]=23; p=A;

• int b = A[i]; is equivalent to intb = *(A + 0);

• int c = p[i]; is equivalent to intc = *(p + i);

• p = A; is equivalent to p = &A[0];

• p = A + 1; is equivalent to p = &A[1];

All will equally sum the array ellements:

1)

for (p = a; p <&a[N]; ++p)

sum += *p;

2)

for (i = 0; i < N; ++i)

sum += *(a + i);

3)

p = a;

for (i = 0; i < N; ++i)

sum += p[i];

• Whenever variables are passed as arguments to a function, their values are copied to the function parameters:

• int main(){

• int a=20; int b=30;

• swap (a, b)

• printf("%d %d: ", a, b);

• return 0;

• }

• void swap(int x, y) {

• int tmp;

• tmp=x;

• x=y;

• y=tmp;

• }

• Pointers are passed as arguments to a function, their addresses are assigned to the function parameters defined as pointers:

• int main(){

• int a=20; int b=30;

• swap (&a, &b)

• printf("%d %d: ", a, b);

• return 0;

• }

• void swap(int *x, int *y) {

• int tmp;

• tmp = *x; // get value pointed by x.

• *x = *y; // assign value pointed by y to x

• *y = tmp;

• }

#include <stdio.h>

void swap(int, int);

int main() {

int num1 = 5, num2 = 10;

swap(num1, num2);

printf("num1 = %d and num2 = %d\n", num1, num2);

return 0;

}

void swap(int n1, int n2) { /* passed by value */

int temp;

temp = n1;

n1 = n2;

n2 = temp;

}

#include <stdio.h>

void swap(int *, int *);

int main() {

int num1 = 5, num2 = 10;

swap(&num1, &num2);

printf("num1 = %d and num2 = %d\n", num1, num2);

return 0;

}

void swap(int *n1, int *n2) { /* passed and returned by reference */

int temp;

temp = *n1;

*n1 = *n2;

*n2 = temp;

}

Arrays as Function Arguments

#include <stdio.h>

void init_array(int array[], int size) ;

void main(void) {

int list[5];

init_array(list, 5);

for (i = 0; i < 5; i++)

printf("next:%d", array[i]);

}

void init_array(int array[], int size) { /* why size ? */

/* arrays ALWAYS passed by reference */

int i;

for (i = 0; i < size; i++)

array[i] = 0;

}

int month[12]; /* month is a pointer to base address 430*/

month[3] = 7; /* month address + 3 * int elements

=> int at address (430+3*4) is now 7 */

ptr = month + 2; /* ptr points to month[2],

=> ptr is now (430+2 * int elements)= 438 */

ptr[5] = 12;

/* ptr address + 5 int elements

=> int at address (434+5*4) is now 12.

Thus, month[7] is now 12 */

ptr++; /* ptr <- 438 + 1 * size of int = 442 */

(ptr + 4)[2] = 12; /* accessing ptr[6] i.e., array[9] */

• Nowmonth[6], *(month+6), (month+4)[2], ptr[3], *(ptr+3) are all the same integer variable.

Pointer Example - argc and argv parameters

#include <stdio.h>

/* program called with cmd line parameters */

void main(int argc, char *argv[]) {

int ctr;

for (ctr = 0; ctr < argc; ctr = ctr + 1) {

printf("Argument #%d is -> |%s|\n", ctr, argv[ctr]);

} /* ex., argv[0] == the name of the program */

}

Pointers to function

int func(); /*function returning integer*/

int *func(); /*function returning pointer to integer*/

int (*func)(); /*pointer to function returning integer*/

int *(*func)(); /*pointer to func returning ptr to int*/

#include <stdio.h>

void myproc (int d);

void mycaller(void (* f)(int), int param);

void main(void) {

myproc(10); /* call myproc with parameter 10*/

mycaller(myproc, 10); /* and do the same again ! */

}

void mycaller(void (* f)(int), int param){

(*f)(param); /* call function *f with param */

}

void myproc (int d){

. . . /* do something with d */

}

Container Data types: Structures

#include <stdio.h>

struct birthday{

int month;

int day;

int year;

};

int main() {

struct birthday mybday;

mybday.day=1; mybday.month=1; mybday.year=1977;

printf("I was born on %d/%d/%d", birth.day,

birth.month, birth.year);

return 0;

}

Structures Cont’d

struct person{

char name[41];

int age;

float height;

struct { /* embedded or nested structure */

int month;

int day;

int year;

} birth;

};

struct person me;

me.birth.year=1977;………

struct person class[60];

/* array of info about everyone in class */

class[0].name="CS206"; class[0].birth.year=1971;……

struct exp {

char c;

int i;

float arr[10];

};

struct exp exp1; struct exp *expPtr;

exp1.c = ‘A’; i = 20;

prinf("%c%d ", exp1.c, exp1.i);

expPtr->c=‘B’; expPtr->i=30;

prinf("%c%d ", expPtr->c, expPtr->i);

expPtr = &exp1;

prinf("%c%d ", expPtr->c, expPtr->i);

prinf("%c%d ", (*expPtr).c, (*expPtr).i);

#include <stdio.h>

enum month{

JANUARY, /* like #define JANUARY 0 */

FEBRUARY, /* like #define FEBRUARY 1 */

MARCH /* like #define MARCH2 */

APRIL /* like #define APRIL2 */

};

/* JANUARY is the same as month.JANUARY */

/* alternatively, …. */

enum month{

JANUARY=1, /* like #define JANUARY 1 */

FEBRUARY = 2, /* like #define FEBRUARY 2 */

MARCH /* … */

};

typdef: Synonym for a data type

• Easier to remember

• For Clean code creation

typedef int numbers;

numbersa_number; /* same as int a_number; */

typedef struct person Person;

Person me; /* same as struct person me; */

typedef struct person *Personptr;

Personptr ptrtome; /* same as struct person *ptrtome;*/

Memory layout of programs

0

100

400

560

1010

1200

Code

all malloc()s

Dynamic memory

Data - Heap

Local memory

+ function call

stack

all normal vars

• Explicit allocation and de-allocation

#include <stdio.h>

void main(void) {

int *ptr;

/* allocate space to hold an int */

ptr = malloc(sizeof(int));

/* Put something into the space */

*ptr=4;

free(ptr);

/* free up the allocated space */

char *w[10]; /* Space for 10 words: pointer array */

char word[12]

w[i] = calloc(strlen(word) + 1, sizeof(char));

/* allocate space to hold a word (string) */

}

Structures: Summary

#include <stdio.h>

struct birthday{

int month;

int day;

int year;

};

int main() {

struct birthday mybday; /* Create structure */

mybday.day=1;

mybday.month=1;

mybday.year=1977;

printf("I was born on %d/%d/%d", birth.day,

birth.month, birth.year);

return 0;

}

struct person{

char name[41];

int age;

float height;

struct { /* embedded structure (iç içe)*/

int month;

int day;

int year;

} birth;

};

struct person me;

me.birth.year=1977;………

struct person class[2];

/* array of info about everyone in class */

class[0].name="Gül Nihal";

class[0].birth.year=1971;

Class[1].name="Mustafa Kemal"; class[0].birth.year=1883;……

/* pass struct by value */

void display_year_1(struct birthday mybday) {

printf("I was born in %d\n", mybday.year);

} /* - inefficient: why ? */

. . . .

/* pass struct by reference */

void display_year_2(struct birthday *pmybday) {

printf("I was born in %d\n", pmybday->year);

/* warning ! ‘->’, not ‘.’, after a struct pointer*/

}

. . . .

/* return struct by value */

struct birthday get_bday(void){

struct birthday newbday;

newbday.day=02;

newbday;newbday.month=08;

newbday.year=1971;

return newbday;

}

File Operations

### File I/O:Writing Data to FilesReading Data From Files

File Input Output Operations

File I/O

• Open the file

• Do operations on the File

• Close the file

• In C, each file is simply a sequential stream of bytes. C imposes no structure on a file.

• A file must first be opened properly before it can be accessed for reading or writing. When a file is opened, a file handle is associated with the file.

• Successfully opening a file returns a pointer to (i.e., the address of) a file structure,which contains a file descriptor and a file control block.

• The statement:

FILE *fptr1, *fptr2 ;

declares that fptr1 and fptr2are pointer variables of type FILE. They will be assigned the address of a file descriptor, that is, an area of memory that will be associated with an input or output stream.

• Whenever you are to read from or write to the file, you must first open the file and assign the address of its file descriptor (or structure) to the file pointer variable.

• The statement:

fptr1 = fopen ( "mydata", "r" ) ;

would open the file mydata for input (reading).

• The statement:

fptr2 = fopen ("results", "w" ) ;

would open the file results for output (writing).

• Once the files are open, they stay open until you close them or end the program (which will close all files.)

• If the file was not able to be opened, then the value returned by the fopen routine is NULL.

• For example, let's assume that the file mydata does not exist. Then:

FILE *fptr1 ;

fptr1 = fopen ( "mydata", "r") ;

if (fptr1 == NULL)

{

printf ("File 'mydata' could not open.\n") ;

}

Below are modes of opening a file:

"w" open write to text file

"a" append to end of file

"wb" write binary

"ab" binary appending

"r+" Text file read and write

"w+" Text file write and read

• In the following segment of C language code:

int a, b ;

FILE *fptr1, *fptr2 ;

fptr1 = fopen ( "mydata", "r" ) ;

fscanf ( fptr1, "%d%d", &a, &b) ;

the fscanf function would read values from the file "pointed" to by fptr1 and assign those values to a and b.

• The end-of-file indicator informs the program when there are no more data (no more bytes) to be processed.

• There are a number of ways to test for the end-of-file condition. One is to use the feof function which returns a true or false condition:

fscanf (fptr1, "%d", &var) ;

if ( feof (fptr1) )

{

printf ("End-of-file encountered.\n) ;

}

• There are a number of ways to test for the end-of-file condition. Another way is to use the value returned by the fscanf function:

int istatus ;

istatus = fscanf (fptr1, "%d", &var) ;

if ( istatus == EOF )

{

printf ("End-of-file encountered.\n) ;

}

• Likewise in a similar way, in the following segment of C language code:

int a = 5, b = 20;

FILE *fptr2 ;

fptr2 = fopen ( "results", "w" ) ;

fprintf ( fptr2, "%d %d\n", a, b ) ;

the fprintf functions would write the values stored in a and b to the file "pointed" to by fptr2.

• The statements:

fclose ( fptr1 ) ;

fclose ( fptr2 ) ;

will close the files and release the file descriptor space and I/O buffer memory.

#include <stdio.h>

void main ( )

{

FILE *outfile, *infile ;

int b = 5, f ;

float a = 13.72, c = 6.68, e, g ;

outfile = fopen ("testdata", "w") ;

fprintf (outfile, "%6.2f%2d%5.2f", a, b, c) ;

fclose (outfile) ;

infile = fopen ("testdata", "r") ;

fscanf (infile,"%f %d %f", &e, &f, &g) ;

printf ("%6.2f%2d%5.2f\n", a, b, c) ;

printf ("%6.2f,%2d,%5.2f\n", e, f, g) ;

}

12345678901234567890

****************************

13.72 5 6.68

13.72, 5, 6.68

• The last assignment requires us to read several lines of some information from a file and write it out to the screen and to a file. (Sounds repetitive, doesn't it?)

• Simple repetitive tasks are easily performed with a "for" or "while" loop. For example:

int i, ii = 0;

FILE *fptr2 ;

fptr2 = fopen ( "results", "w" ) ;

for ( i = 1 ; i <= n ; i++ )

{

fprintf ( fptr2, "%d %d\n", a, b ) ;

}

fclose (fptr);

#include <ctype.h> #include <fcntl.h>

#include <stdio.h> /* #include <unistad.h> only Unix/linux */

#define BUFSIZE 1024

void main(int argc, char *argv[]) {

char mybuf[BUFSIZE], *p;

int in_fd, out_fd, n;

in_fd = open(argv[1], O_RDONLY);

out_fd = open(argv[2], O_WRONLY | O_EXCL | O_CREAT, 0600);

while ((n = read(in_fd, mybuf, BUFSIZE)) > 0) {

for (p = mybuf; p - mybuf < n; ++p)

if (islower(*p)) *p = toupper(*p);

else if (isupper(*p)) *p = tolower(*p);

write(out_fd, mybuf, n);

}

close(in_fd);

close(out_fd);

}

The following code (conv.c) will convert the content of a file having lowercase letters to corresponding capital (uppercase) letters

Do the followings on UNIX/linux:

gcc –o toupper conv.c

./toupper

fp = fopen(argv[1], "r+");

tmp_fp = tmpfile();

while ((c = getc(fp)) != EOF)

putc(toupper(c), tmp_fp);

rewind(tmp_fp);

fprintf(fp, "---\n");

while ((c = getc(tmp_fp)) != EOF)

putc(c, fp);

return 0;

}

#include <ctype.h>

#include <stdio.h>

#include <stdlib.h>

int main(int argc, char *argv[]) {

int c; FILE *fp, *tmp_fp;

if (argc != 2) {

printf("\n%s%s%s\n\n%s\n\n", "Usage: "

argv[0], " filename");

exit(1);

}

if (fp=fopen(argv[1],"rw") == NULL) {

printf("Cannot open %s - bye!\n", argv[1]);

exit(1);

}

#include <stdio.h> #include <stdlib.h>

void double_space(FILE *, FILE *);

void prn_info(char *);

int main(int argc, char **argv) {

FILE *ifp, *ofp;

if (argc != 3) {

prn_info(argv[0]);

exit(1);

}

ifp = fopen(argv[1], "r"); /* open for reading */

ofp = fopen(argv[2], "w"); /* open for writing */

double_space(ifp, ofp);

fclose(ifp);

fclose(ofp);

return 0;

}

void double_space(FILE *ifp, FILE *ofp) {

int c;

while ((c = getc(ifp)) != EOF) {

putc(c, ofp);

if (c == '\n')

putc('\n', ofp); /* found a newline - duplicate it */

}

}

void prn_info(char *pgm_name){

printf("\n%s%s%s\n\n%s%s\n\n",

"Usage: ", pgm_name, " infile outfile",

"The contents of infile will be double-spaced ",

"and written to outfile.");

}

Preprocessors & Macros

• Preprocessors extend power of C

• Lines starting with # are preprocessing directives.

• #define macro facility generates inline code in place of functions. They provide fatser execution. Examples:

• #include <stdio.h>

• #include "filename"

• #define identifier token_string

• #define (identifier,…, identifier) token_string

The Use of #define

• #define PI 3.14159

• #define size 1000

• #define seconds_per_day (60*60*2)

• #define EQ ==

• #define LT <

• #define LTE <=

• #define NOT !=

• Example:

int main(){

int i=0

while (i NOT 5){

printf ("hello!");

i++;

}

return 0;

}

• Macros are small codes that can be used

• They execute very fast!

• Syntax:

#define (identifier,…, identifier) token_string

#define sq(x) ((x) * (x))

In the code

int w = 6;

sq(7 + w) expands to ((7 + 6) 0 (7 + 6))

sq(sq(5)) expands to what?

#define min(x,y) (((x) < (y)) ? (x) : (y))

How to call ?

int u,v,m;

scanf("%d%d", &u,&v);

int m = (u,v);

• #define fractional_part(x) (x – (int) x)

• #define random_char() (rand() % 26 + ‘a’)

• #define random_int(x) (rand() % x)

• #define mix(x,y) (((x) > (y)) ? (x) : (y))

int main() {

char a = random_char();

int r = random_int(100);

fractional_part(3.456);

printf("%c%d",c,r,f);

printf("%d%d",min(r,f));

printf("%c%d",max(r,f));

return 0;

}

• In the file ctype.h we have

• #define getchar() getc(stdin)

• #define putcahr() putc((c),stdout)

Your code should contain this at the top

#include <ctype.h>

• All related data are collected in conglomerate structures

• Many types of conglomerate structures:

• Stacks

• Queues (FIFO = First in First Out)

• Trees

• Vectors

• Single

• Double

• Circle

Stacks

Overflow

MAX

PUSH

POP

0

-1

Underflow

const int MaxStack = 1024;

const char EmptyFlag = '\0';

char items [ MaxStack ];

int top;

enum { FullStack = MaxStack, EmptyStack = -1 };

/* Required tack functions are: */

push(char);

char pop();

bool empty(); bool full();

const int MaxStack = 1024;const char EmptyFlag = '\0';

char items [ MaxStack ];

int top;

enum { FullStack = MaxStack, EmptyStack = -1 };

void push(char);char pop();

bool empty(); bool full();

void push(char c){

if (full()) return;

items[++top] = c;

}

char pop(){

if (empty()) return EmptyFlag;

return items[top--];

}

bool full(){

if (top + 1 == FullStack) {

cerr << "Stack Full at " << MaxStack << endl;

return true;

}

return false;

}

bool empty(){

if (top == EmptyStack) {

cerr <<"Stack empty" <<endl;

return true;

}

return false;

}

void main(void){

push(‘A’); push(‘B’);

pop();pop();

pop();

}

Tail

next

next

• Nodes: Represent data storage points

• Pointers: are used to handle nodes

A node

int a

char c

char *name = "kerem"

NULL

• Creating a list element,

• Prepending elements on top of lists,

• Inserting elements into lists,

• Appending to end of lists,

• Finding/searching elements in the list

• Sorting elements,

• Deleting,

• Moving elements around in the list.

int a

char c

char *name = "kerem"

Tail

Tail

next

next

next

next

A node

Tail

previous

previous

NULL

next

next

next

A node

int a

char c

char *name = "kerem"

next

NULL

next

3

2

1

2

3

1

next

next

next

next

next

next

NULL

NULL

struct list {

int data;

struct list *next;

}a;

struct list a, b,c

a.data = 1; b.data=1;c.data=3;

a.next=b.next=c.next = NULL;

a.next = &b;

b.next =&c;

#include <assert.h>#include <stdio.h>

#include <stdlib.h>

#define MAXLINE 100

typedef char DATA; /* will use char in examples */

DATA d;

};

A

B

A

A

B

next

next

next

next

next

next

NULL

NULL

NULL

/* Let’s add a second element */

/* Let’s add a 3rd element */

#include <assert.h>

#include <stdio.h>

#include <stdlib.h>

#define MAXLINE 100

typedef char DATA; /* will use char in examples */

DATA d;

};

#include "list.h"

if (s[0] != '\0') { /* first element */

for (i = 1; s[i] != '\0'; ++i) { /* add to tail */

tail -> next = malloc(sizeof(ELEMENT));

tail = tail -> next;

tail -> d = s[i];

}

tail -> next = NULL; /* end of list */

}

}

#include "list.h"

if (s[0] == '\0') /* base case */

return NULL;

else {

head -> next = string_to_list(s + 1);

}

}

#include "list.h"

{

int count;

++count;

return count;

}

#include "list.h"

{

if (head == NULL) return 0;

else

}

#include "list.h"

{

LIST p;

if (head == NULL) printf("NULL list");

else

for (p = head; p != NULL; p = p -> next)

putchar(p -> d);

}

#include "list.h"

{

if (head == NULL) printf("NULL list");

Else {

}

}

C

A

next

next

next

NULL

Insertion of Elements in a List

#include "list.h"

{

Assert (p1-> next == p2);

p1->next = q;

q->next = p2;

}

initially

p2

p1

q

#include "list.h"

{

LIST p;

if (head == NULL) printf("NULL list");

else

for (p = head; p != NULL; p = p -> next)

free(p);

}

#include "list.h"

{

}

}

First In - First Out Queues

daat

data

next

next

next

NULL

A linked list implementation of a queue

queue

Queue: First-In-First-Out (FIFO) data structure

cnt

front

rear

elem

elem

elem

#define EMPTY 0

#define FULL 10000

typedef unsigned int data;

typedef enum {false, true} boolean;

struct elem { /* an element in the queue */

data d;

struct elem *next;

};

typedef struct elem elem;

struct queue {

int cnt; /* a count of the elements */

elem *front; /* ptr to the front element */

elem *rear; /* ptr to the rear element */

};

typedef struct queue queue;

void initialize(queue *q);

void enqueue(data d, queue *q);

data dequeue(queue *q);

data front(const queue *q);

boolean empty(const queue *q);

boolean full(const queue *q);

#include "queue.h"

void initialize(queue *q){

q -> cnt = 0;

q -> front = NULL;

q -> rear = NULL;

}

data dequeue(queue *q){

data d;

elem *p;

d = q -> front -> d;

p = q -> front;

q -> front = q -> front -> next;

q -> cnt--;

free(p);

return d;

}

Basic queue routines(cont’ d)

void enqueue(data d, queue *q){

elem *p;

p = malloc(sizeof(elem));

p -> d = d;

p -> next = NULL;

if (!empty(q)) {

q -> rear -> next = p;

q -> rear = p;

} else

q -> front = q -> rear = p;

q -> cnt++;

}

Basic queue routines(cont’ d)

data front(const queue *q){

return (q -> front -> d);

}

boolean empty(const queue *q){

return ((boolean) (q -> cnt == EMPTY));

}

boolean full(const queue *q){

return ((boolean) (q -> cnt == FULL));

}

The End (for now)