Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Further C  Multiple source code file projects  Structs  The preprocessor  Pointers.

Similar presentations


Presentation on theme: "1 Further C  Multiple source code file projects  Structs  The preprocessor  Pointers."— Presentation transcript:

1 1 Further C  Multiple source code file projects  Structs  The preprocessor  Pointers

2 2 Multiple source code files  Real programs are normally written in the form of several source code files - several.c files  Just one file will contain main()  In an IDE, the files are listed in a ‘project’  so eg your project might contain files called base.c, graphics.c, data.c, with main() being in base.c  The options are normally - u Compile just one file u Build - compiles any changed files, then links u Build all - compiles and links all  In a command line environment, you use a ‘make’ utility to do the equivalent

3 3 Scope across multiple source files  An external variable has scope across all files  It can only be defined in 1 file eg int x;  In other files where it needs to be accessed, it must be declared as extern eg extern int x;  Same applies to functions  An external defined as static has scope restricted to the one file eg static int x;

4 4 Scope across files - example  extern int x in file2.c stops the compiler complaining that x is an undeclared identifier - it is declared in file1.c #include void foo( void); int x; int y; int main() { foo(); return 0; } file1.c extern int x; extern int y; void foo() { x++; y++; return; } file2.c

5 5 Multiple file project exercise Start a new project Add two new files to it - called prog1.c and prog2.c prog1 should contain a global int called x, and a main function prog2 should contain a function called setX, which makes x equal to 4 The main in prog1 should call setX, then display the value of x

6 6  A data structure is a way of arranging and organising sets of data items  In C the struct keyword is used to help set up such structures  A struct is like a record or a row in a database - it consists of a set of named fields  The syntax for declaring a struct is like struct structurename { typefieldname1; typefieldname2;.. }  A variable of this structure is then declared like struct structurename variablename; Structures

7 7 struct stockItemStruct { int barCode; double price; int stockLevel; }; int main() { struct stockItemStruct beans; struct stockItemStruct cornflakes; beans.barCode = 100; beans.price = 1.49; beans.stockLevel = 50; cornflakes.barCode = 101; cornflakes.price=2.49; cornflakes.stockLevel = 35; printf("%i \n", beans.barCode); return 0; } type variables structure member reference struct example

8 8 struct exercise Design and write a struct suitable for an employee (no strings so no names yet) Declare 3 employee variables Give the fields suitable values Display the 3 employees Keep this program for future use

9 9 The preprocessor  This is a software tool which acts on the source code carrying out various textual processes - before the compiler operates  Preprocessor directives start with a #  The main ones are u #include- for including header files u #define- to define constants and macros u #if- conditional

10 10 #include  the purpose is to include header files. These define constants and prototype standard library functions  #include “myheader.h” will make the preprocessor look for myheader.h in the current directory - used for headers you write  #include means the preprocessor will look in an implementation-defined directory - used for standard headers like

11 11 #define  used to define constants eg #define PI 3.1415962 no equals, no ;  used to define macros - similar to functions  eg macro to find the larger of 2 values: #include #define bigger( a, b ) a > b ? a : b int main() { int x; int y = 2, z = 3; x= bigger( y-3, z-1); printf(" x = %i\n",x); return 0; }

12 12 macro errors  macros are prone to bugs which are hard to see eg  a macro to square a number : #include #define square( a ) a * a int main() { int y, x = 2; y=square( x ); printf(" y = %i\n",y); // get 4 - correct y=square( x+1 ); printf(" y = %i\n",y); // get 5 - wrong should be 9 return 0; }  because square(x) becomes x * x  but square ( x +1 ) becomes x + 1 * x + 1 which is 2x+1 not x 2  should be square ( a ) ( a ) * ( a )

13 13 macro exercise Following the example #define bigger( a, b ) a > b ? a : b write a macro called cube which works out the cube of its argument test it works

14 14 #if - first technique  Writing code which is easily switched between platforms  eg a code fragment.. #if defined UNIX... blah - UNIX-specific code... #elif defined MSDOS.. DOS-specific code #else #error platform not specified #endif  then put a line in code at start #define UNIX and compile UNIX version, then change that to #define MSDOS and compile an MSDOS version

15 15 #if - second technique  problem with multiple includes eg each source code file in project contains #include so the compiler will see lines like #define SEEK_END 2 more than once, giving a macro re-definition warning  can solve problem with only doing #include in one file - but very difficult to track..  solution is like this.. stdio.h starts #ifndef _INC_STDIO #define _INC_STDIO..... rest of it #endif  on the first include, _INC_STDIO is not defined, so it defines it, and all the rest  on second and subsequent includes, it is defined, so rest of file ignored

16 16 pointers  pointers are actually addresses where values are stored in memory  but they are better thought of as being things which ‘point to’ data stored  symbol & means ‘the address of’ so &x is the address of x - where it is stored  symbol * means ‘the value stored at’ so *p is the value stored at where p points to

