Reason: restructure the article
Creation Using pointers Using pointers to objects Special null pointer Pointers and const Pitfalls Accessing uninitialized pointers Different lifetime of memory and pointer |
A pointer is declared just like a variable but with * after the type:
This is a pointer, which can point to an integer. The pointer is not yet initialized, therefore it points to an undefined location and any access to it is undefined behaviour.
What the statement did behind the scenes is to reserve a memory area large enough to hold a memory address on the given system.
Notice that so far we didn't reserve any memory to hold the integer object that the pointer will point.
Assignment and access of pointers:
The code above takes the address of a ( & operator) and assigns it to the pointer px . Afterwards we retrieve the value, by so called dereferencing of the pointer, using the * operator and assign it to b .
In the example you see that px points to the memory of variable a and therefore will see any changes made to a . b however has a copy of the value of a and therefore doesn't change.
Pointer can be assigned to other pointers of the same type just like variables. In this case the address inside the pointer is copied and both pointer point to the same location after the assignment.
If pointers refer to objects which are not plain old data types, there is an easier syntax to access the members of the object.
Accessing members of objects could be done by dereferencing the pointer and accessing the function or variable of the object using the . operator. Or simply do both in a nicer syntax using the -> operator.
Sometimes it is desirable to mark a pointer as invalid. This can be achieved by the assignment of nullptr to the pointer. This pointer is called a null pointer and dereferencing it results in undefined behavior.
A special feature of a null pointer is that it is the only possible pointer value that evaluates to false when converted to bool .
Before the C++11 standard, the standard way to refer to null pointers was by using NULL macro constant. Unfortunately, this method has a serious issue of being type-unsafe as NULL evaluates to an integer, not a pointer.
Consider the following example:
It is obvious that the intent of the programmer was to call the first overload of the foo function in both cases. However, as NULL is an integral constant, the second overload is called, which is unexpected behavior and may lead to a bug.
Since pointers access memory of a certain type, like variables, and are variables themselves they have two const parameters.
If the pointer is const, we can't assign a different address to it. The pointer will always point to the same part of memory.
If the value is constant, we are able to assign a different address to the pointer, but we can't change the value it points to.
Pointers should always be initialized with a valid address or nullptr . But this doesn't prevent access to null pointers causing an exception or undesired behaviour.
Therefore pointers should be compared against nullptr before access, unless it is guaranteed that the pointer is valid.
SubFunc creates a variable and returns the pointer to the variable. When SubFunc returns, the variable x goes out of scope and its memory is freed. The pointer px will still point to the old address of x which might already be assigned to a different process. Accessing the address is undefined behaviour.
Memory for an integer is reserved using new. First px points to this memory, but later on it points to the memory of a . The reserved memory is still reserved, but the address is lost, because no pointer points to it any more.
Basics of c++.
baz = *foo; |
* number; * character; * decimals; |
std; main () { firstvalue, secondvalue; * mypointer; mypointer = &firstvalue; *mypointer = 10; mypointer = &secondvalue; *mypointer = 20; cout << << firstvalue << ; cout << << secondvalue << ; 0; } |
std; main () { firstvalue = 5, secondvalue = 15; * p1, * p2; p1 = &firstvalue; p2 = &secondvalue; *p1 = 10; *p2 = *p1; p1 = p2; *p1 = 20; cout << << firstvalue << ; cout << << secondvalue << ; 0; } |
* p1, * p2; |
* p1, p2; |
myarray [20]; * mypointer; |
std; main () { numbers[5]; * p; p = numbers; *p = 10; p++; *p = 20; p = &numbers[2]; *p = 30; p = numbers + 3; *p = 40; p = numbers; *(p+4) = 50; ( n=0; n<5; n++) cout << numbers[n] << ; 0; } |
*(a+5) = 0; |
myvar; * myptr = &myvar; |
myvar; * myptr; myptr = &myvar; |
myvar; * myptr; *myptr = &myvar; |
myvar; *foo = &myvar; *bar = foo; |
*mychar; *myshort; *mylong; |
*++p ++*p (*p)++ |
x; y = 10; * p = &y; x = *p; *p = x; |
std; increment_all ( * start, * stop) { * current = start; (current != stop) { ++(*current); ++current; } } print_all ( * start, * stop) { * current = start; (current != stop) { cout << *current << ; ++current; } } main () { numbers[] = {10,20,30}; increment_all (numbers,numbers+3); print_all (numbers,numbers+3); 0; } |
x; * p1 = &x; * p2 = &x; * p3 = &x; * p4 = &x; |
* p2a = &x; * p2b = &x; |
* foo = ; |
a; * b; ** c; a = ; b = &a; c = &b; |
std; increase ( * data, psize) { ( psize == ( ) ) { * pchar; pchar=( *)data; ++(*pchar); } (psize == ( ) ) { * pint; pint=( *)data; ++(*pint); } } main () { a = ; b = 1602; increase (&a, (a)); increase (&b, (b)); cout << a << << b << ; 0; } |
* p; myarray[10]; * q = myarray+20; |
* p = 0; * q = ; |
* r = NULL; |
std; addition ( a, b) { (a+b); } subtraction ( a, b) { (a-b); } operation ( x, y, (*functocall)( , )) { g; g = (*functocall)(x,y); (g); } main () { m,n; (*minus)( , ) = subtraction; m = operation (7, 5, addition); n = operation (20, m, minus); cout <<n; 0; } |
(* minus)( , ) = subtraction; |
C structures, c reference, creating pointers.
You learned from the previous chapter, that we can get the memory address of a variable with the reference operator & :
In the example above, &myAge is also known as a pointer .
A pointer is a variable that stores the memory address of another variable as its value.
A pointer variable points to a data type (like int ) of the same type, and is created with the * operator.
The address of the variable you are working with is assigned to the pointer:
Create a pointer variable with the name ptr , that points to an int variable ( myAge ). Note that the type of the pointer has to match the type of the variable you're working with ( int in our example).
Use the & operator to store the memory address of the myAge variable, and assign it to the pointer.
Now, ptr holds the value of myAge 's memory address.
In the example above, we used the pointer variable to get the memory address of a variable (used together with the & reference operator).
You can also get the value of the variable the pointer points to, by using the * operator (the dereference operator):
Note that the * sign can be confusing here, as it does two different things in our code:
Good To Know: There are two ways to declare pointer variables in C:
Notes on Pointers
Pointers are one of the things that make C stand out from other programming languages, like Python and Java .
They are important in C, because they allow us to manipulate the data in the computer's memory. This can reduce the code and improve the performance. If you are familiar with data structures like lists, trees and graphs, you should know that pointers are especially useful for implementing those. And sometimes you even have to use pointers, for example when working with files and memory management .
But be careful ; pointers must be handled with care, since it is possible to damage data stored in other memory addresses.
Test yourself with exercises.
Create a pointer variable called ptr , that points to the int variable myAge:
Start the Exercise
If you want to use W3Schools services as an educational institution, team or enterprise, send us an e-mail: [email protected]
If you want to report an error, or if you want to make a suggestion, send us an e-mail: [email protected]
Top references, top examples, get certified.
Posted on Oct 29, 2023
In this comprehensive C Pointers tutorial, my primary goal is to guide you through the fundamentals of C pointers from the ground up. By the end of this tutorial, you will have gained an in-depth understanding of the following fundamental topics:
Null pointers, prerequisite:.
To grasp pointers effectively, you should be comfortable with basic C programming concepts, including variables, data types, functions, loops, and conditional statements. This familiarity with C programming forms the foundation for understanding how pointers work within the language. Once you have a solid grasp of these fundamental concepts, you can confidently delve into the intricacies of C pointers.
A pointer serves as a reference that holds the memory location of another variable. This memory address allows us to access the value stored at that location in the memory. You can think of a pointer as a way to reference or point to the location where data is stored in your computer's memory
Pointers can be a challenging concept for beginners to grasp, but in this tutorial, I'll explain them using real-life analogies to make the concept clearer. However, Before delving into pointers and their workings, it's important to understand the concept of a memory address.
A memory address is a unique identifier that points to a specific location in a computer's memory. Think of it like a street address for data stored in your computer's RAM (Random Access Memory). Just as a street address tells you where a particular house is located in the physical world, a memory address tells the computer where a specific piece of information or data is stored in its memory.
Take a look at the image below for a better understanding:
In this illustration, each block represents one byte of memory. It's important to note that every byte of memory has a unique address. To make it easier to understand, I've represented the addresses in decimal notation, but computers actually store these addresses using hexadecimal values. Hexadecimal is a base-16 numbering system commonly used in computing to represent memory addresses and other low-level data. It's essential to be aware of this representation when working with memory-related concepts in computer programming
Every piece of data in your computer, whether it's a number, a character, or a program instruction, is stored at a specific memory address. The amount of space reserved for each data type can vary, and it is typically measured in bytes (where 1 byte equals 8 bits, with each bit representing either 0 or 1). The specific sizes of data types also depend on the computer architecture you are using. For instance, on most 64-bit Linux machines, you'll find the following typical sizes for common data types: char = 1 byte int = 4 bytes float = 4 bytes double = 8 bytes These sizes define how much memory each data type occupies and are crucial for memory management and efficient data representation in computer systems.
You can use the sizeof operator to determine the size of data types on your computer. example:
In this example: sizeof(char) returns the size of the char data type in bytes. sizeof(int) returns the size of the int data type in bytes. sizeof(float) returns the size of the float data type in bytes. sizeof(double) returns the size of the double data type in bytes. When you run this code, it will print the sizes of these data types on your specific computer, allowing you to see the actual sizes used by your system.
When you declare a variable, the computer allocates a specific amount of memory space corresponding to the chosen data type. For instance, when you declare a variable of type char, the computer reserves 1 byte of memory because the size of the 'char' data type is conventionally 1 byte.
In this example, we declare a variable n of type char without assigning it a specific value. The memory address allocated for the n variable is 106 . This address, 106 , is where the computer will store the char variable n, but since we haven't assigned it a value yet, the content of this memory location may initially contain an unpredictable or uninitialized value.
When we assign the value 'C' to the variable n, the character 'C' is stored in the memory location associated with the variable n. When we assign the value 'C' to the variable n, the character 'C' is stored in the memory location associated with the variable n.
As mentioned earlier, a byte can only store numerical values. When we store the letter 'C' in a byte, the byte actually holds the ASCII code for 'C,' which is 67. In computer memory, characters are represented using their corresponding ASCII codes. So, in memory, the character 'C' is stored as the numerical value 67. Here's how it looks in memory
Since integers are typically stored within four bytes of memory, let's consider the same example with an int variable. In this scenario, the memory structure would appear as follows:
In this example, the memory address where the variable t is stored is 121. An int variable like “t” typically uses four consecutive memory addresses, such as 121, 122, 123, and 124. The starting address, in this case, 121, represents the location of the first byte of the int, and the subsequent addresses sequentially represent the following bytes that collectively store the complete int value.
If you want to know the memory address of a variable in a program, you can use the 'address of' unary operator, often denoted as the '&' operator. This operator allows you to access the specific memory location where a variable is stored.
When you run the following program on your computer: It will provide you with specific memory addresses for the variables c and n. However, each time you rerun the program, it might allocate new memory addresses for these variables. It's important to understand that while you can determine the memory address of a variable using the & operator, the exact memory location where a variable is stored is typically managed by the system and the compiler. As a programmer, you cannot directly control or assign a specific memory location for a variable. Instead, memory allocation and management are tasks handled by the system and the compiler.
As mentioned earlier, a pointer is a variable that stores the memory address of another variable. This memory address allows us to access the value stored at that location in memory. You can think of a pointer as a way to reference or point to the location where data is stored in your computer's memory.
Now, let's begin by declaring and initializing pointers. This step is essential because it sets up the pointer to hold a specific memory address, enabling us to interact with the data stored at that location.
Declaring Pointers: To declare a pointer, you specify the data type it points to, followed by an asterisk (*), and then the pointer's name. For example:
Here, we've declared a pointer named ptr that can point to integers.
The size of pointers on 64-bit systems is usually 8 bytes (64 bits). To determine the pointer size on your system, you can use the sizeof operator:
Initializing Pointers: Once you've declared a pointer, you typically initialize it with the memory address it should point to. Once again, To obtain the memory address of a variable, you can employ the address-of operator (&). For instance:
In this program:
We declare an integer variable x and initialize it with the value 10. This line creates a variable x in memory and assigns the value 10 to it.
We declare an integer pointer ptr using the int *ptr syntax. This line tells the compiler that ptr will be used to store the memory address of an integer variable.
We initialize the pointer ptr with the memory address of the variable x . This is achieved with the line ptr = &x; . The & operator retrieves the memory address of x, and this address is stored in the pointer ptr .
Dereferencing Pointers: To access the data that a pointer is pointing to, you need to dereference the pointer. Dereferencing a pointer means accessing the value stored at the memory address that the pointer points to. In C, you can think of pointers as variables that store memory addresses rather than actual values. To get the actual value (data) stored at that memory address, you need to dereference the pointer.
Dereferencing is done using the asterisk (*) operator. Here's an example:
It looks like this in the memory: int x = 10; variable 'x' stores the value 10:
int *ptr = &x; Now, the pointer 'ptr' point to the address of 'x':
int value = *ptr; Dereference 'ptr' to get the value stored at the address it points to:
Reading and Modifying Data: Pointers allow you to not only read but also modify data indirectly:
Note: The asterisk is a versatile symbol with different meanings depending on where it's used in your C program, for example: Declaration: When used during variable declaration, the asterisk (*) indicates that a variable is a pointer to a specific data type. For example: int *ptr; declares 'ptr' as a pointer to an integer.
Dereferencing: Inside your code, the asterisk (*) in front of a pointer variable is used to access the value stored at the memory address pointed to by the pointer. For example: int value = *ptr; retrieves the value at the address 'ptr' points to.
Pointer arithmetic is the practice of performing mathematical operations on pointers in C. This allows you to navigate through arrays, structures, and dynamically allocated memory. You can increment or decrement pointers, add or subtract integers from them, and compare them. It's a powerful tool for efficient data manipulation, but it should be used carefully to avoid memory-related issues.
Incrementing a Pointer:
Now, this program is how it looks in the memory: int arr[4] = {10, 20, 30, 40};
This behavior is a key aspect of pointer arithmetic. When you add an integer to a pointer, it moves to the memory location of the element at the specified index, allowing you to efficiently access and manipulate elements within the array. It's worth noting that you can use pointer arithmetic to access elements in any position within the array, making it a powerful technique for working with arrays of data. Now, let's print the memory addresses of the elements in the array from our previous program.
If you observe the last two digits of the first address is 40, and the second one is 44. You might be wondering why it's not 40 and 41. This is because we're working with an integer array, and in most systems, the size of an int data type is 4 bytes. Therefore, the addresses are incremented in steps of 4. The first address shows 40, the second 44, and the third one 48
Decrementing a Pointer Decrement (--) a pointer variable, which makes it point to the previous element in an array. For example, ptr-- moves it to the previous one. For example:
Explanation:
We have an integer array arr with 5 elements, and we initialize a pointer ptr to point to the fourth element (value 40) using &arr[3].
Then, we decrement the pointer ptr by one with the statement ptr--. This moves the pointer to the previous memory location, which now points to the third element (value 30).
Finally, we print the value pointed to by the decremented pointer using *ptr, which gives us the value 30.
In this program, we demonstrate how decrementing a pointer moves it to the previous memory location in the array, allowing you to access and manipulate the previous element.
Pointers to pointers, or double pointers, are variables that store the address of another pointer. In essence, they add another level of indirection. These are commonly used when you need to modify the pointer itself or work with multi-dimensional arrays.
To declare and initialize a pointer to a pointer, you need to add an extra asterisk (*) compared to a regular pointer. Let's go through an example:
In this example, ptr2 is a pointer to a pointer. It points to the memory location where the address of x is stored (which is ptr1 ).
The below program will show you how to print the value of x through pointer to pointer
In this program, we first explain that it prints the value of x using a regular variable, a pointer, and a pointer to a pointer. We then print the memory addresses of x , ptr1 , and ptr2 .
In C, you can pass pointers as function arguments. This allows you to manipulate the original data directly, as opposed to working with a copy of the data, as you would with regular variables. Here's how it works:
How to Declare and Define Functions that Take Pointer Arguments: In your function declaration and definition, you specify that you're passing a pointer by using the * operator after the data type. For example:
In the above function, we declare ptr as a pointer to an integer. This means it can store the memory address of an integer variable.
Why Would You Pass Pointers to Functions?
Passing pointers to functions allows you to:
This concept is especially important when working with large data structures or when you need to return multiple values from a function.
Understanding how data is passed to functions is crucial when working with pointers. there are two common ways that data can be passed to functions: call by value and call by reference.
When you pass data by value, a copy of the original data is created inside the function. Any modifications to this copy do not affect the original data outside of the function. This is the default behavior for most data types when you don't use pointers.
When you pass data by reference, you're actually passing a pointer to the original data's memory location. This means any changes made within the function will directly affect the original data outside the function. This is achieved by passing pointers as function arguments, making it call by reference. Using pointers as function arguments allows you to achieve call by reference behavior, which is particularly useful when you want to modify the original data inside a function and have those changes reflected outside the function.
Let's dive into some code examples to illustrate how pointers work as function arguments. We'll start with a simple example to demonstrate passing a pointer to a function and modifying the original data.
Consider this example:
In this code, we define a function modifyValue that takes a pointer to an integer. We pass the address of the variable num to this function, and it doubles the value stored in num directly.
This is a simple demonstration of passing a pointer to modify a variable's value. Pointers allow you to work with the original data efficiently.
An array of pointers is essentially an array where each element is a pointer. These pointers can point to different data types (int, char, etc.), providing flexibility and efficiency in managing memory.
How to Declare an Array of Pointers? To declare an array of pointers, you specify the type of data the pointers will point to, followed by square brackets to indicate it's an array, and then the variable name. For example:
Initializing an Array of Pointers You can initialize an array of pointers to each element to point to a specific value, For example:
How to Access Elements Through an Array of Pointers? To access elements through an array of pointers, you can use the pointer notation. For example:
This program demonstrates how to access and print the values pointed to by the pointers in the array.
A NULL pointer is a pointer that lacks a reference to a valid memory location. It's typically used to indicate that a pointer doesn't have a specific memory address assigned, often serving as a placeholder or default value for pointers.
Here's a code example that demonstrates the use of a NULL pointer:
In this example, we declare a pointer ptr and explicitly initialize it with the value NULL. We then use an if statement to check if the pointer is NULL. Since it is, the program will print "The pointer is NULL." This illustrates how NULL pointers are commonly used to check if a pointer has been initialized or assigned a valid memory address.
You've embarked on a comprehensive journey through the intricacies of C pointers. You've learned how pointers store memory addresses, enable data access, facilitate pointer arithmetic, and how they can be used with arrays and functions. Additionally, you've explored the significance of NULL pointers.
By completing this tutorial, you've equipped yourself with a robust understanding of pointers in C. You can now confidently navigate memory, manipulate data efficiently, and harness the power of pointers in your programming projects. These skills will be invaluable as you advance in your coding endeavors. Congratulations on your accomplishment, and keep coding with confidence!
Reference: C - Pointers - Tutorials Point
Pointers in C: A One-Stop Solution for Using C Pointers - simplilearn
Templates let you quickly answer FAQs or store snippets for re-use.
Love your way to write articles, could you add an article for, .o files, .h files, lists and makefile? Thank you in advance!
Great post. Thank you so much for this.
Thank you for your kind words! I'm thrilled to hear that you enjoyed the article. Your feedback means a lot to me. If you have any questions or if there's a specific topic you'd like to see in future posts, feel free to let me know. Thanks again for your support
Some comments may only be visible to logged-in visitors. Sign in to view all comments.
Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink .
Hide child comments as well
For further actions, you may consider blocking this person and/or reporting abuse
EVan Wilson - Sep 12
Renato Junior - Sep 17
Leandro Nuñez - Sep 25
We're a place where coders share, stay up-to-date and grow their careers.
If you are learning C programming, you have probably heard the term "pointer" before.
Pointers are one of the most important and powerful features of the C programming language. They allow us to manipulate memory directly, which can be very useful in many programming scenarios.
In C, a pointer is simply a variable that holds a memory address. We can think of it as a way to refer to a specific location in memory.
To declare a pointer variable in C, we use the asterisk * symbol before the variable name. There are two ways to declare pointer variables in C:
Both of these declarations are equivalent and they declare a pointer variable named "p" that can hold the memory address of an integer.
However, it's important to note that if you declare multiple variables in a single statement, you need to include the asterisk before each variable name to indicate that they are all pointers. For example:
This declares three pointer variables named "p", "q", and "r" that can hold the memory address of an integer.
When we declare a pointer variable, it does not automatically point to any particular memory location. To initialize a pointer to point to a specific variable or memory location, we use the ampersand & operator to get the address of that variable.
For example, to initialize the pointer p to point to an integer variable called x , we would write:
This sets the value of p to be the memory address of x .
Once we have a pointer that points to a specific memory location, we can access or modify the value stored at that location by dereferencing the pointer.
To dereference a pointer, we use the asterisk * symbol again, but this time in front of the pointer variable itself. For example, to print the value of the integer that p points to, we would write:
A pointer can also point to another pointer variable. This is known as a "pointer to a pointer". We declare a pointer to a pointer by using two asterisks ** . For example:
Here, q is a pointer to a pointer. It points to the address of the p variable, which in turn points to the address of the x variable
We can pass pointers to functions as arguments, which allows the function to modify the value of the original variable passed in. This is known as "passing by reference".
To pass a pointer to a function, we simply declare the function parameter as a pointer. For example:
Here, the increment function takes a pointer to an integer ( int *p ) and increments the value of the integer by one ( (*p)++ ).
In main() , we declare the integer x and a pointer p that points to x . We then call the increment function, passing in the p pointer. After the function call, x has been incremented to 43 .
One of the most powerful uses of pointers in C is for dynamic memory allocation. This allows us to allocate memory at runtime, rather than at compile time.
We use the malloc function to dynamically allocate memory, and it returns a pointer to the allocated memory. For example:
Here, p is a pointer to an integer that has been allocated using malloc . The sizeof operator is used to determine the size of an integer in bytes.
After allocating memory, we can use the pointer variable like any other pointer. When we are finished with the memory, we should free it using the free function. For example:
This frees up the memory that was allocated to p .
Sometimes you may need to cast a pointer from one type to another. You can do this using the (type *) syntax. For example:
Here, p is cast to a pointer to a double type.
Because pointers hold memory addresses, we can perform arithmetic operations on them to move them to different memory locations.
For example, we can increment a pointer to move it to the next memory location. This is often used in array operations, where we use a pointer to access elements of an array.
For example, to print the first element of an integer array using a pointer, we could write:
Here, p is set to point to the first element of the arr array, and *p dereferences the pointer to get the value of the first element (which is 1 ).
We can also declare arrays of pointers in C. For example:
This declares an array of three pointers to integers. Each element of the array can point to a separate integer variable.
We can use pointer arithmetic to access elements of an array. For example:
Here, p is set to point to the first element of the arr array. We can use pointer arithmetic to access the second element of the array ( *(p + 1) ), which is 2 .
Here's an example program that demonstrates some of the concepts we've discussed:
This program demonstrates several concepts related to pointers.
First, we declared an integer variable x and a pointer p that points to x . We called the increment function, passing in the p pointer. The increment function modifies the value of x by incrementing it by one. We then printed the value of x before and after the function call to demonstrate that x has been incremented.
Next, we used dynamic memory allocation to allocate an array of three integers. We set the values of the array elements using pointer arithmetic ( arr[0] = 1 , arr[1] = 2 , etc.). We then declared a pointer q that points to the first element of the array. Furthermore, we used pointer arithmetic to access and print the values of each element of the array.
Finally, we freed the memory that was allocated to the array using the free function.
This program demonstrates how pointers can be used to modify the value of a variable, access elements of an array using pointer arithmetic, and dynamically allocate and free memory.
Pointers can be tricky to work with, and they can lead to some common errors.
One common error is using an uninitialized pointer. If you declare a pointer variable but do not initialize it to point to a valid memory location, you may get a segmentation fault or other error when you try to dereference the pointer.
Another common error is dereferencing a null pointer, which can also cause a segmentation fault.
Another error to be aware of is using the wrong type of pointer. For example, if you declare a pointer to an integer but then try to dereference it as a pointer to a character, you may get unexpected results or errors.
Pointers are a powerful tool in C programming, but they can be a bit tricky to work with. With practice and patience, you can master pointers and use them to manipulate memory and work with complex data structures.
Thank you for reading!
Read more posts .
If this article was helpful, share it .
Learn to code for free. freeCodeCamp's open source curriculum has helped more than 40,000 people get jobs as developers. Get started
Pointers are the heart of C programming. It is the most distinct feature of C, which provides power and flexibility to C. Pointers separates C from other programming languages.
C programmers make extensive use of pointers, because of their numerous benefits. Below are some advantages of pointers.
Pointers are closely related to low level memory operations. Hence, let us first understand memory in contrast to C programming.
Computer memory ( RAM ) is a collection of contiguous block of bytes. Where individual block is called as cell (memory cell). Each cell has a unique numeric address (also known as physical memory address) associated with it. These addresses starts from zero and runs up to maximum memory size (in bytes).
For example, memory location of a 64KB RAM starts from 0 and ends to 65536 (or 0x10000) bytes.
Before I formally introduce pointers let us first see what happens during a variable definition. Consider the statement int num = 10;
A pointer is a variable that stores memory address. If it is a variable, it must have a valid C data type . Yes, every pointer variable has a data type associated with it. Which means an integer pointer can hold only integer variable addresses.
Note: We never say pointer stores or holds a memory location. Instead, we say pointer points to a memory location. So from now always use the language pointer points to a memory location.
Because we are dealing with memory addresses, we must know how to get memory address of a variable. We use unary & (reference of) operator to get memory address of a variable. Reference operator is also known as address of operator .
Read more about operators in C programming .
Example program to use reference operator.
Note: Output of above program may vary on your machine.
Once you have a memory address, you must be willing to get value stored at that memory address, for that we need to dereference the memory address.
Dereferencing is the process of retrieving value at memory location pointed by a pointer. We use unary * dereference operator to get value pointed by a memory address. Dereference operator is also known as indirection operator .
Example program to use dereference operator, how to declare pointer variable.
Once you got basics of memory addresses, reference and dereference operator. Let us declare our first pointer variable.
Pointer variable declaration follows almost similar syntax as of normal variable.
In above example I declared an integer pointer.
There are two ways to initialize a pointer variable. You can use reference operator & to get memory location of a variable or you can also directly assign one pointer variable to other pointer variable.
How pointers are stored in memory.
You got a basic picture of pointer working. Let us take a closer look on how pointer variables are stored in memory. Consider the following statements
Write a C program to demonstrate the use of pointers in C programming.
Note: %x format specifier is used to print hexadecimal representation of a decimal .
Output –
Note: Output of above program may differ on your system.
Computer Notes
How to pointer assignment and initialization in c.
By Dinesh Thakur
When we declare a pointer, it does not point to any specific variable. We must initialize it to point to the desired variable. This is achieved by assigning the address of that variable to the pointer variable, as shown below.
int a = 10;
pa = &a; /* pointer variable pa now points to variable a */
In this example, the first line declares an int variable named a and initializes it to 10. The second line declares a pointer pa of type pointer to int. Finally, the address of variable a is assigned to pa.Now pa is said to point to variable a.
We can also initialize a pointer when it is declared using the format given below.
type * ptr_var = init_expr ;
where init_expr is an expression that specifies the address of a previously defined variable of appropriate type or it can be NULL, a constant defined in the <stdio.h> header file.
Consider the example given below.
float x = 0.5;
float *px = &x;
int *p = NULL;
The second line declares a pointer variable px of type float * and initializes it with the address of variable x declared in the first line. Thus, pointer px now points to variable x. The third line declares pointer variable p of type int * and initializes it to NULL. Thus, pointer p does not point to any variable and it is an error to dereference such a pointer.
Note that a character pointer can be initialized using a character string constant as in
char *msg = “Hello, world!”;
Here, the C compiler allocates the required memory for the string constant (14 characters, in the above example, including the null terminator), stores the string constant in this memory and then assigns the initial address of this memory to pointer msg,as iliustrated in Fig.
The C language also permits initialization of more that one pointer variable in a single statement using the format shown below.
type *ptr_var1 = init_expr1, *ptr_var2 = init_expr2, … ;
It is also possible to mix the declaration and initialization of ordinary variables and pointers. However, we should avoid it to maintain program readability.
char a= ‘A’;
char *pa = &a;
printf(“The address of character variable a: %p\n”, pa);
printf(“The address of pointer variable pa : %p\n”, &pa);
printf(“The value pointed by pointer variable pa: %c\n”, *pa);
Here, pa is a character pointer variable that is initialized with the address of character variable a defined in the first line. Thus, pa points to variable a. The first two printf statements print the address of variables a and pa using the %p (p for pointer) conversion. The last printf statement prints the value of a using the pointer variable pa. When the program containing this code is executed in Code::Blocks, the output is displayed as shown below. ·
The address of character variable a: 0022FF1F
The address of pointer variable pa : 0022FF18
The value pointed by pointer variable pa: A
Note that the addresses displayed in the output will usually be different depending on other variables declared in the program and the compiler/IDE used.
Another example is given below in which pointers are initialized with the addresses of variables of incompatible type.
char c = ‘Z’;
int i = 10;
float f = 1.1;
char *pcl = &i, *pc2 = &f;
int *pil = &c, *pi2 = &f;
float *pfl = &c, *pf2 = &i;
printf(“Character: %c %c\n”, *pcl, *pc2);
printf(“Integer : %d %d\n”, *pil, *pi2);
printf (“Float : %f %f\n”, =pfl, *pf2);
Note that the character pointer variables pcl and pc2 are initialized with the addresses of the int and float variables, respectively. Similarly, the int and float pointer variables are also initialized with addresses of variables of incompatible type. When the program containing this code is compiled in Code::Blocks, the compiler reports six warning messages (initialization from incompatible pointer type), one for each incompatible pointer initialization.
It is not a good idea to ignore such warnings associated with pointers. Although, the program executes in the presence of these warnings, it displays wrong results as shown below.
Integer : 90 1066192077
Float : 0.000000 0.000000
Dinesh Thakur is a Freelance Writer who helps different clients from all over the globe. Dinesh has written over 500+ blogs, 30+ eBooks, and 10000+ Posts for all types of clients.
For any type of query or something that you think is missing, please feel free to Contact us .
Prerequisite: Pointers in C
The pointer to a pointer in C is used when we want to store the address of another pointer. The first pointer is used to store the address of the variable. And the second pointer is used to store the address of the first pointer. That is why they are also known as double-pointers . We can use a pointer to a pointer to change the values of normal pointers or create a variable-sized 2-D array. A double pointer occupies the same amount of space in the memory stack as a normal pointer.
Declaring Pointer to Pointer is similar to declaring a pointer in C. The difference is we have to place an additional ‘*’ before the name of the pointer.
The above diagram shows the memory representation of a pointer to a pointer. The first pointer ptr1 stores the address of the variable and the second pointer ptr2 stores the address of the first pointer.
The working of the double-pointer can be explained using the above image:
In the C programming language, a double pointer behaves similarly to a normal pointer in C. So, the size of the double-pointer variable is always equal to the normal pointers. We can verify this using the below C Program.
Note: The output of the above code also depends on the type of machine which is being used. The size of a pointer is not fixed in the C programming language and it depends on other factors like CPU architecture and OS used. Usually, for a 64-bit Operating System, the size will be 8 bytes and for a 32-bit Operating system, the size will be 4 bytes.
Following are the main uses of pointer to pointers in C:
Double Pointers are not the only multilevel pointers supported by the C language. What if we want to change the value of a double pointer?
In this case, we can use a triple pointer, which will be a pointer to a pointer to a pointer i.e, int ***t_ptr.
Similarly, to change the value of a triple pointer we can use a pointer to a pointer to a pointer to a pointer (Four level Pointer). In other words, we can say that to change the value of a ” level – x ” variable we can use a ” level – x+1 ” pointer. And this concept can be extended further.
Note : We can use any level pointer in C. There is no restriction about it but it makes the program very complex and vulnerable to errors.
Must Read – Function Pointer in C
Please login to comment....
Find centralized, trusted content and collaborate around the technologies you use most.
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Get early access and see previews of new features.
This is a fragment of a program and it works.
Can anyone explain how can an int variable address be assigned to char pointer?
This works, because size of char pointer is the same as size of an int pointer. However, when some pointer arithmetic will be applied, you won't get valid results. It means that if you would like to access second element of your array - p[1] then only one byte would added to the p address. If p would be of type int, then 4 byte would be added (since that's the size of int) and second element would be accessed properly.
As I have intel processor, which is in little endian, arr[0] in memory is stored as following:
p[1] which is equivalent to *(p + 1), will add one byte to p pointer, because size of p is char.
and printf("%d\n, p[1]); gives 0. Note that if you were on big endian machine, the result of printing p[0] would be different (e.g. 0).
However, your compiler should warn you about what you're doing.
warning: assignment from incompatible pointer type [enabled by default]
When you assign a char point to the address of integer array, many things can happen, depending on the size of the integer. Below is the memory location of the array in compile under 32 bit windows OS. You may also want to cast it p=(char*)arr.
01 00 00 00 02 00 00 00 03 00 00 00
Your code is invalid. In C language an int * pointer cannot be assigned to a char * pointer without an explicit conversion. C language prohibits assignment of incompatible pointer types. (I.e. it prohibits implicit conversion between such types). Your compiler probably issued a diagnostic message telling you exactly the same thing. Your code contains constraint violation - it is not a valid C code.
This conversion was legal a long time ago, in archaic non-standardized versions of C language. For that reason, by default C compilers are rather permissive with regard to invalid code of this kind. They issue diagnostic messages as "warnings", but continue to compile the code, which misleads some people into believing that the code is valid.
Many C compilers offer you additional options that make them more explicit in detecting such errors. For example, in GCC you have to specify -pedantic-errors switch to have this constraint violation reported with an "error" message.
If your compiler accepted the code, its behavior is the same as if you wrote p = (char *) arr , i.e. it makes p point to the beginning of the arr array. That's all there is to it. If you attempt to access the array data through pointer p , you will simply reinterpret the memory occupied by arr as a sequence of char s. What you will see there will depend on many implementation-dependent factors. (I.e. there are no universal answers to your "Why do I see 0 there? Why do I see 2 there?" questions.) For example, the reinterpreted data will look different between big-endian and little-endian platforms.
Yes you can assign a address of variable of any type to pointer of any type (however you may get a warning about assigning incompatible pointer type). This is because sizeof pointer of any type is same.
For Example:-
Side effect of this:
Consider the following example:
In order to understand this output you need to consider binary values of variables.
Lets start with i1:- Binary value of i1 is
and by assigning address of this memory to char pointer causes char pointer c1 to point to first byte (Little Endian Method) .
Now binary value of i2 is
here again c2 points to first byte but why output is -128? because first byte is 10000000 that sign bit is 1 which means number is negative now perform a reverse operation of 2's complement
Your compiler should give you a warning that this is not compatible.
After assignment , lets say address of arr is 1000, arr[0] will be at address 1000, arr[1] will be at address 1004 and arr[2] will be at address 1008
Now p points to arr, so it points to address 1000, so every time you want to access arr[1] you will have to use *(p + 4) since char is 1 byte only (Also care should be taken if its a little endian or big endian machine)
Though its incompatible you can use it but you should be carefull when you use this assignment.
gdb output.
Reminder: Answers generated by artificial intelligence tools are not allowed on Stack Overflow. Learn more
Post as a guest.
Required, but never shown
By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy .
IMAGES
VIDEO
COMMENTS
Pointers are one of the core components of the C programming language. A pointer can be used to store the memory address of other variables, functions, or even other pointers. The use of pointers allows low-level memory access, dynamic memory allocation, and many other functionality in C. ... Assignment of pointers of the same type. C
You need to create an int variable somewhere in memory for the int * variable to point at. Your second example does this, but it does other things that aren't relevant here. Here's the simplest thing you need to do: int main(){. int variable; int *ptr = &variable; *ptr = 20; printf("%d", *ptr); return 0;
Pointers and assignment. We can use assignment with pointers in two different ways: To change what the pointer is pointing at (by assigning the pointer a new address) To change the value being pointed at (by assigning the dereferenced pointer a new value) First, let's look at a case where a pointer is changed to point at a different object:
Pointer assignment between two pointers makes them point to the same pointee. So the assignment y = x; makes y point to the same pointee as x. Pointer assignment does not touch the pointees. It just changes one pointer to have the same reference as another pointer. After pointer assignment, the two pointers are said to be "sharing" the pointee.
A pointer a pointing to the memory address associated with a variable b, i.e., a contains the memory address 1008 of the variable b.In this diagram, the computing architecture uses the same address space and data primitive for both pointers and non-pointers; this need should not be the case.. In computer science, a pointer is an object in many programming languages that stores a memory address.
Explanation of the program. int* pc, c; Here, a pointer pc and a normal variable c, both of type int, is created. Since pc and c are not initialized at initially, pointer pc points to either no address or a random address. And, variable c has an address but contains random garbage value.; c = 22; This assigns 22 to the variable c.That is, 22 is stored in the memory location of variable c.
Here b points to a char that stores 'g' and c points to the pointer b. Void Pointers. This is a special type of pointer available in C++ which represents the absence of type. Void pointers are pointers that point to a value that has no type (and thus also an undetermined length and undetermined dereferencing properties). This means that ...
Pointers are arguably the most difficult feature of C to understand. But, they are one of the features which make C an excellent language. In this article, we will go from the very basics of pointers to their usage with arrays, functions, and structure. So relax, grab a coffee, and get ready to learn all about pointers.
Certain addition, subtraction, compound assignment, increment, and decrement operators are defined for pointers to elements of arrays.. Comparison operators are defined for pointers to objects in some situations: two pointers that represent the same address compare equal, two null pointer values compare equal, pointers to elements of the same array compare the same as the array indices of ...
In general, pointer is a type of a variable that stores a link to another object. In C and C++, the link is the address of that object in the program memory. Pointers allow to refer to the same object from multiple locations of the source code without copying the object. Also, the same pointer variable may refer to different objects during its ...
This is a standard assignment operation, as already done many times in earlier chapters. The main difference between the second and third statements is the appearance of the address-of operator (&). The variable that stores the address of another variable (like foo in the previous example) is what in C++ is called a pointer. Pointers are a very ...
char *pa = &a; // pa now contains the address of a. printf("%p", pa); // %p is the format specifier to print a pointer. If you run this program, you will see something like 0x7ffc2fc4ff27. That is the value of the pointer, which is the address of the variable a (this is in hexadecimal). This value is not fixed.
Example explained. Create a pointer variable with the name ptr, that points to a string variable, by using the asterisk sign * (string* ptr). Note that the type of the pointer has to match the type of the variable you're working with. Use the & operator to store the memory address of the variable called food, and assign it to the pointer.
Example explained. Create a pointer variable with the name ptr, that points to an int variable (myAge).Note that the type of the pointer has to match the type of the variable you're working with (int in our example).Use the & operator to store the memory address of the myAge variable, and assign it to the pointer.. Now, ptr holds the value of myAge's memory address.
Accessing Data through Pointers. Dereferencing Pointers: To access the data that a pointer is pointing to, you need to dereference the pointer. Dereferencing a pointer means accessing the value stored at the memory address that the pointer points to. In C, you can think of pointers as variables that store memory addresses rather than actual values.
A pointer can also point to another pointer variable. This is known as a "pointer to a pointer". We declare a pointer to a pointer by using two asterisks **. For example: int x = 42; int *p = &x; int **q = &p; Here, q is a pointer to a pointer. It points to the address of the p variable, which in turn points to the address of the x variable
A pointer is a variable that stores memory address. If it is a variable, it must have a valid C data type. Yes, every pointer variable has a data type associated with it. Which means an integer pointer can hold only integer variable addresses. Note: We never say pointer stores or holds a memory location. Instead, we say pointer points to a ...
As to why one uses pointers to pointers:. The name of an array usually yields the address of its first element. So if the array contains elements of type t, a reference to the array has type t *.Now consider an array of arrays of type t: naturally a reference to this 2D array will have type (t *)* = t **, and is hence a pointer to a pointer.; Even though an array of strings sounds one ...
This is achieved by assigning the address of that variable to the pointer variable, as shown below. int a = 10; int *pa; pa = &a; /* pointer variable pa now points to variable a */. In this example, the first line declares an int variable named a and initializes it to 10. The second line declares a pointer pa of type pointer to int.
The pointer to a pointer in C is used when we want to store the address of another pointer. The first pointer is used to store the address of the variable. And the second pointer is used to store the address of the first pointer. That is why they are also known as double-pointers. We can use a pointer to a pointer to change the values of normal ...
Salt Lake City, Utah September 26, 2024 - Colliers has been appointed as the exclusive leasing agent for 2.3 million square feet of office space at The Point, a historic mixed-use site encompassing 6.3 million square feet in Draper, Utah. This historic project represents one of the largest and most innovative developments in the United States, offering a transformative opportunity for ...
In C language an int * pointer cannot be assigned to a char * pointer without an explicit conversion. C language prohibits assignment of incompatible pointer types. (I.e. it prohibits implicit conversion between such types). Your compiler probably issued a diagnostic message telling you exactly the same thing.