0% found this document useful (0 votes)
9 views

ITP Week 8

This document provides a comprehensive overview of pointers in C, covering their declaration, initialization, and usage, including pointer arithmetic and the relationship between arrays and pointers. Key concepts include the dereference operator, L-value and R-value distinctions, and the implications of passing variables by value versus by reference. The document also highlights the importance of understanding pointers for efficient memory management and programming practices.

Uploaded by

Hashem Abdullah
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views

ITP Week 8

This document provides a comprehensive overview of pointers in C, covering their declaration, initialization, and usage, including pointer arithmetic and the relationship between arrays and pointers. Key concepts include the dereference operator, L-value and R-value distinctions, and the implications of passing variables by value versus by reference. The document also highlights the importance of understanding pointers for efficient memory management and programming practices.

Uploaded by

Hashem Abdullah
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 11

Summary: Understanding Pointers in C

A pointer in C is a variable that holds an address, rather than a simple value. To


declare a pointer, use int *ptr, where * denotes the type of data being pointed
to (int). A pointer can be initialized with the address of another variable using
the unary operator &.
Key Takeaways:
1. Memory Allocation: Variables have a specific memory location allo-
cated for them.
2. Pointer Declaration: Declare a pointer variable by specifying its type
and allocating memory using int *ptr.
3. Initializing a Pointer: Initialize a pointer with the address of another
variable using &, e.g., ptr = &a;.
4. Dereference Operator (*): The dereference operator retrieves the value
stored at the address contained in a pointer, e.g., *ptr.
5. Advantages of Pointers: Use pointers to access and modify variables
indirectly, avoiding explicit variable names.
6. Pointer Variables: Allocate memory for each pointer variable (typically
8 bytes per compiler).
Example Walkthrough:
1. Declare an integer variable a with value 5.
2. Print the address of a using %p, which outputs a hexadecimal address
(1000).
3. Declare and initialize a pointer ptr to point to a: int *ptr = &a;.
4. Use the dereference operator (*) to retrieve the value stored at the address
pointed to by ptr: *ptr == 5.
5. Modify the value of a from 5 to 6.
6. Use the pointer ptr again, and observe that it now points to the new value
(6).
Conclusion:
Understanding pointers in C is essential for efficient memory management and
indirect variable access. This summary provides a concise overview of key con-
cepts, including pointer declaration, initialization, dereference operators, and
advantages of using pointers.
Summary: Understanding Pointers in C
This video provides an explanation of how pointers work in C programming
language, focusing on the concepts of L-value (left-hand side) and R-value (right-
hand side).
Key Takeaways:
1. Pointer Declaration: Declare a pointer variable using int *ptr or
float *pv, where * denotes the type of data being pointed to (int or

1
float).
2. Initializing a Pointer: Initialize a pointer with the address of another
variable using the unary operator &, e.g., ptr = &a;.
3. Dereference Operator (*): The dereference operator retrieves the value
stored at the address contained in a pointer, e.g., *ptr or *pv.
4. L-value and R-value:
• L-value (left-hand side) refers to a memory location that can be mod-
ified.
• R-value (right-hand side) is a temporary value that will be consumed
immediately.
5. Pointer Usage: Pointers can be used as both L-values and R-values
depending on their position in the assignment statement.
Example 1:
• Declare int a = 5;
• Initialize int *ptr = &a;
• Increment (*ptr)++; (use dereference operator to modify value at mem-
ory location pointed by ptr)
– Value of a changes from 5 to 6
– R-value (*ptr) is used on the right-hand side, while L-value (a) is
modified
Example 2:
• Declare float v = 3.14;
• Initialize float *pv = &v;
• Assign new value using dereference operator: (*pv) = 3.14 (use R-value
on left-hand side, modify L-value at memory location pointed by pv)
– Value of v changes from 3.14 to 6.28
– Print value using pointer: printf("%f", *pv);
Conclusion:
This video demonstrates the use of pointers in C programming language and
highlights the concepts of L-values (left-hand side) and R-values (right-hand
side). The examples illustrate how pointers can be used to access memory
locations, modify values, and print results.
Pointer Arithmetic: A Comprehensive Summary

Introduction
In this summary, we will explore the concept of pointer arithmetic and under-
stand how adding an integer value to a pointer variable affects its address.

Understanding Pointers and Addresses


