- Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers
- Advertising & Talent Reach devs & technologists worldwide about your product, service or employer brand
- OverflowAI GenAI features for Teams
- OverflowAPI Train & fine-tune LLMs
- Labs The future of collective knowledge sharing
- About the company Visit the blog
Collectives™ on Stack Overflow
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.
Staging Ground badges
Earn badges by improving or asking questions in Staging Ground.
Directly assigning values to C Pointers
I've just started learning C and I've been running some simple programs using MinGW for Windows to understand how pointers work. I tried the following:
which compiled properly but when I run the executable it doesn't work - the value isn't printed to the command line, instead I get an error message that says the .exe file has stopped working.
However when I tried storing the value in an int variable and assign *ptr to the memory address of that variable as shown below:
it works fine.
My question is, why am I unable to directly set a literal value to the pointer? I've looked at tutorials online for pointers and most of them do it the same way as the second example.
Any help is appreciated.
- Cause that pointer is not initialized - it may point to pretty much anywhere and might crash the program. – Till Commented Jul 15, 2013 at 23:50
- 1 You got lucky that it terminated with an error. – JonnyRo Commented Jul 15, 2013 at 23:55
- 2 @JonnyRo is right. In real code, this kind of bug tends to lead to either week-long debugging sessions trying to figure out why some other variable randomly changes every once in a while (never when you're actually testing for it, always when you're doing a public demonstration) or security exploits where someone sets the "is_admin" flag to true by manipulating different values. – abarnert Commented Jul 16, 2013 at 0:20
- The title of this question, "Directly assigning values to C Pointers" is a bit misleading. The whole problem is that you don't assign a value to the pointer. – Keith Thompson Commented Sep 27, 2015 at 1:32
- 1 int *pointer=NULL; Initialize a pointer to null during declaration is a good software engineering practice. – Zeni Commented Jun 24, 2022 at 11:47
4 Answers 4
The problem is that you're not initializing the pointer. You've created a pointer to "anywhere you want"—which could be the address of some other variable, or the middle of your code, or some memory that isn't mapped at all.
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:
Here, the int variable isn't initialized—but that's fine, because you're just going to replace whatever value was there with 20 . The key is that the pointer is initialized to point to the variable . In fact, you could just allocate some raw memory to point to, if you want:
First Program with comments
Second Program with comments
The key is you cannot use a pointer until you know it is assigned to an address that you yourself have managed, either by pointing it at another variable you created or to the result of a malloc call.
Using it before is creating code that depends on uninitialized memory which will at best crash but at worst work sometimes, because the random memory address happens to be inside the memory space your program already owns. God help you if it overwrites a data structure you are using elsewhere in your program.
In the first example, ptr has not been initialized, so it points to an unspecified memory location. When you assign something to this unspecified location, your program blows up.
In the second example, the address is set when you say ptr = &q, so you're OK.
You can set a value for the pointer, but once you've asked for memory for it using "new". This is how your code should look
- 1 new is C++. The OP was asking about C. – Steve Summit Commented Jun 17, 2021 at 1:37
Your Answer
Reminder: Answers generated by artificial intelligence tools are not allowed on Stack Overflow. Learn more
Sign up or log in
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 .
Not the answer you're looking for? Browse other questions tagged c pointers or ask your own question .
- The Overflow Blog
- Brain Drain: David vs Goliath
- How API security is evolving for the GenAI era
- Featured on Meta
- Preventing unauthorized automated access to the network
- Upcoming initiatives on Stack Overflow and across the Stack Exchange network...
- Proposed designs to update the homepage for logged-in users
Hot Network Questions
- Why is toluene less acidic than cyclopentadiene?
- Can you take the maximum result of a die roll when you are not pressed for time and there is no usage limit?
- Is travel insurance required for an hour stopover in Paris, France
- Are there any commentaries regarding the first disciples of Christ already being disciples of John?
- Explanation of syntax and parameters of a sample UTM projection file
- How can these regular polygons be arranged within a page
- How can I non destructively remove this ceiling to run electrical wires?
- There is mathematics in physics but is there any physics in mathematics?
- Is it 'de mortibus nihil nisi bonum/bene', or is it 'de mortuis nihil nisi bonum/bene'?
- How does an entangled state collapse when we measure only one qubit?
- How long would it have taken to travel from Southampton to Madeira by boat in the 1920s?
- Can \AddToHookWithArguments let us access to the arguments of a command that has an optional argument?
- A bunch of grammas
- How do I make reimbursements easier on my students?
- Nexus 8 Gear Hub spring not working
- Does -iller have an implied meaning in French verbs?
- 1 curly bracket on the left and 2 curly brackets on the right of a list of items
- Does every variable need to be statistically significant in a regression model?
- Are cantrips prepared spells?
- Is it possible that mosquitoes have been laying eggs and reproducing inside my house?
- A bird that is about as UNBIRD-LIKE as it is possible for a bird to be. | Is "unbird-like" applicable to other nouns?
- Converting a char string to wchar_t string based on a given toWideStr() starting point
- PhD program but no funding?
- Latex; cant fit in my paper
- Engineering Mathematics
- Discrete Mathematics
- Operating System
- Computer Networks
- Digital Logic and Design
- C Programming
- Data Structures
- Theory of Computation
- Compiler Design
- Computer Org and Architecture
Pointer Expressions in C with Examples
Prerequisite: Pointers in C Pointers are used to point to address the location of a variable. A pointer is declared by preceding the name of the pointer by an asterisk(*) . Syntax:
When we need to initialize a pointer with variable’s location, we use ampersand sign(&) before the variable name. Example:
The ampersand (&) is used to get the address of a variable. We can directly find the location of any identifier by just preceding it with an ampersand(&) sign. Example:
Arithmetic Operators
We can perform arithmetic operations to pointer variables using arithmetic operators. We can add an integer or subtract an integer using a pointer pointing to that integer variable. The given table shows the arithmetic operators that can be performed on pointer variables:
We can also directly perform arithmetic expressions on integers by dereferencing pointers. Let’s look at the example given below where p1 and p2 are pointers.
Note: While performing division, make sure you put a blank space between ‘/’ and ‘*’ of the pointer as together it would make a multi-line comment(‘/*’). Example:
Relational Operators
The value of the relational expression is either 0 or 1 that is false or true. The expression will return value 1 if the expression is true and it’ll return value 0 if false. Let us understand relational expression on pointer better with the code given below:
Assignment Operators
Assignment operators are used to assign values to the identifiers. There are multiple shorthand operations available. A table is given below showing the actual assignment statement with its shorthand statement.
Let us understand assignment operator in better way with the help of code given below:
Conditional Operators
There is only one mostly used conditional operator in C known as Ternary operator. Ternary operator first checks the expression and depending on its return value returns true or false, which triggers/selects another expression. Syntax:
- As shown in example, assuming *ptr1=20 and *ptr2=10 then the condition here becomes true for the expression, so it’ll return value of true expression i.e. *ptr1, so variable ‘c’ will now contain value of 20.
- Considering same example, assume *ptr1=30 and *ptr2=50 then the condition is false for the expression, so it’ll return value of false expression i.e. *ptr2, so variable ‘c’ will now contain value 50.
Let us understand the concept through the given code:
Unary Operators
Let us understand the use of the unary operator through the given code:
Bitwise Operators
Similar Reads
Please login to comment..., improve your coding skills with practice.
What kind of Experience do you want to share?
cppreference.com
Pointer declaration.
(C11) | ||||
Miscellaneous | ||||
(C11) | ||||
(C23) |
Pointer is a type of an object that refers to a function or an object of another type, possibly adding qualifiers. Pointer may also refer to nothing, which is indicated by the special null pointer value.
Syntax Explanation Pointers to objects Pointers to functions Pointers to void Null pointers Notes References See also |
[ edit ] Syntax
In the declaration grammar of a pointer declaration, the type-specifier sequence designates the pointed-to type (which may be function or object type and may be incomplete), and the declarator has the form:
attr-spec-seq (optional) qualifiers (optional) declarator | |||||||||
where declarator may be the identifier that names the pointer being declared, including another pointer declarator (which would indicate a pointer to a pointer):
The qualifiers that appear between * and the identifier (or other nested declarator) qualify the type of the pointer that is being declared:
The attr-spec-seq (C23) is an optional list of attributes , applied to the declared pointer.
[ edit ] Explanation
Pointers are used for indirection, which is a ubiquitous programming technique; they can be used to implement pass-by-reference semantics, to access objects with dynamic storage duration , to implement "optional" types (using the null pointer value), aggregation relationship between structs, callbacks (using pointers to functions), generic interfaces (using pointers to void), and much more.
[ edit ] Pointers to objects
A pointer to object can be initialized with the result of the address-of operator applied to an expression of object type (which may be incomplete):
Pointers may appear as operands to the indirection operator (unary * ), which returns the lvalue identifying the pointed-to object:
Pointers to objects of struct and union type may also appear as the left-hand operands of the member access through pointer operator -> .
Because of the array-to-pointer implicit conversion, pointer to the first element of an array can be initialized with an expression of array type:
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 those elements, and pointers to struct members compare in order of declaration of those members.
Many implementations also provide strict total ordering of pointers of random origin, e.g. if they are implemented as addresses within continuous ("flat") virtual address space.
[ edit ] Pointers to functions
A pointer to function can be initialized with an address of a function. Because of the function-to-pointer conversion, the address-of operator is optional:
Unlike functions, pointers to functions are objects and thus can be stored in arrays, copied, assigned, passed to other functions as arguments, etc.
A pointer to function can be used on the left-hand side of the function call operator ; this invokes the pointed-to function:
Dereferencing a function pointer yields the function designator for the pointed-to function:
Equality comparison operators are defined for pointers to functions (they compare equal if pointing to the same function).
Because compatibility of function types ignores top-level qualifiers of the function parameters, pointers to functions whose parameters only differ in their top-level qualifiers are interchangeable:
[ edit ] Pointers to void
Pointer to object of any type can be implicitly converted to pointer to void (optionally const or volatile -qualified), and vice versa:
Pointers to void are used to pass objects of unknown type, which is common in generic interfaces: malloc returns void * , qsort expects a user-provided callback that accepts two const void * arguments. pthread_create expects a user-provided callback that accepts and returns void * . In all cases, it is the caller's responsibility to convert the pointer to the correct type before use.
[ edit ] Null pointers
Pointers of every type have a special value known as null pointer value of that type. A pointer whose value is null does not point to an object or a function (dereferencing a null pointer is undefined behavior), and compares equal to all pointers of the same type whose value is also null .
To initialize a pointer to null or to assign the null value to an existing pointer, a null pointer constant ( NULL , or any other integer constant with the value zero) may be used. static initialization also initializes pointers to their null values.
Null pointers can indicate the absence of an object or can be used to indicate other types of error conditions. In general, a function that receives a pointer argument almost always needs to check if the value is null and handle that case differently (for example, free does nothing when a null pointer is passed).
[ edit ] Notes
Although any pointer to object can be cast to pointer to object of a different type, dereferencing a pointer to the type different from the declared type of the object is almost always undefined behavior. See strict aliasing for details.
It is possible to indicate to a function that accesses objects through pointers that those pointers do not alias. See for details. | (since C99) |
lvalue expressions of array type, when used in most contexts, undergo an implicit conversion to the pointer to the first element of the array. See array for details.
Pointers to char are often used to represent strings . To represent a valid byte string, a pointer must be pointing at a char that is an element of an array of char, and there must be a char with the value zero at some index greater or equal to the index of the element referenced by the pointer.
[ edit ] References
- C23 standard (ISO/IEC 9899:2024):
- 6.7.6.1 Pointer declarators (p: TBD)
- C17 standard (ISO/IEC 9899:2018):
- 6.7.6.1 Pointer declarators (p: 93-94)
- C11 standard (ISO/IEC 9899:2011):
- 6.7.6.1 Pointer declarators (p: 130)
- C99 standard (ISO/IEC 9899:1999):
- 6.7.5.1 Pointer declarators (p: 115-116)
- C89/C90 standard (ISO/IEC 9899:1990):
- 3.5.4.1 Pointer declarators
[ edit ] See also
for Pointer declaration |
- Recent changes
- Offline version
- What links here
- Related changes
- Upload file
- Special pages
- Printable version
- Permanent link
- Page information
- In other languages
- This page was last modified on 9 April 2024, at 00:10.
- Privacy policy
- About cppreference.com
- Disclaimers
Learn C practically and Get Certified .
Popular Tutorials
Popular examples, reference materials, learn c interactively, c introduction.
- Getting Started with C
- Your First C Program
C Fundamentals
- C Variables, Constants and Literals
- C Data Types
- C Input Output (I/O)
- C Programming Operators
C Flow Control
- C if...else Statement
- C while and do...while Loop
- C break and continue
- C switch Statement
- C goto Statement
- C Functions
- C User-defined functions
- Types of User-defined Functions in C Programming
- C Recursion
- C Storage Class
C Programming Arrays
- C Multidimensional Arrays
- Pass arrays to a function in C
C Programming Pointers
Relationship Between Arrays and Pointers
C Pass Addresses and Pointers
C Dynamic Memory Allocation
- C Array and Pointer Examples
- C Programming Strings
- String Manipulations In C Programming Using Library Functions
- String Examples in C Programming
C Structure and Union
C structs and Pointers
- C Structure and Function
C Programming Files
- C File Handling
- C Files Examples
C Additional Topics
- C Keywords and Identifiers
- C Precedence And Associativity Of Operators
- C Bitwise Operators
- C Preprocessor and Macros
- C Standard Library Functions
C Tutorials
- Access Array Elements Using Pointer
Pointers are powerful features of C and C++ programming. Before we learn pointers, let's learn about addresses in C programming.
- Address in C
If you have a variable var in your program, &var will give you its address in the memory.
We have used address numerous times while using the scanf() function.
Here, the value entered by the user is stored in the address of var variable. Let's take a working example.
Note: You will probably get a different address when you run the above code.
Pointers (pointer variables) are special variables that are used to store addresses rather than values.
Pointer Syntax
Here is how we can declare pointers.
Here, we have declared a pointer p of int type.
You can also declare pointers in these ways.
Let's take another example of declaring pointers.
Here, we have declared a pointer p1 and a normal variable p2 .
- Assigning addresses to Pointers
Let's take an example.
Here, 5 is assigned to the c variable. And, the address of c is assigned to the pc pointer.
Get Value of Thing Pointed by Pointers
To get the value of the thing pointed by the pointers, we use the * operator. For example:
Here, the address of c is assigned to the pc pointer. To get the value stored in that address, we used *pc .
Note: In the above example, pc is a pointer, not *pc . You cannot and should not do something like *pc = &c ;
By the way, * is called the dereference operator (when working with pointers). It operates on a pointer and gives the value stored in that pointer.
- Changing Value Pointed by Pointers
We have assigned the address of c to the pc pointer.
Then, we changed the value of c to 1. Since pc and the address of c is the same, *pc gives us 1.
Let's take another example.
Then, we changed *pc to 1 using *pc = 1; . Since pc and the address of c is the same, c will be equal to 1.
Let's take one more example.
Initially, the address of c is assigned to the pc pointer using pc = &c; . Since c is 5, *pc gives us 5.
Then, the address of d is assigned to the pc pointer using pc = &d; . Since d is -15, *pc gives us -15.
- Example: Working of Pointers
Let's take a working example.
Explanation of the program
Common mistakes when working with pointers
Suppose, you want pointer pc to point to the address of c . Then,
Here's an example of pointer syntax beginners often find confusing.
Why didn't we get an error when using int *p = &c; ?
It's because
is equivalent to
In both cases, we are creating a pointer p (not *p ) and assigning &c to it.
To avoid this confusion, we can use the statement like this:
Now you know what pointers are, you will learn how pointers are related to arrays in the next tutorial.
Table of Contents
- What is a pointer?
- Common Mistakes
Sorry about that.
Our premium learning platform, created with over a decade of experience and thousands of feedbacks .
Learn and improve your coding skills like never before.
- Interactive Courses
- Certificates
- 2000+ Challenges
Related Tutorials
CHAPTER 1: What is a pointer?
DEV Community
Posted on Oct 29, 2023
How C-Pointers Works: A Step-by-Step Beginner's Tutorial
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:
- What is a Pointer?
- How Data is Stored in Memory?
- Storing Memory Addresses using Pointers
Accessing Data through Pointers
- Pointer Arithmetic
- Pointer to Pointer (Double Pointers)
- Passing Pointers as Function Arguments
Arrays of Pointers
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.
What is a pointer?
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
How data is stored in the memory:
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.
Storing memory address using pointers
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:
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.
Pointer to pointer
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 .
Passing Pointers as Function Arguments:
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:
- Modify the original data directly within the function.
- Avoid making a copy of the data, which can be more memory-efficient.
- Share data between different parts of your program efficiently.
This concept is especially important when working with large data structures or when you need to return multiple values from a function.
Call by Value vs. Call by Reference:
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.
Call by Value:
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.
Call by Reference (Using 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.
conclusion:
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
Top comments (3)
Templates let you quickly answer FAQs or store snippets for re-use.
- Joined Jan 7, 2024
Love your way to write articles, could you add an article for, .o files, .h files, lists and makefile? Thank you in advance!
- Joined Nov 4, 2023
Great post. Thank you so much for this.
- Email [email protected]
- Joined Jul 7, 2023
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
Create an AI Customer Service Chatbot API
Makram El Timani - Oct 2
How to Switch Between Shopify Apps
babar ali - Oct 3
Native iOS App Updater in Flutter: How Zomato, Swiggy, and Others Do It
Md. Mobin - Sep 29
Payments Recruiter Tips: Dos and Don’ts for Job Seekers
Fabina Sari - Sep 28
We're a place where coders share, stay up-to-date and grow their careers.
Pointers in C Explained – They're Not as Difficult as You Think
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.
A. Fundamentals
- What exactly are pointers?
- Definition and Notation
- Some Special Pointers
- Pointer Arithmetic
B. Arrays and Strings
- Why pointers and arrays?
- Array of Pointers
- Pointer to Array
C. Functions
- Call by Value v/s Call by Reference
- Pointers as Function Arguments
- Pointers as Function Return
- Pointer to Function
- Array Of Pointers to Functions
- Pointer to Function as an Argument
D. Structure
- Pointer to Structure
- Array of Structure
- Pointer to Structure as an Argument
E. Pointer to Pointer
F. conclusion, a. definition, notation, types and arithmetic, 1. what exactly are pointers.
Before we get to the definition of pointers, let us understand what happens when we write the following code:
A block of memory is reserved by the compiler to hold an int value. The name of this block is digit and the value stored in this block is 42 .
Now, to remember the block, it is assigned with an address or a location number (say, 24650).
The value of the location number is not important for us, as it is a random value. But, we can access this address using the & (ampersand) or address of operator.
We can get the value of the variable digit from its address using another operator * (asterisk), called the indirection or dereferencing or value at address operator.
2. Definition and Notation
The address of a variable can be stored in another variable known as a pointer variable. The syntax for storing a variable's address to a pointer is:
For our digit variable, this can be written like this:
or like this:
This can be read as - A pointer to int (integer) addressOfDigit stores the address of(&) digit variable.
Few points to understand:
dataType – We need to tell the computer what the data type of the variable is whose address we are going to store. Here, int was the data type of digit .
It does not mean that addressOfDigit will store a value of type int . An integer pointer (like addressOfDigit ) can only store the address of variables of integer type.
* – A pointer variable is a special variable in the sense that it is used to store an address of another variable. To differentiate it from other variables that do not store an address, we use * as a symbol in the declaration.
Here, we can assign the address of variable1 and variable2 to the integer pointer addressOfVariables but not to variable3 since it is of type char . We will need a character pointer variable to store its address.
We can use our addressOfDigit pointer variable to print the address and the value of digit as below:
Here, *addressOfDigit can be read as the value at the address stored in addressOfDigit .
Notice we used %d as the format identifier for addressOfDigit . Well, this is not completely correct. The correct identifier would be %p .
Using %p , the address is displayed as a hexadecimal value. But the memory address can be displayed in integers as well as octal values. Still, since it is not an entirely correct way, a warning is shown.
The output according to the compiler I'm using is the following:
This is the warning shown when you use %d - " warning: format '%d' expects argument of type 'int', but argument 2 has type 'int *' ".
3. Some Special Pointers
The wild pointer.
When we defined our character pointer alphabetAddress , we did not initialize it.
Such pointers are known as wild pointers . They store a garbage value (that is, memory address) of a byte that we don't know is reserved or not (remember int digit = 42; , we reserved a memory address when we declared it).
Suppose we dereference a wild pointer and assign a value to the memory address it is pointing at. This will lead to unexpected behaviour since we will write data at a memory block that may be free or reserved.
Null Pointer
To make sure that we do not have a wild pointer, we can initialize a pointer with a NULL value, making it a null pointer .
A null pointer points at nothing, or at a memory address that users can not access.
Void Pointer
A void pointer can be used to point at a variable of any data type. It can be reused to point at any data type we want to. It is declared like this:
Since they are very general in nature, they are also known as generic pointers .
With their flexibility, void pointers also bring some constraints. Void pointers cannot be dereferenced as any other pointer. Appropriate typecasting is necessary.
Similarly, void pointers need to be typecasted for performing arithmetic operations.
Void pointers are of great use in C. Library functions malloc() and calloc() which dynamically allocate memory return void pointers. qsort() , an inbuilt sorting function in C, has a function as its argument which itself takes void pointers as its argument.
Dangling Pointer
A dangling pointer points to a memory address which used to hold a variable. Since the address it points at is no longer reserved, using it will lead to unexpected results.
Though the memory has been deallocated by free(ptr) , the pointer to integer ptr still points to that unreserved memory address.
4. Pointer Arithmetic
We know by now that pointers are not like any other variable. They do not store any value but the address of memory blocks.
So it should be quite clear that not all arithmetic operations would be valid with them. Would multiplying or dividing two pointers ( having addresses ) make sense?
Pointers have few but immensely useful valid operations:
- You can assign the value of one pointer to another only if they are of the same type (unless they're typecasted or one of them is void * ).
- You can only add or subtract integers to pointers.
When you add (or subtract) an integer (say n) to a pointer, you are not actually adding (or subtracting) n bytes to the pointer value. You are actually adding (or subtracting) n- times the size of the data type of the variable being pointed bytes.
The value stored in newAddress will not be 103, rather 112 .
- Subtraction and comparison of pointers is valid only if both are members of the same array. The subtraction of pointers gives the number of elements separating them.
- You can assign or compare a pointer with NULL .
The only exception to the above rules is that the address of the first memory block after the last element of an array follows pointer arithmetic.
Pointer and arrays exist together. These valid manipulations of pointers are immensely useful with arrays, which will be discussed in the next section.
1. Why pointers and arrays?
In C, pointers and arrays have quite a strong relationship.
The reason they should be discussed together is because what you can achieve with array notation ( arrayName[index] ) can also be achieved with pointers, but generally faster.
2. 1-D Arrays
Let us look at what happens when we write int myArray[5]; .
Five consecutive blocks of memory starting from myArray[0] to myArray[4] are created with garbage values in them. Each of the blocks is of size 4 bytes.
Thus, if the address of myArray[0] is 100 (say), the address of the rest of the blocks would be 104 , 108 , 112 , and 116 .
Have a look at the following code:
So, &prime , prime , and &prime[0] all give the same address, right? Well, wait and read because you are in for a surprise (and maybe some confusion).
Let's try to increment each of &prime , prime , and &prime[0] by 1.
Wait! How come &prime + 1 results in something different than the other two? And why are prime + 1 and &prime[0] + 1 still equal? Let's answer these questions.
prime and &prime[0] both point to the 0th element of the array prime . Thus, the name of an array is itself a pointer to the 0th element of the array .
Here, both point to the first element of size 4 bytes. When you add 1 to them, they now point to the 1st element in the array. Therefore this results in an increase in the address by 4.
&prime , on the other hand, is a pointer to an int array of size 5 . It stores the base address of the array prime[5] , which is equal to the address of the first element. However, an increase by 1 to it results in an address with an increase of 5 x 4 = 20 bytes.
In short, arrayName and &arrayName[0] point to the 0th element whereas &arrayName points to the whole array.
We can access the array elements using subscripted variables like this:
We can do the same using pointers which are always faster than using subscripts.
Both methods give the output:
Thus, &arrayName[i] and arrayName[i] are the same as arrayName + i and *(arrayName + i) , respectively.
3. 2-D Arrays
Two-dimensional arrays are an array of arrays.
Here, marks can be thought of as an array of 5 elements, each of which is a one-dimensional array containing 3 integers. Let us work through a series of programs to understand different subscripted expressions.
Like 1-D arrays, &marks points to the whole 2-D array, marks[5][3] . Thus, incrementing to it by 1 ( = 5 arrays X 3 integers each X 4 bytes = 60) results in an increment by 60 bytes.
If marks was a 1-D array, marks and &marks[0] would have pointed to the 0th element. For a 2-D array, elements are now 1-D arrays . Hence, marks and &marks[0] point to the 0th array (element), and the addition of 1 point to the 1st array.
And now comes the difference. For a 1-D array, marks[0] would give the value of the 0th element. An increment by 1 would increase the value by 1.
But, in a 2-D array, marks[0] points to the 0th element of the 0th array. Similarly, marks[1] points to the 0th element of the 1st array. An increment by 1 would point to the 1st element in the 1st array.
This is the new part. marks[i][j] gives the value of the jth element of the ith array. An increment to it changes the value stored at marks[i][j] . Now, let us try to write marks[i][j] in terms of pointers.
We know marks[i] + j would point to the ith element of the jth array from our previous discussion. Dereferencing it would mean the value at that address. Thus, marks[i][j] is the same as *(marks[i] + j) .
From our discussion on 1-D arrays, marks[i] is the same as *(marks + i) . Thus, marks[i][j] can be written as *(*(marks + i) + j) in terms of pointers.
Here is a summary of notations comparing 1-D and 2-D arrays.
Expression | 1-D Array | 2-D Array |
---|---|---|
&arrayName | points to the address of whole array adding 1 increases the address by 1 x sizeof(arrayName) | points to the address of whole array adding 1 increases the address by 1 x sizeof(arrayName) |
arrayName | points to the 0th element adding 1 increases the address to 1st element | points to the 0th element (array) adding 1 increases the address to 1st element (array) |
&arrayName[i] | points to the the ith element adding 1 increases the address to (i+1)th element | points to the ith element (array) adding 1 increases the address to the (i+1)th element (array) |
arrayName[i] | gives the value of the ith element adding 1 increases the value of the ith element | points to the 0th element of the ith array adding 1 increases the address to 1st element of the ith array |
arrayName[i][j] | Nothing | gives the value of the jth element of the ith array adding 1 increases the value of the jth element of the ith array |
Pointer Expression To Access The Elements | ( *( arrayName + i) + j) |
A string is a one-dimensional array of characters terminated by a null(\0) . When we write char name[] = "Srijan"; , each character occupies one byte of memory with the last one always being \0 .
Similar to the arrays we have seen, name and &name[0] points to the 0th character in the string, while &name points to the whole string. Also, name[i] can be written as *(name + i) .
A two-dimensional array of characters or an array of strings can also be accessed and manipulated as discussed before.
5. Array of Pointers
Like an array of int s and an array of char s, there is an array of pointers as well. Such an array would simply be a collection of addresses. Those addresses could point to individual variables or another array as well.
The syntax for declaring a pointer array is the following:
Following the operators precedence , the first example can be read as - example1 is an array( [] ) of 5 pointers to int . Similarly, example2 is an array of 8 pointers to char .
We can store the two-dimensional array to string top using a pointer array and save memory as well.
top will contain the base addresses of all the respective names. The base address of "Liverpool" will be stored in top[0] , "Man City" in top[1] , and so on.
In the earlier declaration, we required 90 bytes to store the names. Here, we only require ( 58 (sum of bytes of names) + 12 ( bytes required to store the address in the array) ) 70 bytes.
The manipulation of strings or integers becomes a lot easier when using an array of pointers.
If we try to put "Leicester" ahead of "Chelsea" , we just need to switch the values of top[3] and top[4] like below:
Without pointers, we would have to exchange every character of the strings, which would have taken more time. That's why strings are generally declared using pointers.
6. Pointer to Array
Like "pointer to int " or "pointer to char ", we have pointer to array as well. This pointer points to whole array rather than its elements.
Remember we discussed how &arrayName points to the whole array? Well, it is a pointer to array.
A pointer to array can be declared like this:
Notice the parentheses. Without them, these would be an array of pointers. The first example can be read as - ptr1 is a pointer to an array of 5 int (integers) .
When we dereference a pointer, it gives the value at that address. Similarly, by dereferencing a pointer to array, we get the array and the name of the array points to the base address. We can confirm that *pointerToGoals gives the array goals if we find its size.
If we dereference it again, we will get the value stored in that address. We can print all the elements using pointerToGoals .
Pointers and pointer to arrays are quite useful when paired up with functions. Coming up in the next section!
1. Call by Value vs Call by Reference
Have a look at the program below:
The function multiply() takes two int arguments and returns their product as int .
In the function call multiply(x,y) , we passed the value of x and y ( of main() ), which are actual arguments , to multiply() .
The values of the actual arguments are passed or copied to the formal arguments x and y ( of multiply() ). The x and y of multiply() are different from those of main() . This can be verified by printing their addresses.
Since we created stored values in a new location, it costs us memory. Wouldn't it be better if we could perform the same task without wasting space?
Call by reference helps us achieve this. We pass the address or reference of the variables to the function which does not create a copy. Using the dereferencing operator * , we can access the value stored at those addresses.
We can rewrite the above program using call by reference as well.
2. Pointers as Function Arguments
In this section, we will look at various programs where we give int , char , arrays and strings as arguments using pointers.
We created four functions, add() , subtract() , multiply() and divide() to perform arithmetic operations on the two numbers a and b .
The address of a and b was passed to the functions. Inside the function using * we accessed the values and printed the result.
Similarly, we can give arrays as arguments using a pointer to its first element.
Since the name of an array itself is a pointer to the first element, we send that as an argument to the function greatestOfAll() . In the function, we traverse through the array using loop and pointer.
Here, we pass in the string name to wish() using a pointer and print the message.
3. Pointers as Function Return
The function multiply() takes two pointers to int . It returns a pointer to int as well which stores the address where the product is stored.
It is very easy to think that the output would be 15. But it is not!
When multiply() is called, the execution of main() pauses and memory is now allocated for the execution of multiply() . After its execution is completed, the memory allocated to multiply() is deallocated.
Therefore, though c ( local to main() ) stores the address of the product, the data there is not guaranteed since that memory has been deallocated.
So does that mean pointers cannot be returned by a function? No!
We can do two things. Either store the address in the heap or global section or declare the variable to be static so that their values persist.
Static variables can simply be created by using the keyword static before data type while declaring the variable.
To store addresses in heap, we can use library functions malloc() and calloc() which allocate memory dynamically.
The following programs will explain both the methods. Both methods return the output as 15.
4. Pointer to Function
Like pointer to different data types, we also have a pointer to function as well.
A pointer to function or function pointer stores the address of the function. Though it doesn't point to any data. It points to the first instruction in the function.
The syntax for declaring a pointer to function is:
The below example will make it clearer.
The declaration for the pointer p to function multiply() can be read as ( following operator precedence ) - p is a pointer to function with two int eger pointers ( or two pointers to int ) as parameters and returning a pointer to int .
Since the name of the function is also a pointer to the function, the use of & is not necessary. Also removing * from the function call doesn't affect the program.
5. Array of Pointers to Functions
We have already seen how to create an array of pointers to int , char , and so on. Similarly, we can create an array of pointers to function.
In this array, every element will store an address of a function, where all the functions are of the same type. That is, they have the same type and number of parameters and return types.
We will modify a program discussed earlier in this section. We will store the addresses of add() , subtract() , multiply() and divide() in an array make a function call through subscript.
The declaration here can be read as - p is an array of pointer to functions with two float pointers as parameters and returning void .
6. Pointer to Function as an Argument
Like any other pointer, function pointers can also be passed to another function, therefore known as a callback function or called function . The function to which it is passed is known as a calling function .
A better way to understand would be to look at qsort() , which is an inbuilt function in C. It is used to sort an array of integers, strings, structures, and so on. The declaration for qsort() is:
qsort() takes four arguments:
- a void pointer to the start of an array
- number of elements
- size of each element
- a function pointer that takes in two void pointers as arguments and returns an int
The function pointer points to a comparison function that returns an integer that is greater than, equal to, or less than zero if the first argument is respectively greater than, equal to, or less than the second argument.
The following program showcases its usage:
Since a function name is itself a pointer, we can write compareIntegers as the fourth argument.
1. Pointer to Structure
Like integer pointers, array pointers, and function pointers, we have pointer to structures or structure pointers as well.
Here, we have declared a pointer ptrStudent of type struct records . We have assigned the address of student to ptrStudent .
ptrStudent stores the base address of student , which is the base address of the first member of the structure. Incrementing by 1 would increase the address by sizeof(student) bytes.
We can access the members of student using ptrStudent in two ways. Using our old friend * or using -> ( infix or arrow operator ).
With * , we will continue to use the . ( dot operator) whereas with -> we won't need the dot operator.
Similarly, we can access and modify other members as well. Note that the brackets are necessary while using * since the dot operator( . ) has higher precedence over * .
2. Array Of Structure
We can create an array of type struct records and use a pointer to access the elements and their members.
Note that ptrStudent1 is a pointer to student[0] whereas ptrStudent2 is a pointer to the whole array of 10 struct records . Adding 1 to ptrStudent1 would point to student[1] .
We can use ptrStudent1 with a loop to traverse through the elements and their members.
3. Pointer to Structure as an Argument
We can also pass the address of a structure variable to a function.
Note that the structure struct records is declared outside main() . This is to ensure that it is available globally and printRecords() can use it.
If the structure is defined inside main() , its scope will be limited to main() . Also structure must be declared before the function declaration as well.
Like structures, we can have pointers to unions and can access members using the arrow operator ( -> ).
So far we have looked at pointer to various primitive data types, arrays, strings, functions, structures, and unions.
The automatic question that comes to the mind is – what about pointer to pointer?
Well, good news for you! They too exist.
To store the address of int variable var , we have the pointer to int ptr_var . We would need another pointer to store the address of ptr_var .
Since ptr_var is of type int * , to store its address we would have to create a pointer to int * . The code below shows how this can be done.
We can use ptr_ptrvar to access the address of ptr_var and use double dereferencing to access var.
It is not required to use brackets when dereferencing ptr_ptrvar . But it is a good practice to use them. We can create another pointer ptr_ptrptrvar , which will store the address of ptr_ptrvar .
Since ptr_ptrvar is of type int** , the declaration for ptr_ptrptrvar will be
We can again access ptr_ptrvar , ptr_var and var using ptr_ptrptrvar .
If we change the value at any of the pointer(s) using ptr_ptrptrvar or ptr_ptrvar , the pointer(s) will stop pointing to the variable.
Phew! Yeah, we're finished. We started from pointers and ended with pointers (in a way). Don't they say that the curve of learning is a circle!
Try to recap all the sub-topics that you read. If you can recollect them, well done! Read the ones you can't remember again.
This article is done, but you shouldn't be done with pointers. Play with them. Next, you can look into Dynamic Memory Allocation to get to know pointers better .
Stay home, stay safe.
If you read this far, thank the author to show them you care. Say Thanks
Learn to code for free. freeCodeCamp's open source curriculum has helped more than 40,000 people get jobs as developers. Get started
C Functions
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:
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.
Dereference
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:
- When used in declaration ( int* ptr ), it creates a pointer variable .
- When not used in declaration, it act as a dereference operator .
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.
C Exercises
Test yourself with exercises.
Create a pointer variable called ptr , that points to the int variable myAge:
Start the Exercise
COLOR PICKER
Contact Sales
If you want to use W3Schools services as an educational institution, team or enterprise, send us an e-mail: [email protected]
Report Error
If you want to report an error, or if you want to make a suggestion, send us an e-mail: [email protected]
Top Tutorials
Top references, top examples, get certified.
IMAGES
VIDEO
COMMENTS
You've created a pointer to "anywhere you want"—which could be the address of some other variable, or the middle of your code, or some memory that isn't mapped at all. You need to create an int variable somewhere in memory for the int * variable to point at.
The use of pointers allows low-level memory access, dynamic memory allocation, and many other functionality in C. In this article, we will discuss C pointers in detail, their types, uses, advantages, and disadvantages with examples.
Assignment operators are used to assign values to the identifiers. There are multiple shorthand operations available. A table is given below showing the actual assignment statement with its shorthand statement. Examples: *a=10 *b+=20 *z=3.5 *s=4.56743. Let us understand assignment operator in better way with the help of code given below: C
To initialize a pointer to null or to assign the null value to an existing pointer, a null pointer constant (NULL, or any other integer constant with the value zero) may be used. static initialization also initializes pointers to their null values.
Assigning addresses to Pointers. Let's take an example. int* pc, c; c = 5; pc = &c; Here, 5 is assigned to the c variable. And, the address of c is assigned to the pc pointer. Get Value of Thing Pointed by Pointers. To get the value of the thing pointed by the pointers, we use the * operator.
CHAPTER 1: What is a pointer? One of the things beginners in C find most difficult to understand is the concept of pointers. The purpose of this document is to provide an introduction to pointers and their use to these beginners.
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.
By Srijan. 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.
using the NULL macro, as with an assignment statement such as ptr = NULL, guarantees that the pointer has become a null pointer. Similarly, just as one can test for an integer value of zero, as in if(k == 0), we can test for a null pointer using if (ptr == NULL). But, back to using our new variable ptr. Suppose now that we want to store in ptr the
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: