Problem Solving and 'C' Programming Targeted at: Entry Level Trainees Session 15: Files and Preprocessor Directives/Pointers 2007, Cognizant Technology Solutions. All Rights Reserved. The information contained herein is subject to change without notice. C3: Protected
About the Author Created By: Jeyshankar Perumal (125623) Credential Information: Version and Date: Technical Skills: UNIX/C/C++/Oracle Experience: 8.5 Years PSC/PPT/1107/1.0 2
Icons Used Questions Tools Hands on Exercise Coding Standards Test Your Understanding Reference Try it Out A Welcome Break Contacts 3
Problem Solving and 'C' Programming Session 15: Overview Introduction: This session discuss about the random file operation, pre-processor directives and introduces the important concept called pointers. It discusses about pointer declarations, how pointers can be used with arrays 4
Problem Solving and 'C' Programming Session 15: Objective Objectives: After completing this session you will be able to:» Access files in both sequential and random order» Define pre-processor directives» Perform pre-processor operations» Perform conditional compilation» Work with pointers» Explain pointer arithmetic» Perform operations on pointers and arrays 5
Random File Operations For some applications, it may be necessary to access any part of the file directly. This can be achieved by using the functions fseek(), ftell(), and rewind().
ftell() This function takes a file pointer and returns a long integer, which corresponds to the current file pointer position. If it is a binary stream, then the value is the number of bytes from the beginning of the file. If it is a text stream, then the value is the current file pointer position. On success the current file position is returned. On error, the value -1L is returned and error number is set. Syntax: n = ftell(fptr);
fseek() Sets the file position to the given offset. Syntax: fseek( fptr, offset, from_where) The argument offset signifies the number of bytes to seek from the given from_where position. On success zero is returned. On error a nonzero value is returned.
fseek(): Examples fseek Usage Functionality fseek (fp, 0L, 0); fseek (fp, 0L, 2); fseek (fp, 10L, 0); fseek (fp, 10L, 1); Move the file pointer to the beginning Move the file pointer to the end of file Move forward 10 bytes from the beginning Move forward 10 bytes from the current position fseek (fp, -10L, 1); fseek (fp, -10L, 2); Move backward 10 bytes from the current position Move backward 10 bytes from the EOF
rewind() rewind():» Sets the file position to the beginning of the file.» The error and end-of-file indicators are reset» Syntax: rewind(fptr);
Preprocessor Directives Preprocessor directives are lines included in the code that are not program statements but directives for the preprocessor. These lines are always preceded by a hash sign (#). The preprocessor is executed before the actual compilation of code begins, therefore the preprocessor digests all these directives before any executable code is generated for the statements.
Preprocessor Directives (Contd.) Preprocessing is a step that takes place before compilation:» Replace preprocessor tokens in the current file with specified replacement tokens.» Embed files within the current file.» Conditionally compile sections of the current file.» Generate diagnostic messages.» Remove the blank lines in your program, changes the line number of the next line of the source and change the file name of the current file.» Removes comments from the source file.
Preprocessing Operations (Contd.) Pre processing operations are mainly classifieds into: 1.File inclusion 2.Macro substitution 3.Conditional compilation
File Inclusion The #include directive allows external files to be added in to our source file, and then processed by the compiler. Syntax: #include <header file> or #include header file If the file name is enclosed between angle-brackets <>, the file is searched in the directories where the compiler is configured to look for the standard header files. In the second case, the file is searched first in the current working directory.
Macro Substitution #define preprocessor directive is used to define a macro that assigns a value to an identifier. The preprocessor replaces subsequent occurrences of that identifier with its assigned value until the identifier is undefined with the #undef preprocessor directive.
Macro Substitution (Contd.) There are two basic types of macro definitions that can be used to assign a value to an identifier:» Object-like Macros (Symbolic constants): Replaces a single identifier with a specified token or constant value.» Function-like Macros: Associates a user-defined macro function and argument list to an identifier.
Symbolic Constants The preprocessing directives #define and #undef allow the definition of identifiers which can hold a certain value. These identifiers can simply be constants or a macro function. Syntax: #define <symbolic varaiable name> value Example: #define SIZE 10 #define NAME xyz Note: good practice is to use upper case letters.
Symbolic Constants (Contd.) #undef:» Undefines the defined symbolic constant» Syntax: #undef variablename» Example: #undef SIZE
Function Like Macros Syntax: #define macroname(argument list) macrodefn Example: #define sqarea(a) ((a)*(a)) main() { areaofsquare=sqarea(a); ( macro will be expanded here) }
Conditional Compilation A preprocessor conditional compilation directive causes the preprocessor to conditionally suppress the compilation of portions of source code. The directives are:» #if» #ifdef» #ifndef» #else» #elif» #endif
Conditional Compilation (Contd.) Syntax: #if constant_expression #else #endif or #if constant_expression #elif constant_expression #endif
Introduction to Pointers Pointers are variables that contain the memory address of another variable. Variables can contain the value and pointers can contain the address of variable which in turn contains the value. Variable directly references the value and Pointer indirectly references the value. Referencing a value through a pointer is called Indirection. 22
Introduction to pointers(contd.) Memory is allocated for the variable according to the data type specified. int a = 5; 2 bytes of memory will be allocated for variable a. printf( Value = %d, a); prints the value 5. a 5 printf( Address of a = %u, &a); 1000 prints the address 1000
Pointer Operators & - address operator: Unary operator that returns the address of its operand. * - Indirection or de-referencing operator: It returns the value of the variable to which its operand points. 24
Declaration and Initialization A pointer is declared like a normal variable, but with an asterisk before the variable name. The type-specifiers determine the kind of variable the pointer points to. Syntax: data-type *pointer-name; 25
Declaration Example: int x, *px; px = &x; x = 5; x px Variable 5 1000 Values 1000 3000 Address
Declaration (Contd.) For the example in the preceding slide:» printf( x = %d, x); /*prints 5*/» printf( address of x = %d, &x); /*prints 1000*/» printf( address pointed by pointer = %u, px); /*prints 1000*/» printf( address of the pointer = %u, &px); /*prints 3000*/» printf( content pointed by pointer = %d, *px); /*prints 5*/
Initialization Pointer variables should be initialized to 0, NULL, or an address. No other constant can be used for initializing a pointer variable. Pointer variable of a particular data type can only hold the address of the variable of same data type.
Initialization (Contd.) Example:» Valid and invalid pointer assignments: Pointer Assignment Valid / Invalid int a, b, *p = &a, *q = NULL; q = p; b = &a; q = a; Valid Valid Invalid ordinary variables cannot hold address Invalid - cannot assign value to the pointer variable
Pointer Arithmetic A pointer variable can be assigned the address of an ordinary variable or it can be a null pointer. A pointer variable can be assigned the value of another pointer variable. An integer quantity can be added to or subtracted from a pointer variable. One pointer can be subtracted from another pointer variable provided both are pointing to same array. Two pointer variables can be compared.
Pointer Arithmetic (Contd.) Pointer addition or subtraction is done in accordance with the associated data type:» int adds 2 for every increment» char adds 1 for every increment» float adds 4 for every increment» long int adds 4 for every increment
Pointer Arithmetic (Contd.) Example:» int * ptr, i=5;» ptr= &i; - let ptr = 1000 (location of i)» ptr ++; - ptr = 1002 (+2 for integers)» ++*ptr or (*ptr)++ - increments the value of i by 1
Illegal Operations on Pointers Two pointer variables can not be added Pointer variable can not be multiplied or divided by a constant
Pointer and Arrays Array addressing is in the form of relative addressing. Compiler treats the subscript as a relative offset from the beginning of the array. Pointer addressing is in the form of absolute addressing. Exact location of the array elements can be accessed directly by assigning the starting location of the array to the pointer variable.
Pointer and Arrays (Contd.) C treats the name of the array as if it were a pointer to the first element. Thus, if v is an array, *v is the same thing as v[0] and *(v+0).
Pointer to Arrays: Initialization Conventional array is declared and pointer is made to point to the starting location of the array. Syntax: ptr_vble = &array_name [starting index]; OR ptr_vble = array_name;
Pointer to Arrays: Initialization Example int a[5] = {1,2,3,4,5}, *ptr, i; ptr = a ; or ptr = &a[0]; Assume that array starts at location 1000: &a[0] = 1000 a[0] = 1 ptr + 0 = 1000 *(ptr+0) = 1 &a[1] = 1002 a[1] = 2 ptr + 1 = 1002 *(ptr+1) = 2 &a[2] = 1004 a[2] = 3 ptr + 2 = 1004 *(ptr+2) = 3 &a[3] = 1006 a[3] = 4 ptr + 3 = 1006 *(ptr+3) = 4 &a[4] = 1008 a[4] = 5 ptr + 4 = 1008 *(ptr+4) = 5
Pointers and Multi Dimensional Arrays Multi dimensional arrays can be represented by pointer in the following two ways:» Pointer to a group of arrays» Array of pointers
Pointer to a Group of Arrays A two-dimensional array is defined as a pointer to a group of one dimensional array. For example:» int a[3][2] can be represented by a pointer as below, int (*p)[2] /*p is a pointer points to a set of one dimensional array, each with 2 elements*/
Pointer to a Group of Arrays (Contd.) The following representations should be used when a pointer is pointing to a 2D array:» ptr+i /*is a pointer to i th row.*/» *(ptr+i) /*refers to the entire row; actually a pointer to the first element in i th row.*/» (*(ptr + i) +j) /*is a pointer to j th element in i th row*/» *(*(ptr+i) + j)) /*refers to the content available in i th row, j th column*/
Array of Pointers Multi dimensional array can also be expressed in terms of an array of pointers int a[2][2] can be represented as int *ptr[2] *p[3] declares p as array of 3 pointers (*p)[3] declares p as a pointer to a set of one dimensional array of 3 elements
Pointers and Strings Character pointer is a pointer, which can hold the address of a character variable: char name[30] = { C program }; Declare a character pointer as follows: char *p = NULL; Assign the address of the array to pointer: p = name; String can be represented by either as one-dimensional character array or a character pointer: char *p = string ;
Ragged Arrays char names[3][10] = { abcde, rstu, xyz }» The array occupies 30 bytes» The row length is fixed Instead of making each row a fixed number of characters, make it a pointer to a string of varying length:» char *names[3] = { abcde, rstu, xyz } This occupies only 15 bytes Creates 3 pointers, each pointing to a character array This is called Ragged Array To access jth character in ith row of an array named name array, *(names[ i ] + j)
Q & A Allow time for questions from participants 44
Try it Out - 1 Problem Statement: Write a program to print the address of character, float and integer array. 45
Try it Out - 1 (Contd.) Code: #include <stdio.h> main() { char *c, ch[10]; int *i, j[10]; float *f, g[10]; int x; c = ch; i = j; f = g; } for ( x=0 ; x<10 ; x++ ) printf("%p %p %p\n", c+x, i+x, f+x); getchar(); Refer File Name : <ses15_1.c> for soft copy of the code 46
Try it Out - 1 (Contd.) How it Works: This program declares both array and the pointer for char, int and float. The address of array is assigned to the corresponding pointers Print the pointer, it prints the address it points to. Each pointer is moved to 10 bytes and again print the pointer Continue till 10 times. This give good idea on traversing of pointers. 47
Try it Out - 2 Problem Statement: Write a program using pointers to break the inputted sentence in to words and print each word in separate line 48
Try it Out - 2 (Contd.) Code: #include <stdio.h> main() { char str[80]; char token[10]; char *p, *q; printf("enter a sentence: "); gets(str); p = str; while (*p) { q = token; while (*p!= ' ' && *p) { *q = *p; q++ ; p++; } Refer File Name : <ses15_2.c> for soft copy of the code 49
Try it Out - 2 (Contd.) Code: if (*p) p++; *q = '\0'; printf("%s\n", token); } getchar(); } Refer File Name : <ses15_2.c> for soft copy of the code 50
Try it Out - 2 (Contd.) How it Works: The program gets the sentence as input from the user str array. The str array is assigned to pointer p. The token array is assigned to q. Until the character space is encountered in the string pointed to by p, the value at p is copied to q. When space is encountered, the string pointed by q is null terminated and print on the screen. Again pointer q is re-initialized to point to token array. The loop continues till next space is encountered. The above 4 step continues until the full sentence is parsed. Finally exit the program 51
Test Your Understanding 1. If a C library does not contain rewind function, how can it be implemented? 2. Write a program to create a telephone directory file and perform the following search Operations: a) Search for the name, given the number. b) Search for the number, given the name and address. 52
Test Your Understanding (Contd.) 3. What will be the output when the following code is executed? char *p = xyz ; *p= A ; printf ( %s %s,p,p+1); 4. What will be the output when the following code is executed? main() { int a[5],*p; for (p=a; p<&a[5];p++) { *p=p-a; printf ( %d,*p); } } 53
Problem Solving and 'C' Programming Session 15: Summary Direct access of a file is supported by fseek(), ftell(), and rewind() functions Preproccessing is done before compilation and preprocessor directives are identified by # symbol Preprocessor directives performs: macro substitution, file inclusion, and conditional compilation 54
Problem Solving and 'C' Programming Session 15: Summary (Contd.) Pointer is a variable which can hold the address of another variable. & operator is used to refer the address of a variable and * operator is used for dereferencing the pointer. Pointer can point to an array of any dimensions. There are two ways to represent multi dimensional arrays by means of pointers:» Single pointer points to set of arrays» Array of pointers Strings can easily be represented using pointer ragged arrays. 55
Problem Solving and 'C' Programming Session 15: Source C Reference Card (ANSI) C Reference Manual by Dennis Ritchie Programming in C: A Tutorial by Brian W. Kernighan, Bell Laboratories Byron Gottfried, Programming in C, Tata McGraw Hill Deitel & Deitel, C How to Program, Third Edition, Prentice Hall Disclaimer: Parts of the content of this course is based on the materials available from the Web sites and books listed above. The materials that can be accessed from linked sites are not maintained by Cognizant Academy and we are not responsible for the contents thereof. All trademarks, service marks, and trade names in this course are the marks of the respective owner(s). 56
You have completed the Session 15 of Problem Solving and 'C' Programming 2007, Cognizant Technology Solutions. All Rights Reserved. The information contained herein is subject to change without notice.