C Language: Elementary Pointers

memory and address

In the computer, all calculation data will be temporarily stored in the memory, when we needWhen calling a certain part of memory, pointers are used. We can compare the memory of a computer to a row of houses on a street, each house will contain a certain amount of data, and can be identified by a room number; first of all, this analogy has certain limitations, but it is for beginners to understand , is enough; there is no need to expand here; how big is this house? The memory in the computer is composed of hundreds of millions of bits (bit), so the house storesbyteas the unit;
insert image description here
assuming that the above grid is regarded as a byte, then each grid can store 8 bits; each location in the memory contains some values; eachByte location with addressto identify; here, the address is hexadecimal; in order to store larger values, we put two or more bytes together as a larger memory unit. In our system, addresses are addressed by bytes, the short type occupies 2 bytes, and the double type occupies 8 bytes; here, each location in memory is identified by a unique address; when we want to refer to a When data, it is necessary to call to a certain memory, we find the location through the address, andThe pointer is to remember this addressof;

pointer

Therefore, a pointer is the number of the smallest unit in memory, that is, the address. The pointer in spoken language usually refers to a pointer variable.
like:

#include <stdio.h>
int main()
{
    
    
 int a = 10;
 int *p = &a;
  //a变量占用4个字节的空间,这里是将a的4个字节的第一个字节的地址存放在p变量中,p就是一个之指针变量。
 return 0;
}

For the variable a, a space will be opened in the memory, for the variable a, we need to get its address, we can use the & operator.

insert image description here
Generally speaking, on a 32-bit machine, the size of a pointer variable is 4 bytes, and on a 64-bit machine, 8 bytes.

value and type

First look at the following code:

#include <stdio.h>
int main()
{
    
    
 int a=112,b=1;
 float c=3.14;
 int* d=&a;
 int* e=&c;
 return 0;
}

Variable means:
insert image description here

We know that a is of integer storage type. For a to take the address, dereferencing it is itself. However, c is of floating point type. After dereferencing its address, it is an integer; the answer isThis variable contains a series of 0 or 1 bits, for whether it is an integer type or a floating point type, depending on itsarithmetic instruction; So, you can't simply check a value's bits to determine its type;

Then look at the following code:

char  *pc = NULL;
int   *pi = NULL;
short *ps = NULL;
long  *pl = NULL;
float *pf = NULL;
double *pd = NULL

The pointer definition type is type+*;

For different types of pointers, it is to store the address of the corresponding type; for example, a char type pointer stores the address of a char variable. What is the difference between different types of pointers?

#include <stdio.h>
int main()
{
    
    
 int n = 10;
 char *pc = (char*)&n;//括号是强制转换
 int *pi = &n;
 
 printf("%p\n", &n);
 printf("%p\n", pc);
 printf("%p\n", pc+1);
 printf("%p\n", pi);
 printf("%p\n", pi+1);
 return  0;
}

Result:
insert image description here
We can see that for the char type and int type to take the address, it is the address on the n memory.
insert image description here
After adding 1 to the address,
insert image description here
the summary:The type of the pointer determines how far the pointer takes one step forward or backward (distance)

at last:

//演示实例
#include <stdio.h>
int main()
{
    
    
 int n = 0x11223344;//表示地址位置
 char *pc = (char *)&n;
 int *pi = &n;
 *pc = 0;  
 *pi = 0; 
 return 0;
}

Initial address:

0x11223344

After pc is dereferenced:

0x11223300

After pi is dereferenced:

0x00000000

Here, the computer useslittle endianstorage method. In the computer, the data must be read and written from the low address of the memory to the high address in turn, and the little endian storage will store the low bit to the low address, and the high address to the high address, that is, 0x44332211 when storing. Therefore, after pc is dereferenced, because it is of char type and its size is only one byte, it only assigns a value of 0 to the memory size of one byte, which is 44; while pi is of type int and its size is 4 bytes, so when When it is dereferenced, it makes the entire address 0.

Summarize:
The type of the pointer determines how much authority you have when dereferencing the pointer(Can operate several bytes).

pointer arithmetic

pointer ± integer

