C Programming for Problem Solving programming Unit- 2
1.
Arrays Introduction • Often weneed many different variables that are of the same type and play a similar role in the program • For example, suppose we have a temperature reading for each day of the year and need to manipulate these values several times within a program. • With simple variables, – We would need to declare 365 variables. – We would not be able to loop over these variables. • An array is a numbered collection of variables of the same type. • An array is a homogeneous collection of data. • The variables in an array share the same name and are distinguished from one another by their numbers or subscripts. • We can loop through the variables of an array by using a variable for the subscript. • The subscripts are always 0,1,…, size-1
2.
Array Characteristics Anarray represents a group of related data. An array has two distinct characteristics: An array is ordered: data is grouped sequentially. In other words, here is element 0, element 1, etc. An array is homogenous: every value within the array must share the same data type. In other words, an int array can only hold ints, not doubles. How to create an Array Before you create an array, you need to decide on two properties: Element type: what kind of data will your array hold? ints, double, chars? Remember, you can only choose one type. Array size: how many elements will your array contain? When you initially write your program, you must pick an array size. Your array will stay this size throughout the execution of your program. In other words, you can change the size of an array at compile time, but cannot change it at run-time.
3.
Declaring Arrays Todeclare regular variables we just specify a data type and a unique name: int number; To declare an array, we just add an array size. For example: int temp[5]; creates an array of 5 integer elements. For example: double stockprice[31]; creates an array of 31 doubles. Syntax for Declaring Arrays Where: elementType: data type of each element in the array. arrayName: name of the variable you are declaring. size: number of elements allocated for this array. elementType arrayName [size]
4.
Initializing Arrays Youhave three options for initializing your arrays. But, first, REMEMBER THIS: Just like regular variables, arrays that have not been initialized may contain “garbage values.” But, now, the stakes are even higher. If you declare an array with 31 elements, and forget to initialize it, you end up with 31 garbage values! Option 1: If you know all the data at compile time, you can specify all your data within brackets: int temp [5] = {45, 47, 44, 56, 49}; Option 2: If you omit the size of your array, but specify an initial set of data, the compiler will automatically determine the size of your array. int temp [] = {45, 47, 44, 56}; Here, the compiler creates an array of 4 elements. Option 3: If you do not know any data ahead of time, but you want to initialize everything to 0, just use 0 within { }. For example: int temp[5] = {0}; This will initialize every element within the array to 0.
5.
Referencing Array Elements •Suppose we have an array, temperature, for the temperature readings for the year. • The subscripts would be 0,1,…,364. • To refer to the reading for a given day, we use the name of the array with the subscript in brackets: temperature[4] for the fifth day. 75 79 82 70 68 65 58 63 67 61 temperature temperature[4] • To assign the value 89 for the 150th day: temperature[149] = 89; • We can loop through the elements of an array by varying the subscript. To set all of the values to 0, say for (i = 0; i < 365; ++i) temperature[i] = 0;
6.
#include <stdio.h> #define SIZE12 void main() { int a[SIZE] = {1, 3, 5, 4, 7, 2, 99, 16, 45, 67, 89, 45}; int i, total = 0; for (i = 0; i <= SIZE - 1; i++) total += a[i]; printf("Total of array element values is %dn", total); getch(); } C does not provide array bounds checking Hence, if we have double stockPrice[5]; printf ("%g", stockPrice[10]); This will compile, but you have overstepped the bounds of your array. You may therefore be accessing another variable in your program or another application.
7.
2D Arrays • Anarray of arrays is called a two-dimensional array and can be regarded as a table with a number of rows and columns: 'J' 'o' 'h' 'n' 'M' 'a' 'r' 'y' 'I' 'v' 'a' 'n' is a 3 4 array: 3 rows, 4 columns 'J' 'o' 'h' 'n' 'M' 'a' 'r' 'y' 'I' 'v' 'a' 'n' type of element in each slot name of array number of rows number of columns • This is an array of size 3 names[3] whose elements are arrays of size 4 [4] whose elements are characters char • Declare it like this: char names[3][4];
8.
Initializing 2D arrays •An array may be initialized at the time of declaration: char names[3][4] = { { 'J', 'o', 'h', 'n'} , { 'M', 'a', 'r', 'y'} , { 'I', 'v', 'a', 'n'} }; • An integer array may be initialized to all zeros as follows: • This only works for zero. int nums[3][4] = {0}; nums[0][0] = 16; printf("%d", nums[1][2]); • To access an element of a 2D array, you need to specify both the row and the column: 'J' 'o' 'h' 'n' 'M' 'a' 'r' 'y' is stored: 'J' 'o' 'h' 'n' 'M' 'a' 'r' 'y' Address ... 4269 4270 4271 4272 4273 4274 4275 4276 ... • Two-dimensional arrays in C are stored in "row-major format": the array is laid out contiguously, one row at a time:
9.
/* Fill 2-darray, print out values, sum the array. */ #include <stdio.h> #define M 3 /* Number of rows */ #define N4 /* Number of columns */ int main(void){ int a [ M ] [ N ], i, j, sum = 0; for ( i = 0; i < M; ++i ) /* fill the array */ for (j = 0; j < N, ++j ) a [ i ] [ j ] = i + j; for ( i = 0; i < M; ++i ){/* print array values */ for (j = 0; j < N, ++j ) printf(“a [ %d ] [ %d ] = %d “, i, j, a[ i ] [ j ]); printf (“n”); } for ( i = 0; i < M; ++i ) /* sum the array */ for (j = 0; j < N, ++j ) sum += a[ i ] [ j ]; printf(“nsum = %dnn”); return 0; } Produces the output: a[ 0 ] [ 0 ] = 0 a[ 0 ] [ 1 ] = 1 a[ 0 ] [ 2 ] = 2 a[ 0 ] [ 3 ] = 3 a[ 1 ] [ 0 ] = 1 a[ 1 ] [ 1 ] = 2 a[ 1 ] [ 2 ] = 3 a[ 1 ] [ 3 ] = 4 a[ 2 ] [ 0 ] = 0 a[ 2 ] [ 1 ] = 3 a[ 2 ] [ 2 ] = 4 a[ 2 ] [ 3 ] = 5 sum = 30
10.
• Array declarationsread right-to-left • int a[10][3][2]; • “an array of ten arrays of three arrays of two ints” • In memory 2 2 2 3 2 2 2 3 2 2 2 3 ... 10 Multi Dimensional Arrays
11.
Strings • C hasno native string type, instead we use arrays of char • A special character, called a “null”, marks the end • This may be written as ‘0’ (zero not capital ‘o’) • This is the only character whose ASCII value is zero • Depending on how arrays of characters are built, we may need to add the null by hand, or the compiler may add it for us Example char first_name[5] = { 'J', 'o', 'h', 'n', '0' }; char last_name[6] = "Minor"; char other[] = "Tony Blurt"; char characters[7] = "No null"; 'J' 'o' 'h' 'n' 0 first_name 'M' 'i' 'n' 'o' 'r' last_name 0 'T' 'o' 'n' 'y' 32 other 'B' 'l' 'u' 'r' 't' 0 'N' 'o' 32 'n' 'u' characters 'l' 'l' this special case specifically excludes the null terminator
12.
Printing Strings • Stringsmay be printed by hand • Alternatively printf supports “%s” char other[] = "Tony Blurt"; int i = 0; while(other[i] != '0') printf("%c", other[i++]); printf("n"); printf("%sn", other); •Null Really Does Mark the End! #include <stdio.h> int main(void) { char other[] = "Tony Blurt"; printf("%sn", other); other[4] = '0'; printf("%sn", other); return 0; } Tony Blurt Tony 'T' 'o' 'n' 'y' 32 other 'B' 'l' 'u' 'r' 't' 0 even though the rest of the data is still there, printf will NOT move past the null terminator
13.
Strings in Arrays •A char char array is a fairly good ‘string variable’, and you can initialize it with a string constant: char msg[80]= {“one line of text.”}; char msg[80]= {“one line of text.”}; • Print a string variable using %s %s and printf(); printf(); printf(“You typed printf(“You typed %s %s”, ”, msg msg); ); • Read a string variable using %s %s and scanf(); scanf(); printf(“Type answer, press return:”); printf(“Type answer, press return:”); scanf(“ scanf(“ %s %s”, ”,msg msg); ); SURPRISE! SURPRISE! scanf() uses NO ampersand (& &) for string variables (array name), unlike ordinary variables WHY? --array name is an address—of the 0th array element --for ordinary variable ‘var’, writing ‘&var’ means ‘give me the address of var’
14.
Character I/O fromKeyboard To read characters from the keyboard and write to screen: c = getchar( ); putchar(c); • To input strings, you can use scanf() or gets(). • But it’s important to understand the difference between the two. • scanf reads in character data until the first white space character. – Whitespace = space, tab, or new line character. • For example, given the following program: scanf ("%s", name); printf ("Hello, %s!", name); • If I enter "Ethan Cerami", the program will print: Hello, Ethan! • That’s because scanf reads up until the first space character. gets() • Gets: reads in character data until the new line character. • For example: gets (name); printf ("Hello, %s!", name); • If I enter "Ethan Cerami", the program will print: Hello, Ethan Cerami!
15.
Functions • A functionreceives zero or more parameters, performs a specific task, and returns zero or one value • A function is invoked by its name and parameters • No two functions have the same name in a C program • Communication between the function and its invocation is through its parameters and its return value • A function is independent: – It is completely self-contained – It can be called from any place in your code and can be ported to another program • Functions make programs reusable and readable • Divide and conquer – Construct a program from smaller pieces or components – Each piece more manageable than the original program • Programs written by combining user-defined functions with library functions • C standard library has a wide variety of functions - Makes programmer's job easier - avoid reinventing the wheel
16.
Function Syntax return_type function_name(type1 name1, type2 name2, ..., typen namen) ; Semi-colon indicates that this is only the function prototype, and that its definition will be found elsewhere Parameter names can be omitted from the function prototype Return type and parameter types must be provided in the prototype Function Prototype: - Function_name: any valid identifier - Return_type: data type of the result (default int) - void - function returns nothing - Returning control If nothing returned return; or, until reaches right brace If something returned return expression;
17.
return_type function_name (type1name1, type2 name2, ...,typen namen) { ....statements... } Body of the function appears in its definition Parameter names are required here – they’ll be used in the function body No semi-colon Function Definition: – Declarations and statements: function body (block) • Variables can be declared inside blocks (can be nested) • Function can not be defined inside another function
18.
Passing Arguments • Argumentsin the function call (actual parameters) match up with arguments in the function header (formal parameters) by position • Function call: func1 (a, b, c); • Function header: int func1 (int x, int y, int z) • Each argument in the call can be any valid C expression that has a value of the appropriate type Local Variables • Variables declared within the function are considered local variables • Can only be used inside the function they were declared in, and not elsewhere int func1 (int y) { int a, b = 10; float rate; double cost = 12.55; ....... }
19.
1. Function prototype(3 parameters) 2. Input values 2.1 Call function 3. Function definition Program Output 2 /* Finding the maximum of three integers */ 3 #include <stdio.h> 4 5 int maximum( int, int, int ); /* function prototype */ 6 7 int main() 8 { 9 int a, b, c; 10 11 printf( "Enter three integers: " ); 12 scanf( "%d%d%d", &a, &b, &c ); 13 printf( "Maximum is: %dn", maximum( a, b, c ) ); 14 15 return 0; 16 } 17 18 /* Function maximum definition */ 19 int maximum( int x, int y, int z ) 20 { 21 int max = x; 22 23 if ( y > max ) 24 max = y; 25 26 if ( z > max ) 27 max = z; 28 29 return max; 30 } Enter three integers: 22 85 17 Maximum is: 85
20.
String Functions #include <string.h> •int strlen( char str[] ); – Returns length of string str • int strcpy( char to[], char from[] ); – Copies from into to • int strcat( char existing[], char added[] ); – adds added to end of existing • int strcmp( char str1[], char str2[] ); – Returns relationship between strings • value less than 0 means ''str1'' is less than ''str2'‘ • 0 means ''str1'' is equal to ''str2'‘ • value greater than 0 means ''str1'' is greater than ''str2''
21.
Strlen() • C providesa strlen() function. • located in <string.h> • strlen returns the length of a string (does not include the 0 in its calculation.) • For example: char name[100]="Gore"; printf ("%d", strlen (name)); Output: 4 Note, however, that the size of the array is 100 Comparing Strings • C provides a built-in function to compare two strings. • strcmp (str1, str2) fucntion – If str1 and str2 are identical, the function returns 0. Other String Functions • String.h includes lots of other string manipulation functions: – strcat(): appends one string onto the end of the other. – strcpy(): copies one string to another.
Using strcat() #include <stdio.h> #include<string.h> main () { char opening[255] = "And, the Oscar goes to... "; char winner[255] = "American Beauty"; strcat (opening, winner); printf ("%s", opening); getchar(); } Output: And, the Oscar goes to... American Beauty When using strcat, be careful that you do not overrun the array size. For example, do not append a 255 char word to opening.
24.
Using strcpy() #include <stdio.h> #include<string.h> main () { char word1[] = "And, the winner is...."; char word2[255]; strcpy (word2, word1); printf ("%s", word2); getchar(); } Output: And, the winner is.... This copies the contents of word1 into word2.
25.
User-Defined Functions Allows programmersto define special purpose functions with the same advantages of C’s library functions. Some of the advantages of using functions are: • Changing the program into separate pieces • Code reusing • Easier modification and maintenance of the program • More understandable program • A function is a grouping of program statements into a single program unit. • It must be declared before it can be referenced. • One way of declaration is to insert a function prototype before the main function • Function prototype defines the data type of that function (type of the return value), function name and information about the arguments that the function expects.
26.
Calling Functions :Call by Value and Call by Reference • Used when invoking functions • Call by value – Copy of argument passed to function – Changes in function do not effect original – Use when function does not need to modify argument • Avoids accidental changes • Call by reference – Passes original argument – Changes in function effect original – Only used with trusted functions • For now, we focus on call by value
27.
1. Initialize seed 2.Input value for seed 2.1 Use srand to change random sequence 2.2 Define Loop 3. Generate and output random numbers 1 /* 2 Randomizing die-rolling program */ 3 #include <stdlib.h> 4 #include <stdio.h> 5 6 int main() 7 { 8 int i; 9 unsigned seed; 10 11 printf( "Enter seed: " ); 12 scanf( "%u", &seed ); 13 srand( seed ); 14 15 for ( i = 1; i <= 10; i++ ) { 16 printf( "%10d", 1 + ( rand() % 6 ) ); 17 18 if ( i % 5 == 0 ) 19 printf( "n" ); 20 } 21 22 return 0; 23}
28.
Placement of Functions •For large programs – Put related functions in a .c file – Write a .h (header) file that contains the function prototypes – #include the header file in the files that uses the functions • For small programs in a single .c file, use this order: – All prototypes – main() function – Other functions • mymath.h int min(int x,int y); int max(int x,int y); • mymath.c int min(int x,int y) { return x>y?y:x; } int max(int x,int y) { return x>y?x:y; }
29.
Common programming errorswith functions • Not using #include preprocessor directive for the predefined functions • Not defining a prototype before the main and definition after the main for the user defined functions • Not using the correct order and type for the arguments of the functions • Dividing by zero in the function body Transfer of Control in function call • When the computer executes a function call statement, it transfers control to the function definition. In the function definition after execution of the last statement in the function body, computer returns the control to the main program and executes the next statement after the function call.
30.
Simple Recursion • Recursionis where a function calls itself. • Concept of recursive function: – A recursive function is called to solve a problem – The function only knows how to solve the simplest case of the problem. When the simplest case is given as an input, the function will immediately return with an answer. – However, if a more complex input is given, a recursive function will divide the problem into 2 pieces: a part that it knows how to solve and another part that it does not know how to solve. – The part that it does not know how to solve resembles the original problem, but of a slightly simpler version. – Therefore, the function calls itself to solve this simpler piece of problem that it does now know how to solve. This is what called the recursion step. – The recursion step is done until the problem converges to become the simplest case. – This simplest case will be solved by the function which will then return the answer to the previous copy of the function. – The sequence of returns will then go all the way up until the original call of the function finally return the result.
31.
Recursive factorial function #include<stdio.h> long factorial(long); void main(void) { int i; for (i = 1; i <= 10; i++) printf(“%2d! = %1dn”, i, factorial(i)); } long factorial(long number) { if (number <= 1) return 1; else return (number * factorial(number-1)); } Calls itself with a simpler version of the problem. • Output: 1! = 1 2! = 2 3! = 6 4! = 24 5! = 120 6! = 720 7! = 5040 8! = 40320 9! = 362880 10! = 3628800 • Any problem that can be solved recursively can also be solved iteratively (using loop). • Recursive functions are slow and takes a lot of memory space compared to iterative functions. So why bother with recursion? There are 2 reasons: Recursion approach more naturally resembles the problem and therefore the program is easier to understand and debug.
32.
Storage Classes auto Every variableand function in C has two attributes: type (int, float, ...) storage class • auto • extern • register • static There are four storage classes: Storage class is related to the scope of the variable a auto uto (the default and the most common) Memory for automatic variables is allocated when a block or function is entered. They are defined and are “local” to the block. When the block is exited, the system releases the memory that was allocated to the auto variables, and their values are lost. auto type variable_name; There’s no point in using auto, as it’s implicitly there anyway Declaration:
33.
Storage class static •Thiscan be useful, e.g., for debugging: you can insert code like this anywhere without interfering with the rest of the program • { /* debugging starts here */ static int cnt = 0; printf(“*** debug: cnt = %d, v = %dn”, ++cnt, v); } •The variable cnt is local to the block and won’t interfere with another variable of the same name elsewhere in an outer block; it just increases by one every time this block is encountered. static variables are local variables that keep their previous value when the block is reentered. A declaration static int cnt = 0; will set cnt to zero the first time the function is used; thereafter, it will retain its value from previous iterations.
34.
Storage class register registertells the compiler that the variables should be stored in high-speed memory registers if possible. Only a few such registers are available, and can be assigned to frequently-accessed variables if execution time is a problem. If no register space is free, variables become auto instead. Keep registers in small local blocks which are deallocated quickly. Example: { register int i; for (i=0; i < 100; i++) { ..... } } now obsolete since done automatically by most compilers register is freed on block exit
35.
Storage class extern globalvariables (defined outside functions) and all functions are of the storage class extern and storage is permanently assigned to them extern type variable_name; Within a file variables outside functions have external storage class, even without the keyword extern . Files can be compiled separately, even for one program. extern is used for global variables that are shared across code in several files.
36.
extern in multi-fileprojects file1.c #include <stdio.h> int a =1, b = 2, c = 3; /* external variables */ int f(void); int main (void) { printf(“%3dn”, f( )); printf(“%3d%3d%3dn”, a, b, c); return 0; } file2.c int f(void) { extern int a; /* look for it elsewhere */ int b, c; a = b = c = 4; return (a + b + c); } return 12 a is global and changed by f print 4, 2, 3 b and c are local and don‘t survive
37.
Scope rules forblocks Identifiers (i.e. variables etc.) are accessible only within the block in which they are declared. A variable that is declared in an outer block is available in the inner block unless it is redeclared. In this case the outer block declaration is temporarily “masked”. Avoid masking! Avoid masking! Use different identifiers instead to keep your code debuggable! Use different identifiers instead to keep your code debuggable! { int a = 2; /* outer block a */ printf(“%dn”, a); /* 2 is printed */ { int a = 5; /* inner block a */ printf(“%dn”, a); /* 5 is printed */ } printf(“%dn”, a); /* 2 is printed */ } /* a no longer defined */ outer a masked outer a masked
38.
Scope rules forfunctions int main (void) { int a = 2, b = 1, c; c = func(a); return 0; } int func (int n) { printf(“%dn”,b b); return n; } variables defined within a function (including main) are local local to this function and no other function has direct access to them! b not defined locally! • the only way to pass variables to a function is as parameters • the only way to pass (a single) variable back to the calling function is via the return statement Exceptions: 1. Global Variables 2. Pointers
39.
Global variables #include <stdio.h> inta = 1, b = 2; /* global variables */ int main (void) { int b = 5; /* local redefinition */ printf(“%d”, a+b); /* 6 is printed */ return 0; } variables defined outside blocks and functions are g global lobal , , i.e. available to all blocks and functions that follow Avoid using global variables to pass parameters to functions! Avoid using global variables to pass parameters to functions! • Only when all variables in a function are local, it can be used in different programs • Global variables are confusing in long code
40.
int a, b,c; file.c Structure and scope of variables of a c-file func1 () { int a, b, c; } main () { int x, y; } { int c,d,e; } block2 { int d,e,f; } block1 { int g; } nested block variables out of scope between parallel blocks variables in scope down nested blocks (except (except for for masking) masking) use it for efficient use of memory
41.
The C Preprocessor •Obeys special commands called preprocessor directives • Indicate certain things to be done to the program code prior to compilation. – Include certain other files when compiling – Replace some code by other code • Statements beginning with # are considered preprocessor directives • Preprocessing – Occurs before a program is compiled – Inclusion of other files – Definition of symbolic constants and macros – Conditional compilation of program code – Conditional execution of preprocessor directives • Format of preprocessor directives – Lines begin with # – Only whitespace characters before directives on a line
42.
The #include PreprocessorDirective • #include – Copy of a specified file included in place of the directive – #include <filename> • Searches standard library for file • Use for standard library files – #include "filename" • Searches current directory, then standard library • Use for user-defined files – Used for: • Programs with multiple source files to be compiled together • Header file – has common declarations and definitions (classes, structures, function prototypes) – #include statement in each file
43.
The #define PreprocessorDirective: Symbolic Constants • #define – Preprocessor directive used to create symbolic constants and macros – Symbolic constants • When program compiled, all occurrences of symbolic constant replaced with replacement text – Format #define identifier replacement-text – Example: #define PI 3.14159 – Everything to right of identifier replaces text #define PI = 3.14159 • Replaces “PI” with "= 3.14159" – Cannot redefine symbolic constants once they have been created
44.
The #define PreprocessorDirective: Macros • Macro – Operation defined in #define – A macro without arguments is treated like a symbolic constant – A macro with arguments has its arguments substituted for replacement text, when the macro is expanded – Performs a text substitution – no data type checking – The macro #define CIRCLE_AREA( x ) ( PI * ( x ) * ( x ) ) would cause area = CIRCLE_AREA( 4 ); to become area = ( 3.14159 * ( 4 ) * ( 4 ) );
45.
The #define PreprocessorDirective: Macros • Use parenthesis – Without them the macro #define CIRCLE_AREA( x ) PI * ( x ) * ( x ) would cause area = CIRCLE_AREA( c + 2 ); to become area = 3.14159 * c + 2 * c + 2; • Multiple arguments #define RECTANGLE_AREA( x, y ) ( ( x ) * ( y ) ) would cause rectArea = RECTANGLE_AREA( a + 4, b + 7 ); to become rectArea = ( ( a + 4 ) * ( b + 7 ) );
46.
Conditional Compilation • Conditionalcompilation – Control preprocessor directives and compilation – Cast expressions, sizeof, enumeration constants cannot be evaluated in preprocessor directives – Structure similar to if #if !defined( NULL ) #define NULL 0 #endif • Determines if symbolic constant NULL has been defined – If NULL is defined, defined( NULL ) evaluates to 1 – If NULL is not defined, this function defines NULL to be 0 – Every #if must end with #endif – #ifdef short for #if defined( name ) – #ifndef short for #if !defined( name )
47.
• # – Causesa replacement text token to be converted to a string surrounded by quotes – The statement #define HELLO( x ) printf( “Hello, ” #x “n” ); would cause HELLO( John ) to become printf( “Hello, ” “John” “n” ); – Strings separated by whitespace are concatenated when using printf