17 17  x=3 does the following..  x is stored at address 1003 (maybe), so..  addressvalue there 10033  pointer_variable = &x does this..  &x is the address of x, so pointer_variable becomes 1003  or, now pointer_variable ‘points to’ x  *pointer_variable means the value stored at the address pointer_variable  *pointer_variable = 4; makes the value stored at pointer_variable to be 4  but that is where x is stored  so it changes x to 4.. Addressvalue 10034 pointers - first example #include int main() { int x; int * pointer_variable; x = 3; pointer_variable = &x; *pointer_variable = 4; printf("x = %i\n",x); return 0; }

18 18 dynamic memory allocation  pointers are often used for dynamic storage - the program requests, uses and releases memory as it runs  functions for this are in  int * block; declares block to be a pointer to integer  calloc(20, sizeof(int)) requests the use of some memory - enough for 20 items, each the size of an integer. calloc returns a pointer to the start of it, or NULL if there is not enough memory available  block = calloc(20, sizeof(int)); makes this request, and sets block to point to the start of it  *block is the first integer in this part of memory  *(block+1) is the second  *(block+19) is the last  *(block+20) is the usual error  free(block) releases the memory - so the system can re-use it

19 19 dynamic memory example A program to - get memory to store 20 integers in store 0, 2, 4, 6, 8.. in it print them out release the memory #include int main() { int i; int * block; block = calloc(20, sizeof(int)); if (block) { for (i=0; i<20; i++) *(block+i)=2*i; for (i=0; i<20; i++) printf("Offset %2i Value %i\n",i,*(block+i) ); free(block); } return 0; } Output.. Offset 0 Value 0 Offset 1 Value 2 Offset 2 Value 4 Offset 3 Value 6 Offset 4 Value 8 Offset 5 Value 10 Offset 6 Value 12 Offset 7 Value 14 Offset 8 Value 16 Offset 9 Value 18 Offset 10 Value 20 Offset 11 Value 22 Offset 12 Value 24 Offset 13 Value 26 Offset 14 Value 28 Offset 15 Value 30 Offset 16 Value 32 Offset 17 Value 34 Offset 18 Value 36 Offset 19 Value 38

20 20 Pointer exercise Write a program which - obtains a block of memory to hold 10 integers fills the block with random values prints then out adds them up and displays the total

21 21 pointers and arrays  arrays are implemented in C so that an array with an index is the same as a pointer to the start of a memory block with an offset  the program shown fills an array with 10 random numbers, then outputs them  numbers is declared as an array  When the array is filled, *( numbers + i ) treats numbers as a memory block pointer  When it is output, numbers[ i ] treats numbers as an array again #include int main() { int numbers[ 10 ]; int i; for ( i = 0; i < 10; i++ ) *( numbers + i ) = rand(); for ( i = 0; i < 10; i++) printf("%i\n", numbers[ i ] ); return 0; }

22 22 functions with pointer arguments  arguments are passed to functions by value ie copies  so foo(x,y) cannot change the values of x and y  functions can accept pointers as arguments  like foo( &x, &y )  this cannot change the addresses of x and y  but it can alter the values stored at those addresses  which are the values of x and y  such as this example #include void swap(int * a, int * b) { // exchange values at a and b int temp; // classic 3-cornered swap.. temp = *a; *a = *b; *b = temp; return; } int main() { int x=1, y=2; swap(&x, &y); printf("x = %i, y = %i\n", x, y); return 0; }

23 23 #include int * biggest(int * numbers) { int * where; int offset; int biggestsofar = INT_MIN; for (offset=0; offset<10;offset++) if ( *(numbers+offset) > biggestsofar ) { biggestsofar = *(numbers+offset); where = numbers+offset; } return where; } the example coming up uses a function which returns a pointer to the largest value in an array the main() uses this to find where the biggest number in an array is, then print that value, store INT_MIN there and do this for however many numbers there are there functions returning pointers int main() { int data[10]; int i; int * place; for (i=0; i<10; i++) data[i]=rand(); for (i=0; i<10; i++) { place = biggest(data); printf("%i \n", *place); *place = INT_MIN; } return 0; } Output.. 29358 26962 26500 24464 19169 18467 15724 11478 6334 41

24 24 function and pointer exercise Write a program with no global variables but with functions which - create a block of 10 integers filled with random values a function to display the values in a memory block a function to reverse the values in a memory block main() should call the 'create' block, then display, then reverse, then display again

25 25 pointers to structs suppose we have a struct like struct productStruct { int barCode; int stockLevel; } we can create one of these and get a pointer to it by struct productStruct * prodPtr; prodPtr = calloc(1, sizeof(struct productStruct); we can access a field in this struct by – (*prodPtr).barCode = 99; but more convenient is the arrow notation – prodPtr -> barCode = 99;

26 26 pointers to structures exercise Re-use the employee struct Create a memory block of 100 employee structs Give them suitable random values Display them


Download ppt "1 Further C  Multiple source code file projects  Structs  The preprocessor  Pointers."

Similar presentations


Ads by Google