Pointers, references, and values

What is a pointer?What is a memory address?What is the value of a pointer?A pointer is a variable that stores the address of a computer's memory.In this tutorial "quote" means the computer memory address.Reading data from the memory pointed to by the pointer is called the value of the pointer.A pointer can point to a specific type of variable address,For example, int, long, and double. Pointers can also be void, null, and uninitialized.This article explores all of these pointer types.

Depending on where it appears,The operator * can be used to declare a pointer variable,Can also be used as a pointer value.When used to declare a variable,* Indicates that a pointer is declared here.In other cases, * is used to indicate the value of the pointer.

&Is an address operator,Used to reference a memory address.By using the&operator before a variable name, we can get the memory address of the variable.

//declare an int pointer
int * ptr;
//declare an int value
int val=1;
//assign a pointer to a reference to an int value
ptr =&val;
//Take the value of the pointer,Print the contents stored in the pointer address
int deref=* ptr;
printf ("%d \ n", deref);

In line 2, we declare an int pointer with the * operator. Then we declare an int variable and assign it a value of 1. Then we initialize our int pointer with the address of the int variable. Next, take the value of the int pointer,Initialize the int pointer with the memory address of the variable. Finally, we print out the value of the variable,The content is 1.

&Val in line 6 is a reference.After the val variable is declared and initialized,By using the address operator&before the variable name, we can directly reference the memory address of the variable.

On line 8, we again use the * operator to take the value of the pointer,The data in the memory address pointed to by the pointer can be obtained directly.Because the type of the pointer declaration is int, the value obtained is the int value stored in the memory address pointed by the pointer.

The relationship between pointers, references, and values ​​can be compared here to envelopes, email addresses, and houses.A pointer is like an envelope,We can fill in the mailing address on it.A reference (address) is like an email address,It is the actual address.The value is like the house corresponding to the address.We can erase the address on the envelope,Write another address we want,But this behavior has no effect on the house.

void pointers, null pointers, and uninitialized pointers

A pointer can be declared as void, such as void * x. A pointer can be assigned the value null. After a pointer variable is declared but not assigned,Called uninitialized pointer.

int * uninit;//int pointer is not initialized
int * nullptr=null;//initialized to null
void * vptr;//void pointer is not initialized
int val=1;
int * iptr;
int * castptr;
//void type can store any type of pointer or reference
iptr =&val;
printf ("iptr =%p, vptr =%p \ n", iptr, vptr);
//By displaying the conversion,We can turn a void pointer into
//int pointer and take value
castptr=(int *) vptr;
printf ("* castptr =%d \ n", * castptr);
//print null and uninitialized pointers
printf ("uninit =%p, nullptr =%p \ n", uninit, nullptr);
//don't know what return value you will get,Will it be a random spam address?
//printf ("* nullptr =%d \ n", nullptr);
//a segfault will be generated here
//printf ("* nullptr =%d \ n", nullptr);

Execute the above code,You will get output similar to the following corresponding to different memory addresses.

iptr=0x7fff94b89c6c, vptr=0x7fff94b89c6c
* castptr=1
uninit=0x7fff94b89d50, nullptr=(nil)

In line 1, we declare an uninitialized int pointer. All pointers are uninitialized before being assigned a null, a reference (address), or another pointer.In line 2 we declare a null pointer. Line 3 declares a void pointer. Lines 4 to 6 declare an int value and several int pointers.

In lines 9 to 11, we assign an int pointer to a reference and assign an int pointer to a void pointer. A void pointer can hold various other pointer types.Most of the time they are used to store data structures.It can be noticed thatIn line 11, we print the addresses of the int and void pointers.They now point to the same memory address.All pointers store memory addresses.Their type only works when taking values.

In lines 15 to 16, we convert the void pointer to an int pointer castptr. Please note that the conversion needs to be displayed here.Although the C language does not require explicit conversion,But this will increase the readability of the code.Then we take the value of the castptr pointer,The value is 1.

Line 19 is very interesting,Print uninitialized pointers and null pointers here. It is worth noting thatUninitialized pointers have memory addresses.And it's a spam address.I don't know what this memory address points to.That's why you don't take values ​​from uninitialized pointers.The best case is that you get garbage addresses. Next you need to debug the program.In the worst case, the program will crash.

The null pointer is initialized to o. null is a special address,A null-assigned pointer points to an address of 0 instead of a random address.Only valid if you plan to use this address.Don't take values ​​for null addresses,Otherwise, a segmentation fault will occur.

Pointers and arrays

C language array represents a continuous memory space,Used to store multiple specific types of objects.to the opposite,Pointers are used to store a single memory address.Arrays and pointers are not the same structure and therefore cannot be converted to each other.The array variable points to the memory address of the first element of the array.

An array variable is a constant.Even if the pointer variable points to the same address or a different array,You cannot assign pointers to array variables.It is also not possible to assign an array variable to another array.However, you can assign an array variable to a pointer,This seems puzzling.When assigning an array variable to a pointer,The pointer is actually the address of the first element of the array.

int myarray [4]={1,2,3,0};
int * ptr=myarray;
printf ("* ptr =%d \ n", * ptr);
//array variables are constants,Cannot do the following assignment
//myarray=& myarray2 [0]

Line 1 initializes an int array, and line 2 initializes an int pointer with an array variable. Since the array variable is actually the address of the first element,So we can assign this address to a pointer.This assignment has the same effect as int * ptr =&myarray [0],Explicitly assigns the address of the first element of the array to a ptr reference. It should be noted here thatHere the pointer needs to be consistent with the element type of the array,Unless the pointer type is void.

Pointers and structures

Just like an array,The pointer to the structure stores the memory address of the first element of the structure.As with array pointers,The pointer of the structure must be declared consistent with the structure type.Or declared as void.

struct person {
 int age;
 char * name;
struct person first;
struct person * ptr;
char * fullname="full name";
ptr =&first;
printf ("age =%d, name =%s \ n", first.age, ptr->name);

Lines 1 to 6 declare a person structure, a variable that points to a person structure and a pointer to the person structure.The eighth line is assigned an int value. In lines 9 to 10 we declare a char pointer and assign it to a char array and assign it to the struct name member. In line 11, we assign a person structure reference to the structure variable.

On line 13 we print the age and name of the structure instance. Need to pay attention to two different symbols here,"." And "->". Structure instances can access the age variable by using the "." Symbol. For pointers to struct instances,We can access the name variable via the "->" symbol. You can also access the name variable via (* ptr) .name.

to sum up

Hope this short overview helps to understand the different pointer types.We will explore other types of pointers and advanced usage in subsequent blog posts,Like function pointers.