#define N_VALUES 5
float values[N_VALUES];
float *vp;
//指针+-整数;指针的关系运算
int main()
{
    
    
    for (vp = &values[0]; vp < &values[N_VALUES];)
{
    
    
     *vp++ = 0;
}
 }

Here, values ​​represents an array, and vp is a floating-point pointer. In the for loop, vp is assigned the address of the first element of value. Whenever it is +1, the address will continue to move by 4 bytes until it matches values [5] The address is the same, the loop stops;

insert image description here

pointer-pointer

int my_strlen(char *s)
{
    
    
       char *p = s;
       while(*p != '\0' )
              p++;
       return p-s;
}

This is a function to find the length of a string. Suppose there is a string "abcdef", the pointer is located at the address of the initial position a, and the p pointer represents the address of the initial position. After the loop, p goes to the position of '\0', and finally The subtraction returns, which is the string length 6.

insert image description here
Of course, a conclusion is given here: the pointer-the pointer returns how many elements there are in between, that is, the address difference/integer byte. Generally, it can be applied to strings and arrays. The above example cannot be seen because it is of char type. An example is given below:

#include<stdio.h>
int main()
{
    
    
    int arr[10];
    printf("%d",&arr[10]-&arr[0]);
  
    return 0;
}

Result: 10
Of course the pointer - the prerequisite for the pointer is to point to the same space.

pointers and arrays

first look at the example

#include <stdio.h>
int main()
{
    
    
 int arr[10] = {
    
    1,2,3,4,5,6,7,8,9,0};
    printf("%p\n", arr);
    printf("%p\n", &arr[0]);
    return 0;
}

insert image description here
As can be seenThe arr address is the address of the first element, except for two cases of course. (There are explanations in the chapter on arrays).
Since arr can be used as a pointer, there are the following operations:

#include <stdio.h>
int main()
{
    
    
    int arr[] = {
    
    1,2,3,4,5,6,7,8,9,0};
    int *p = arr; //指针存放数组首元素的地址
    int sz = sizeof(arr)/sizeof(arr[0]);
    for(i=0; i<sz; i++)
   {
    
    
        printf("&arr[%d] = %p   <====> p+%d = %p\n", i, &arr[i], i, p+i);
   }
    return 0;
}

insert image description here
It can be seen that p+i actually calculates the address of the subscript i of the array arr, so we can access the array elements through pointers.

int main()
{
    
    
 int arr[] = {
    
     1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
 int *p = arr; //指针存放数组首元素的地址
 int sz = sizeof(arr) / sizeof(arr[0]);
 int i = 0;
 for (i = 0; i<sz; i++)
 {
    
    
 printf("%d ", *(p + i));
 }
 return 0;
}

insert image description here

secondary pointer

A pointer variable is also a variable, and a variable has an address. likeint *p is a pointer variable, then its address is stored by the secondary pointer

#include<stdio.h>
int main()
{
    
    
    int a=10;
    int* p=&a;
    int** pp=&p;
    return 0;
}

insert image description here

It can be seen that a is an integer variable, p is a first-level pointer, which is 10 after dereferencing, pp is a second-level pointer, *pp indicates the address of the first-level pointer, and **pp indicates the content pointed to by the first-level pointer.

insert image description here

wild pointer

wild pointer isThe location pointed by the pointer is unknown(Random, incorrect, not clearly limited) If the pointer variable is not initialized at the time of definition, its value is random, and the value of the pointer variable is the address of other variables, which means that the pointer points to an address is uncertain variable, to dereference at this time is to access an indeterminate address, so the result is unknowable.
Therefore, we have to avoid the situation of wild pointers.
1.Create a pointer and remember to initialize, when you don’t know where to point, point to NULL directly, you can’t ignore it;
2.cannot make the access location out of bounds, such as an array has 10 elements, and you access the position with subscript 10, which exceeds the range of the array length, this is an out-of-bounds access.
3.The pointer points to the space to release, and set NULL in time
4. Avoid returning the address of a local variable, the address pointed to by the pointer of the local variable will be destroyed after the function is finished. When returning to the main function, the main function pointer cannot receive any address.
5.Check the validity of the pointer before using it

Guess you like

Origin blog.csdn.net/m0_74068921/article/details/130874325