Chapter 4 Pointers In this Chapter you will learn: Basic Idea of Pointers The Pointer Operators o The address operator & o At address * Changing Variables by using Pointers Passing Variables Between Function o o Using return statement Using pointers (call by reference) Example: to demonstrate the call by value and call by reference Storage Class Specifiers o o o o o Constants Automatic variables Static Variables External Variables Register Variables مساعد احلسني.د )1( برمجة: عال1101 Ch4-2 4-1 Basic Idea of Pointers Computer memory (RAM) is usually organized in group of bytes called words. Each location in memory has an address (see Fig. 4-1). Hexadecimal Address RAM 0000 1 byte 0001 0002 0003 0004 0005 FFFE FFFF Figure 4-1: Memory Organization Each variable has three important parts: 1. Name 2. Address 3. Value For Example: Consider the declaration: int i=27; As you know, integer requires four bytes in a 32_bit system. The variable i might be assigned to location (0001)16 to (0004)16 , See Fig. 4-2. In this case, Variable i has: Name : i Address: (0001)16 Value : 27 مساعد احلسني.د )1( برمجة: عال1101 Ch4-3 RAM 0000 0001 0002 0003 0004 0005 27 for variable i: name: i address:(0001) 16 value: (27) 10=(0000001B) 16 FFFE FFFF Figure 4-2: Assignment of variable i to locations 0001 to 0004 A pointer is a variables that holds a memory location. The general form of declaring a pointer is: type *pointer_name; For example: int *p; declaring p as pointer to integer. When a pointer p contains the address of a variable i, we say: pointer p pointes to i. مساعد احلسني.د )1( برمجة: عال1101 Ch4-4 4-2 The Pointer Operators o The address operator & o At address operator * The address operator & The address operator & is a unary operator that returns the memory address of its operand. Program 4-1 and Fig. 4-3 demonstrate the & operator. Program 4-1 #include<stdio.h> void main(void) { int x; x=25; printf("For variable x:\n address: %u\n value : %d\n", &x, x); } Output of Program 4-1: For variable x: address: 6553080 value : 25 RAM 0 6553080 25 6553084 ??? x Figure 4-3: The address operator &. Where &x=6553080 مساعد احلسني.د )1( برمجة: عال1101 Ch4-5 If a variable is going to hold an address, it must be declared as a pointer. See Program 4-2 and Fig. 4-4. Program 4-2 #include<stdio.h> void main(void) { int x; int *p; x=25; printf("For variable x:\n address: %u\n value p=&x; printf("For the pointer variable : %d\n\n", &x, x); p:\n address: %u\n value } Output of Program 4-2: For variable x: address: 6553076 value : 25 For the pointer variable address: 6553080 value : 6553076 p: RAM 0 6553076 25 x 6553080 6553076 p Figure 4-4: Pointer p points to x : %d\n", &p, p); مساعد احلسني.د )1( برمجة: عال1101 Ch4-6 Figure 4-4 could be simplified (represented) by Figure 4-5. pointer p variable x 25 Figure 4-5: another representation At address operator * The operator * returns the value located at address that follows the * operator. In program 4-3, p points to x. thus *p returns the value of x. Note: *p returns the value located at address p, but p contains the address of x. Thus *p returns the value of x. Program 4-3 #include<stdio.h> void main(void) { int x; int *p; x=25; printf("For variable x:\n address: %u\n value p=&x; printf("For the pointer variable p:\n address: %u\n value printf("The value of *p = %d\n", *p); } Output of Program 4-3: For variable x: address: 6553076 value : 25 For the pointer variable address: 6553080 value : 6553076 The value of *p = 25 p: : %d\n\n", &x, x); : %d\n\n", &p, p); مساعد احلسني.د )1( برمجة: عال1101 int x; int *p; x=25; p=&x; Ch4-7 p x p x 25 p x 25 When p points to x, i.e. p contains the address of x, then: x=25 *p=25 Figure 4-6: Graphical representation of Program 4-3 4-3 Changing Variables by using Pointers You can easily change a variable by using a pointer, see program 4-4 and Figure 4-7. Program 4-4 #include<stdio.h> void main(void) { int x; int *p; x=25; printf("For variable x:\n address: %u\n value p=&x; printf("For the pointer variable *p=30; printf("But now, x= %d\n", x); } : %d\n\n", &x, x); p:\n address: %u\n value : %d\n\n", &p, p); مساعد احلسني.د )1( برمجة: عال1101 Ch4-8 Output of Program 4-4: For variable x: address: 6553076 value : 25 For the pointer variable address: 6553080 value : 6553076 p: But now, x= 30 int x; int *p; x=25; p=&p *p=30; p x 25 p x 30 30 Figure 4-7: Changing the value of variable x using pointer p )1( برمجة: عال1101 مساعد احلسني.د Ch4-9 4-4 Passing Variables Between Function o o Using return statement Using pointers (call by reference) As discussed in Chapter_3, we can use the return statement to return a value back to the calling function. See program 4-5. Program 4-5 #include<stdio.h> int func1(void); void main(void) { int x; x=25; printf("Value of x= %d\n", x); x=func1(); printf("But now, x= %d\n", x); } int func1(void) { return(100); } Output of Program 4-5: Value of x= 25 But now, x= 100 But, you can not use the return statement to return two or more values back to the calling function. Use pointers to return two or more values back to the calling function. Look closely at program 4-6. Notice that we passed the address of x to func1 in the calling statement: func1(&x); This type of call is known as call by reference. )1( برمجة: عال1101 مساعد احلسني.د Ch4-10 Program 4-6 #include<stdio.h> void func1(int *ptr); void main(void) { int x; x=25; printf("Value of x= %d\n", x); func1(&x); printf("But now, x= %d\n", x); } void func1(int *ptr) { *ptr=100; } Output of Program 4-6: Value of x= 25 But now, x= 100 Program 4-7 and Program 4-8 clarify the difference between call by value and call by reference. Look closely to each program. Program 4-7: Call by value Program 4-7 #include<stdio.h> void func1(int x); void main(void) { int x; x=25; printf("In main function: x= %d\n", x); func1(x); printf("Still, in main function: x= %d\n", x); } void func1(int x) { printf("In func1: x= %d\n", x); x=2*x; printf("In func1: x= %d\n", x); } )1( برمجة: عال1101 مساعد احلسني.د Output of Program 4-7: In main function: x= 25 In func1: x= 25 In func1: x= 50 Still, in main function: x= 25 Program 4-8: Call by reference Program 4-8 #include<stdio.h> void func1(int *ptr); void main(void) { int x; x=25; printf("In main function: x= %d\n", x); func1(&x); printf("In main function: x= %d\n", x); } void func1(int *ptr) { printf("In func1: *ptr= %d\n", *ptr); *ptr=2*(*ptr); printf("In func1: *ptr= %d\n", *ptr); } Output of Program 4-8: In In In In main function: x= 25 func1: *ptr= 25 func1: *ptr= 50 main function: x= 50 Ch4-11 )1( برمجة: عال1101 مساعد احلسني.د Ch4-12 Example: Also, Program 4-9 demonstrates the call by value and call by reference. Program 4-9 #include <stdio.h> void explain_program(void); void get_inputs(float *l, float *w); float calculate_area(float length, float width); void print_area(float area); void main() { float length; float width; float area; explain_program(); get_inputs(&length, &width); area = calculate_area(length,width); print_area(area); } /*-----------------------------------------------------------------------*/ void explain_program() { printf("This program calculates the area of a rectangle.\n"); printf("You need to enter the length and the width of the rectangle.\n"); } /*-----------------------------------------------------------------------*/ void get_inputs(float *l, float *w) { float length; float width; printf("\n Input the length ==> "); scanf("%f",&length); printf(" Input the width ==> "); scanf("%f",&width); *l = length; *w = width; } /*-----------------------------------------------------------------------*/ float calculate_area(float length, float width) { float area; area = length * width; return(area); } /*-----------------------------------------------------------------------*/ void print_area(float area) { printf("\nThe area of the rectangle is %.2f\n",area); } )1( برمجة: عال1101 مساعد احلسني.د Ch4-13 Output of Program 4-9: This program calculates the area of a rectangle. You need to enter the length and the width of the rectangle. Input the length ==> 7 Input the width ==> 5 The area of the rectangle is 35.00 )1( برمجة: عال1101 مساعد احلسني.د Ch4-14 4-5 Storage Class Specifiers 1. 2. 3. 4. 5. Constants Automatic variables Static Variables External Variables Register Variables 1. Constants: Constants can not be changed by the program. C language allows you to declare such constant by preceding the variable declaration with the keyword const. Example: The following statement const int x=7; declares x of type integer with an initial value of 7. Since the declaration is preceded with const, you program can not modify its value, i.e. its initial value 7. But, your program can use the variable x in other expression. In other word, you can read the value of the constant variable but you can not change it. Program 4-10 #include<stdio.h> const int max=10; void main(void) { int i; for (i=0; i<max; i++) printf("%d ", i); printf("\n"); } Output of Program 4-10: 0 1 2 3 4 5 6 7 8 9 )1( برمجة: عال1101 مساعد احلسني.د Ch4-15 2. Automatic variables: Local variables are automatic variables. This means that local variables are created and destroyed with each entry and exit from the block of the function. Thus local variables can not retain their values between calls. 3. Static Variables: A static local variable is a local variable, but its lifetime lasts as long as the program is running. By default, a static variable is initialized to zero only at the start of the program. See Program 4-11. Program 4-11 #include<stdio.h> void func1(void); void main(void) { int i; for(i=5; i<10; i++) func1(); } void func1(void) { static int x; printf("x=%d\n", x); x=x+1; } Output of Program 4-11: x=0 x=1 x=2 x=3 x=4 )1( برمجة: عال1101 مساعد احلسني.د Ch4-16 You can initialize a static local variable to any value. This value is assigned only once at the start of the program – not each time the block of code is executed. See Program 4-12. Program 4-12 #include<stdio.h> void func1(void); void main(void) { int i; for(i=0; i<5; i++) func1(); } void func1(void) { static int x=7; printf("x=%d\n", x); x=x+1; } Output of Program 4-12: x=7 x=8 x=9 x=10 x=11 4. External Variables C language allows you to divide a large program into separate files, each one can be separately compiled, then all files are linked together. In this case, it is better to declare all global variables in one file and use the keyword extern to inform all the files in your program about the global variable. For example, Program 4-13 consists of two file: file1.c and file2.c . In file1.c the global variables x and y are declared. However, in file2.c the extern tells the compiler that x and y are declared elsewhere, so the compiler will not create a storage for them again. )1( برمجة: عال1101 مساعد احلسني.د Ch4-17 Program 4-13: file1.c file2.c #include<stdio.h> extern int x, y; int x, y; void func1(void); void func1(void) { x=10; y=20; } void main(void) { func1(); printf("x=%d y=%d\n", x, y); } Output of Program 4-13: x=10 y=20 5. Register Variables To place a variable in a register of the CPU rather than in the RAM, use the keyword register, as shown in Program 4-14. The operations on the register are done much faster than that on memory. You can use the register variables for local and formal parameters only. Program 4-14 #include<stdio.h> void main(void) { register int i; for(i=1; i<=256; i=2*i) printf("%d ", i); printf("\n"); } Output of Program 4-14: 1 2 4 8 16 32 64 128 256