1 / 18

Header Files, Preprocessor

Header Files, Preprocessor. Soon Tee Teoh CS 49C. Pointers Review 1. Question: Write a function Append that takes two arrays of floats and their corresponding lengths as arguments.

tom
Download Presentation

Header Files, Preprocessor

An Image/Link below is provided (as is) to download presentation 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. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Header Files,Preprocessor Soon Tee Teoh CS 49C

  2. Pointers Review 1 • Question: Write a function Append that takes two arrays of floats and their corresponding lengths as arguments. • Append will create a new array (by allocating space in the heap) to contain all the elements of the first array followed by all the elements of the second array. • Append will return this new array. float *Append(float *array1, int len1, float *array2, int len2);

  3. Pointers Review 2 • The function Increment takes a pointer to an integer as an argument. It increments the integer pointed to by the pointer. • Which of the following is the correct way to implement the function? • Which one (if any) is incorrect, and why? void Increment(int *nptr) { int *pptr; pptr = new int(*nptr + 1); nptr = pptr; } void Increment(int *nptr) { *nptr = *nptr + 1; }

  4. Back to “Hello World!” Include the standard C header file so that you can call I/O functions like “printf”. #include <stdio.h> int main() { printf(“Hello World!\n”); return 0; } The entry point of any program is the “main” function. It receives no arguments, and returns an integer. printf prints its argument string to the screen. A string is denoted by letters within double quotations. ‘\n’ means newline. Last line must return a value before exiting the function. Note: Online reference for stdio.h functions available at: http://www.cplusplus.com/reference/clibrary/cstdio/

  5. Header file • stdio.h is a C standard header file. • Including it allows you to use functions like printf, fopen, getchar etc. • There are other common C standard header files. • For example, stdlib.h contains the rand function, and math.h contains math functions like sin, cos, sqrt etc.

  6. Your Own Header files • You can create your own header files. • This is to separate the function declarations from the function definitions. useful.c useful.h #include "useful.h" float square(float x) { return x * x; } int factorial(int x) { if (x==1) { return x; } else { return x * factorial(x-1); } } #ifndef USEFUL_H #define USEFUL_H float square(float x); int factorial(int x); #endif

  7. Include the header file • Now, in order for you to use the functions square and factorial in other files, you’ll need to include the header file. main.c #include <stdio.h> #include “useful.h” int main() { float f; int i; f = square(3.5); i = factorial(10); printf(“The numbers are %f %d\n”, f, i); return 0; }

  8. Compiling in Unix • First, make the object files useful.o and main.o • Then, link the object files together to create the executable. The –c option reads a source file and creates an object file. An object file contains compiled binary code, but is not executable. This line creates the object file main.o This line creates the object file useful.o eniac@teoh(2)% gcc –c main.c eniac@teoh(3)% gcc –c useful.c eniac@teoh(4)% gcc –o myprog main.o useful.oeniac@teoh(5)% myprog The –o option creates an executable with the immediately following filename, in this case “myprog.” Supply all the input files. In this case, the input files are the object files main.o and useful.o Run the executable

  9. Compiling in Windows • Using Microsoft Visual Studio, include all the .c and .h files in the project. • Visual Studio will automatically consider all the dependencies and generate all the necessary object files. • Visual Studio will also automatically link the object files to create an executable.

  10. Preprocessor Directives • There is a preprocessor or pre-compiler that runs before the compiler itself. • Any line in your source code that begins with ‘#’ is a preprocessor directive. It gives instructions to the preprocessor.

  11. #include • The #include instruction tells the preprocessor to append the file named before compiling. • Filenames that are enclosed in < > are standard C libraries. The preprocessor looks for the files in the standard C library directory (wherever it is installed). • Filenames that are enclosed in “” are user-written header files and are loaded from the current directory. useful.h float square(float x); int factorial(int x); What the compiler actually sees (after preprocessor) useful.c float square(float x); int factorial(int x); float square(float x) { return x * x; } int factorial(int x) { if (x==1) { return x;} else { return x * factorial(x-1); } } #include "useful.h" float square(float x) { return x * x; } int factorial(int x) { if (x==1) { return x;} else { return x * factorial(x-1); } }

  12. #ifndef, #define and #endif • “#define” defines a symbol. • Example: “#define ABC” defines the string “ABC”. • Now, the string “ABC” is recognized by the pre-processor. • “#ifndef ABC” means “if the string ABC is not defined” • “#endif” closes the “#ifndef” block. useful.h If the string “USEFUL_H” is not defined #ifndef USEFUL_H #define USEFUL_H float square(float x); int factorial(int x); #endif Define the string “USEFUL_H” A ifndef/endif block

  13. #ifndef in header files • The #ifndef, #define and #endif lines are used in header files to prevent them from being included multiple times. • Sometimes A.h includes B.h, and C.h also includes B.h. • Then, D.c includes both A.h and C.h. In this case, B.h is included twice in D.c. • Without the #ifndef lines, the compiler would complain that functions are declared multiple times. • With the #ifndef lines, the preprocessor would completely ignore B.h the second time it is included.

  14. Other common use of #ifdef • Often used for different modes, for example, debugging mode. • You can put an #ifdef DEBUG-endif pair around some printf statements. • To compile the code in debugging mode, include the line “#define DEBUG” at the beginning of the file. • To compile in non-debugging mode, that is, without printing out those lines, just comment out the “#define DEBUG” line. void func( ) { for (i=0;i<100;i++) { arr[i] = i+10; #ifdef DEBUG // in debugging mode, print this to check the values printf(“%d %d\n”, i, arr[i]); #endif } }

  15. #define some strings • You can define some symbols to be some other strings. • For example: #define PI 3.14159 • Thus, when the preprocessor encounters the string PI in the code, it replaces it with 3.14159. • So, the compiler doesn’t see PI at all. It only sees 3.14159. Source file: What the compiler sees: #define PI 3.14159 float caclarea(float r) { return PI * r * r; } float caclarea(float r) { return 3.14159 * r * r; }

  16. #define some strings • Another common example of the use of #define: “#define ARRAY_LEN 512” • When you decide to go to a larger array size, simply change the line to: “#define ARRAY_LEN 1024” What the compiler sees: Source file: float farray[512]; void incArray( ) { int i; for (i=0;i<512;i++) { farray[i] = farray[i] + 1.0; } } #define ARRAY_LEN 512 float farray[ARRAY_LEN]; void incArray( ) { int i; for (i=0;i<ARRAY_LEN;i++) { farray[i] = farray[i] + 1.0; } }

  17. #define macros • #define can also be used in a more complex way. • You can define a #define string that has arguments. These arguments are enclosed in parenthesis. • For example: #define SQUARE(A) A * A • Then any string that matches SQUARE(A) in the program is changed, where A is any string. It is substituted with A * A, where A is the string encountered. What the compiler sees: Source file: float caclarea(float r) { return 3.14159 * r * r; } #define PI 3.14159 #define SQUARE(A) A * A float caclarea(float r) { return PI * SQUARE(r); }

  18. Danger of Macros • Consider the following example. • What is the actual output? • What is the intended output? • What is the solution to the problem? #define SQUARE(A) A * A int func(int m) { int i; i = SQUARE(4+m); return i; }

More Related