• When declaring a variable like int a = 5, 4 bytes are allocated for it in
memory.

2
• The address of a is stored as a hexadecimal value (e.g., 1000, 1001, etc.).
• A pointer variable, such as int *p = &a;, stores the address of another
variable.

Pointer Arithmetic: Adding 1 to a Pointer


• When you add 1 to a pointer like p + 1, it doesn’t simply increment the
address by 1.
• Instead, it adds the size of the data type that p is pointing to (e.g.,
sizeof(int) = 4 bytes) multiplied by 1.

Example: Adding 4 to a Pointer


• When adding 4 to a pointer like q = p + 4, it’s equivalent to multiplying
the address by (sizeof(int)) * 4 or just 16.
• This means that instead of incrementing the address by 4, you’re effectively
moving 16 bytes forward.

Key Takeaways
1. Pointer arithmetic is a way to manipulate pointers based on their data
type.
2. When adding an integer value to a pointer variable, it’s multiplied by the
size of its pointed-to data type (sizeof(int) for int* pointers).
3. This means that the increment is not just linear but dependent on the size
of the data being accessed.
By grasping this fundamental concept, you’ll be better equipped to handle more
complex pointer operations and ensure your code works as intended!
Pointer Arithmetic Review

Key Takeaways
• Besides adding an integer offset to a pointer variable, limited operations
can be done:
– Subtraction of two pointer variables if they point to the same data
type.
– Combination of increment and pre-increment/post-increment opera-
tors with dereference operator (*).
• Example 1: p - q (or q - p)
– If p points to an array element, and q points to another array element
of the same data type, subtracting them results in a value equal to
the difference between their addresses.
– Example: if p is pointing to the 3rd element (1000), and q is pointing
to the 7th element (1012), then p - q = -12.
• *Example 2: ++p

3
– If p points to an array, incrementing it (++) first and then derefer-
encing (*) results in the value at the new position.
– Example: if p is pointing to an element with value 10 (1000), then
after doing * ++ p, the pointer will point to a different location (1012)
containing a higher value, which would be 20.
• Example 3: ++ * p
– If p points to an array, dereferencing (*) and then incrementing (++)
results in the old value before incrementing.
– Example: if p is pointing to an element with value 10 (1000), then af-
ter doing ++ * p, the pointer remains at the same location containing
a higher value, which would be 11.

Summary
In this review, we have explored various examples of pointer arithmetic
operations. We discussed limited operations that can be performed besides
adding integer offsets to pointers, including subtraction and combination of
increment/post-increment operators with dereference operator (*). The specific
cases examined include p - q (or q - p), *++p, ++ * p, and the effect of
parentheses on these expressions.
Summary: Arrays and Pointers
Key Concepts:
• Array Allocation: An integer array arr[3] = {1, 2, 3} allocates a
total of 12 bytes in memory.
• Memory Layout: The first four bytes store the value of arr[0], followed
by four bytes for arr[1] and then another four bytes for arr[2].
• Array Name as Address Pointer: The name of an array (arr) denotes
the address of its zeroth index, which is equivalent to &arr[0].
• Pointer Arithmetic: Adding an integer offset to an array pointer ac-
cesses other elements in the array. For example, arr + 1 points to arr[1],
and arr + i points to arr[i].
Important Takeaways:
• When using an array name as a pointer, you cannot change its address.
• To access different elements of an array using pointers, use pointer arith-
metic (e.g., p = arr + 1; q = arr + 2;)
• The dereference operator (*) can be used to access the value stored at a
specific memory location. For example, *arr is equivalent to arr[0].
Connection between Arrays and Pointers:
Arrays are implemented in C using pointers. An array name serves as an address
pointer to its zeroth index, which allows for accessing other elements through
pointer arithmetic. Understanding this connection enables efficient use of arrays
and memory management in programming.

4
Summary:

Arrays and Pointers Connection


• The name of an array indicates the address of its first element.
• A pointer can be assigned the name of an array, allowing access to all
elements using pointer arithmetic.

Array of Pointers Example


