Pointers in C
Dr. MD Asrar Ahmed
Pointers – Basic Concept
• Every computer has addressable memory locations.
• So far we used only variables to name these memory locations.
• Using variables/identifiers we access data stored in memory.
• Pointers are also used to access the data stored in memory.
• A pointer is a constant or variable that contains an address that can be used to
access the data.
• Consider a character constant such as: ‘a’, ‘A’, ‘Z’, ‘\n’, etc. Let achar be a
variable of type char and stores any of these characters:
• The variable name is created by user.
• The address however, is relative to system memory.
• Each time, program is run, the address will vary.
• Therefore these addresses are called as Pointer Constants.
Pointers – Basic Concept
• Can we save these pointer constants? (the addresses).
• The address operator “&” extracts the address for a variable.
• The address operator format is: &var_name.
• Lets write a program that defines two character variables and prints their
addresses using conversion specification: %p.
• Since a character takes one byte in memory, the addresses may be two
adjacent memory locations like: 12004, and 12005.
• However for integers, which take 4 bytes, then address of first byte is
returned when we use &int_variable.
Pointers – Pointer Variables
• If we have a pointer constant, pointer value, then we can also have a
pointer variable.
• A pointer variable is a variable which can store address of another
variable.
• We can store a variable’s address
in two or more pointer variables.
• A pointer that points to no variable contains
a special null-pointer constant, NULL.
Pointers – Accessing Variables Through Pointers
• When we have a variable and a pointer to that variable, next is how
to use this pointer.
• To use a pointer to access the data stored in a variable, we use
“Indirection” operator * (asterisk).
• This operator is also known as “dereferencing” operator.
• When we dereference a pointer, we actually use its value (address
stored therein), to access another variable.
• The indirection operator is a unary operator. Its operand must be a
pointer.
• To access a variable through its pointer 𝑝𝑡𝑟, we write: ∗ 𝑝𝑡𝑟.
Pointers – Accessing variables through pointers
• Let 𝒊𝒏𝒕 𝒂 = 𝟏𝟎; and 𝒊𝒏𝒕 ∗ 𝒑𝒕𝒓 = &𝒂; be two statements.
• Suppose, we want to add 1 to value of a.
• This can be done in any of the following ways:
• 𝑎 + +; 𝑜𝑟 𝑎 = 𝑎 + 1; 𝑜𝑟 ∗ 𝑝 + +; 𝑜𝑟 ∗ 𝑝 =∗ 𝑝 + 1;
• Let 𝑎 be a variable being pointed by two pointers: 𝑝 and 𝑞.
• Then expressions: a, *p, *q are all equivalent. If these are used on
right hand side, then they only access the value stored in variable.
• But if they are used on left hand side of an assignment operator, the
expression changes the value of x.
Pointers – Accessing variables through pointers
• The indirection and address operators are inverse of each other.
• When the two operators are combined like ∗ &𝑥, they cancel each other, and
what we get is variable x.
Pointer Declaration and Definition
• The pointers are declared as follows:
•
Printing data with pointers
• Program to print pointer contents (address of variables), values
stored in variables.
int main() {
Int a=10;
Int *ptr;
Ptr=&a;
Printf(“%d, %p\n”, a, &a);
printf(“%p, %d, %d\n”, p, *p, a);
}
Initializing Pointers
• C language does not initialize variables, hence all uninitialized
variables have unknown values upon creation.
• The same is true for pointers.
• An uninitialized pointer has unknown value in it, hence using it we
may not be able to access any meaningful location in memory.
• To rectify the problem pointed in figure:
int a;
int *p=&a;
*p=20;
Add two numbers using pointers
int main() {
Int a,b,sum;
Int *pa=&a, *pb=&b, *ps=∑
printf(“Enter first number\n”);
scanf(“%d”, &a);
printf(“Enter second number\n”);
scanf(“%d”, pb);
*ps=*pa+*pb;
printf(“Sum of % and %d is %d”, *pa, *pb, *ps);
}
Pointer Flexibility – A pointer can point to multiple variables
int main() {
Int a,b,c, *p,*q, *r;
printf(“\n Enter three values..\n”);
scanf(“%d %d %d”,&a, &b, &c);
p=&a;
printf(“\n a = %d”, *p);
p=&b;
printf(“\n b = %d”, *p);
p=&c;
printf(“\n c = %d”, *p);
*p=a, *q=a, *r=a; //a variable being pointed by multiple pointers
printf(“a=%d”, *q);
printf(“a=%d”, *r);
}
Pointers for Inter-function Communication
• In a swap function, if we pass two data items
by value, even though the values in formal
parameters change but it does not reflect on
actual parameters.
• To reflect swap operation, we need to pass
data items by address.
• To pass actual parameters, we use: swap(&a,
&b), and for formal parameters in function
definition we use: swap(int *p, int *q){ }
•
Functions Returning Pointers
• A function can return a pointer to a variable as a result.
Functions Returning Pointers
• When a pointer is returned by a function, the pointer must point to a
variable in calling function or some other higher level function.
• It is an error if the pointer being returned points to a local variable in
called function, as the variable gets deleted when the called function
terminates.
Pointers to Pointers
• So far we saw pointers pointing to a data/variable directly.
• It is possible for a pointer to point to another pointer.
• We can have a pointer pointing to pointer to an integer.
• There is no limit to how many levels of indirection we want, but we
seldom use more than two levels.
• To access variable a using q, we need to use
two levels of dereferencing, **q.
• If we use *q, it refers to p, which is a pointer
to integer a.
Pointers to Pointers
• Following code demonstrates reading data using multiple levels of
dereferencing using scanf.
int a, *p, **q, ***r;
p=&a, q=&p, r=&q;
scanf(“%d”, &a); or
sacnf(“%d”, p);
scanf(“%d”, *q);
scanf(“%d”, **r);
Compatibility
• The size of all pointers is same. Every pointer variable hold address
of memory location in a computer.
• But size of variable being pointed may be of different size in bytes.
Dereference Type Compatibility
• The dereference type is the type of variable that the pointer is
referencing.
• It is invalid to assign a pointer of one type to a pointer of another
type, even though values in both pointers are memory addresses.
• In C we cannot use assignment operator with pointers to different
types, if we do so, it is a compile time error.
• A pointer to a char is only compatible with a pointer to a char, and a
pointer to an int is only compatible with pointer to an integer.
• We cannot assign a pointer to a char to pointer to an int.
Dereference Type Compatibility
Lvalue and Rvalue
• In C, an expression is either an lvalue or rvalue.
• Every expression has a value, but value in expression can be used in
two different ways.
– An lvalue expression is used whenever the object is receiving a value; it is being
modified.
– An rvalue expression is used to supply a value for future use; to copy its value.