• An array of pointers is declared by specifying a type for each element (e.g.,
int * arr[5]).
• Each element in the array can point to a different integer location in
memory.
• By using an index, you can access and modify individual elements pointed
to by the array.
Key Takeaways:
1. The name of an array serves as a pointer to its first element.
2. Assigning this address to a pointer enables iteration over all elements.
3. Array of pointers allows multiple integers locations in memory to be ref-
erenced using separate indices.
Example Code:
int iA[3] = {5, 10, 15}; // Address: 1000-1008
int * ptr[3];
ptr[0] = &iA[0]; // Containing address and value of first element (1000)
ptr[1] = &iB[0]; // iB declared similarly with different values
ptr[2] = &iC[0]; // Access elements individually using pointer arithmetic

printf("Address: %p Value: %d\n", ptr[i], *(int*)ptr[i]);


Note that the example code demonstrates how to assign addresses of individual
arrays (iA, iB, and iC) to separate pointers within an array of pointers, allowing
for efficient access and manipulation of these elements.
Summary:

Pointers and Structures


• A pointer to a structure can be declared using struct student * ptr;
• To access individual members of a structure through a pointer, use the
arrow operator (->) or dereference the pointer with (*ptr).member

5
Precedence Rules
• The dot operator has higher precedence than the star (dereference) oper-
ator
• To evaluate expressions correctly, put parentheses around * and . to force
correct order of operations
Examples:
1. (*ptr).roll is equivalent to (ptr)->roll
2. In the expression p->x++, the arrow (->) has higher precedence than the
increment operator (++)
3. Similarly, in the expression *(p[n])++, the square bracket ([]) has highest
precedence followed by dereference and then increment operators
Key Takeaways:
• Pay attention to operator precedence when working with structures and
pointers
• Use parentheses to ensure correct evaluation of expressions
Summary:

Pointers and Structures


• Declaring a Pointer Variable: To declare a pointer variable to an
integer type, use type *ptr; for example, int *iptr;. For a structure
type, use the same syntax as declaring a regular variable, followed by *,
e.g., Student *p1;.
• Accessing Individual Members:
– Using the dot operator: s1.roll (where s1 is a structure variable).
– Using the arrow operator with a pointer variable: (*p1).roll or
equivalently, using parentheses and dereferencing first: (p1->roll).

Example Code
#include <stdio.h>

typedef struct {
int roll;
char department[10];
float cgpa;
} Student;

int main() {
Student s1 = {100, "CS", 9.5};

printf("Roll number: %d\nDepartment: %s\nCGPA: %.2f\n",

6
(*p1).roll, p1->department, *p1.cgpa);

// ...

return 0;
}

Array of Structures and Pointer Arithmetic


• Declaring an Array of Structures: Use the same syntax as declaring
a regular array, e.g., Student list[3];.
• Accessing Individual Members in an Array:
– Using pointer arithmetic: list[i] or equivalently (p1 + i) (where
i is the index).
– Using parentheses and dereferencing first with a pointer variable: (*
(p1 + i)).member.

Example Code
#include <stdio.h>

// ...

int main() {
Student list[3] = {{100, "CS", 9.5}, {200, "EE", 8.0}, {300, "Math", 7.5}};

p1 = list;

// ...
}
Summary:

Call By Value vs Call By Reference


Call By Value:
• When passing data to a function using call by value, a copy of the variable
is made.
• The original variable remains unchanged in the calling function.
• Changes made inside the function only affect the local copy of the variable.
• Example:
– f1(int a) takes an integer a as input and changes its value to 61.
– In the main function, printing a still shows its original value (5) be-
cause no change was made to the original variable.
Call By Reference:

7
• When passing data to a function using call by reference, only the memory
address of the variable is passed.
• A copy of this memory address (key) is made and stored in the function’s
local variables.
• Changes made inside the function affect the original variable in the calling
function because it uses the same memory location.
• Example:
– f2(int *x) takes a pointer to an integer x as input and changes its
value to 61.
– In the main function, printing a shows its new value (61) because the
original variable was modified through call by reference.
Key Differences:
• Call By Value creates a local copy of the variable, while Call By Reference
passes only the memory address.
• Changes made in a Call By Value function do not affect the original vari-
able, whereas changes made in a Call By Reference function reflect in the
calling function.
Summary:
Call By Reference Example with Arrays
• The video demonstrates how an array can be passed by reference to a
function, using C programming language.
• In the example code, int arr[4] = {1, 4, 3, 7} is declared and passed
to the compute_square() function along with its size (4) as arguments.
• Inside the compute_square() function, an array pointer variable a is cre-
ated and assigned the value of arr.
• Using pointer arithmetic (a[i] = a[i]*a[i];), each element in the orig-
inal array is multiplied by itself and updated.
Key Takeaways:
1. Arrays are passed by reference: When passing an array to a function,
only its base address is copied into the receiving variable.
2. Changes made inside the function affect the original array: Since
arrays are passed by reference, any changes made to the elements of the
array within the called function will be reflected in the calling function’s
original array.
3. Arrays can return multiple values: Because arrays are passed by
reference and modified within a function, they can effectively ”return”
multiple values.
Note:
• The video also highlights how pointer arithmetic works with arrays and
demonstrates how it is used to modify each element of the array.

8
• The example code returns no explicit value from the compute_square()
function but modifies the original array passed as an argument.
Summary:
Passing Structures by Value and Reference in C
• A typedef struct called Rect with members l, w, is created.
• In the main function, two variables r1 and r2 of type Rect are initialized
with values 10/8 and 5/3 respectively.
• A function foo is defined to take a structure variable as an argument by
value (Rect r1) and another as a pointer (Rect *r2).
• Inside the foo function, both r1.l, r1.w, r2->l, and r2->w are modified.
• The key concept here is that structures in C are passed by default by value,
not reference.
Key Takeaways:
1. Structures are passed by value by default: When passing a structure
variable to a function, it is copied into the receiving variable, just like
integers and other primitive types.
2. Arrays are passed by reference: Arrays in C behave differently; their
names represent the address of the zeroth element, making them pass-by-
reference-like behavior.
3. Passing structures by reference can be achieved using pointers:
By passing a pointer to a structure variable as an argument, changes made
within the function will affect the original structure.
Note:
• The video explains that even though structures are passed by value by
default, they can still be passed and modified like references if a pointer
is used.
• The example code demonstrates how modifying a structure variable’s mem-
bers through its pointer affects the original data.
Summary:
Understanding Null Pointers in C
• A null pointer is created when an integer pointer (int *) is initialized to
0 or NULL.
• Initializing a pointer with NULL (or equivalently, 0) means it points to no
valid object in memory.
• Uninitialized pointers may have random values and can accidentally point
to valid locations.
Key Takeaways:
1. Null Pointers Indicate Error Conditions: Null pointers are used to
indicate that an operation or function has failed.

9
2. Returning a Pointer from a Function: Functions returning pointers
can use null pointers as error indicators, allowing the caller to check if the
returned pointer is valid.
3. Dereferencing NULL Pointers Results in Runtime Errors: At-
tempting to dereference (access) a null pointer leads to runtime errors
and program termination.
Necessity of Null Pointers:
• To indicate failure or error conditions when returning pointers from func-
tions
• To check if an operation has succeeded or failed
• To prevent attempting to access invalid memory locations
Conclusion:
Null pointers play a crucial role in C programming, providing a mechanism for
indicating errors and preventing runtime errors due to dereferencing null values.
Summary:
Key Concepts Covered:
1. Pointer Variables: Store memory addresses, not simple values.
2. Address Operator (&): Retrieves the memory address of a variable.
3. Dereference Operator (*): Accesses the value stored at a specific mem-
ory address.
4. Pointer Arithmetic: Adding an offset to a pointer changes its value by
the size of the data type it points to.
5. Array-Pointer Connection: Array names denote the starting memory
address, allowing for access using pointers and pointer arithmetic.
6. Structure Pointers: Declare structure variables as pointers to access
individual members using the arrow operator.
7. Call-by-Value vs Call-by-Reference:
• Call-by-value: Pass simple data types or structures by value (copy-
ing).
• Call-by-reference: Pass addresses of variables, making changes re-
flected in both functions.
Important Points:
1. Pointer arithmetic involves adding offsets based on the size of the data
type.
2. Subtraction is allowed between pointers pointing to the same data type.
3. NULL pointers indicate error conditions or invalid memory locations.
4. Call-by-reference requires passing addresses of variables, making changes
reflected in both functions.
Key Takeaways:

10
1. Understand how pointer variables store memory addresses and use opera-
tors like & and *.
2. Recognize the connection between arrays and pointers through pointer
arithmetic.
3. Differentiate call-by-value from call-by-reference when passing data types
or structures to functions.
4. Learn about NULL pointers as indicators of error conditions in C pro-
gramming.

11

You might also like