Elementary C language-pointer

1. Three pointers in a row

1.1 What is a pointer?

In computer science,A pointer is an object in a programming language. Using an address, its value directly points to a value stored in another place in the computer memory.. Since the required variable unit can be found through the address, it can be said that the address points to the variable unit. Therefore, the visualized address is called a "pointer". It means that the memory unit with its address can be found through it.

1.2 Why use pointers?

Improve search efficiency

Summary: A pointer is an address, and a pointer variable is a variable used to store the address of a memory unit. The memory unit with its address can be found through the pointer.

1.3 How to use pointers?

Give a chestnut:

#include <stdio.h>
int main()
{
    
    
    int a = 10;//在内存中开辟一块空间
    int *p = &a;//这里我们对变量a,取出它的地址,可以使用&操作符。
               //将a的地址存放在p变量中,p就是一个之指针变量。
    return 0;
}

Here you need to know how addressing is done in the computer?

For a 32-bit machine, assuming there are 32 address lines, then assuming that each address line is addressing to generate an electrical signal positive/negative (1 or
0),
then the address generated by the 32 address lines will be:
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000001

11111111 11111111 11111111 11111111

There are 2 to 32 addresses here.
Each address identifies a byte, then we can get:
2 32 B yte = 2 32/1024 KB = 2 32/1024/1024 MB = 2 32/1024/1024/1024 GB = 4 GB \begin{aligned } 2^{32}Byte \\ &=2^{32}/1024KB \\ &=2^{32}/1024/1024MB \\ &=2^{32}/1024/1024/1024GB\\ &= 4GB \end{aligned}232Byte=232/1024KB=232/1024/1024MB=232/1024/1024/1024GB=4GB
That is, 4G is idle for addressing .
In the same way, for a 64-bit machine, if you give 64 address lines, you can get:
2 64 B yte = 2 64/1024 KB = 2 64/1024/1024 MB = 2 64/1024/1024/1024 GB \begin {aligned} 2^{64}Byte \\ &=2^{64}/1024KB \\ &=2^{64}/1024/1024MB \\ &=2^{64}/1024/1024/1024GB\\ \end{aligned}264Byte=264/1024KB=264/1024/1024MB=264/1024/1024/1024GB
For general computers, the 64-bit address bus will not be fully used, and usually only 8G of idleness is used for addressing .
Here we understand:

On a 32-bit machine, the address is a binary sequence of 32 0s or 1s, and the address must be stored in 4 bytes, so the size of a pointer variable should be 4 bytes .
So if on a 64-bit machine, if there are 64 address lines, the size of a pointer variable is 8 bytes , and then an address can be stored.

Summary:
Pointers are used to store addresses, and addresses uniquely indicate a piece of address space.
The size of the pointer is 4 bytes on a 32-bit platform and 8 bytes on a 64-bit platform.

Two, pointers and pointer types

2.1 Pointer types

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

Pointer definition: type + *
char* type pointer is to store the address of char type variable. The short* type pointer is to store the address of the short type variable. The int* type pointer is to store the address of the int type variable.
Give a chestnut to understand the definition of pointer types

#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", pc-1);
    printf("%p\n", pi);
    printf("%p\n", pi+1);
    printf("%p\n", pi-1);
	return 0;
}

result
Insert picture description here

It can be seen that the pointer variable is 4 bytes under the 32-bit operating system, and the pointer variable is 8 bytes under the 64-bit operating system.

Summary: Adding 1 to a pointer is actually adding the size of the type pointed to by the pointer. The type of the pointer determines how far (distance) the pointer can go one step forward or backward.

2.2 Pointer dereference

#include<stdio.h>

int main()
{
    
    
	//2.2指针解引用
	int n = 0x11223344;
	char *pc = (char *)&n;
	int *pi = &n;
	*pc = 0;
	*pi = 0;
	 return 0;
}

Insert picture description here
Insert picture description here
Insert picture description here

It can be seen from the debugging result graph that when the pointer variable type is char type, the pointer dereference can only operate on one byte, and when the pointer variable type is int type, the pointer dereference can operate four words at a time. Section.

to sum up:

The type of the pointer determines how much authority it has when dereferencing the pointer, that is, how many bytes can be manipulated.

Three, wild pointer

3.1 Concept

A wild pointer means that the position the pointer points to is unknowable (random, incorrect, and not explicitly limited)

3.2 Causes of wild pointers

3.2.1 The pointer is not initialized

#include <stdio.h>
int main()
{
    
       
    int *p;//局部变量指针未初始化,默认为随机值
    *p = 20;
    return 0;
}

3.2.2 Pointer out-of-bounds access

#include <stdio.h>
int main()
{
    
    
    int arr[10] = {
    
    0};
    int *p = arr;
    int i = 0;
    for(i=0; i<=11; i++)
    {
    
    
        //当指针指向的范围超出数组arr的范围时,p就是野指针
        *(p++) = i;
    }
    return 0;
}

3.2.3 Freeing the space pointed to by the pointer

You can see the third part of the following blog,
05-C language advancement-dynamic memory management

3.3 How to avoid wild pointers

  • Pointer initialization
  • Watch out for pointers out of bounds
  • The pointer points to the space to be set to NULL when the space is released
  • Check the validity of the pointer before use

Four, pointer arithmetic

4.1 Pointer addition and subtraction integer

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

Adding 1 to the pointer is actually adding the size of the type pointed to by the pointer. The type of the pointer determines how far (distance) the pointer can go one step forward or backward.
The standard stipulates
that the pointer to the array element is allowed to be compared with the pointer to the memory location after the last element of the array, but it is not allowed to be compared with the pointer to the memory location before the first element.

4.2 Pointer minus pointer

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

Insert picture description here
to sum up

The subtraction of two pointers represents the number of elements experienced by the two pointers.

  • The element type is indicated by a pointer
  • Two pointers must point to the same piece of memory to make sense (usually the same array, string)

4.3 Relational operations of pointers

for(vp = &values[N_VALUES-1]; vp >= &values[0];vp--)
{
    
    
    *vp = 0;
}

Pointers can be compared in size, usually the pointers to be taught need to point to the same memory (same array, string).
standard regulation:

The pointer to the array element is allowed to be compared with the pointer to the memory location after the last element of the array, but it is not allowed to compare with the pointer to the memory location before the first element.

In fact, the task can be successfully completed on most compilers, but we should still avoid writing this way, because the standard does not guarantee that
it is feasible.

Five, pointers and arrays

First of all, it is clear that pointers and arrays have nothing to do with each other.

#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 picture description here
As can be seen from the above figure, the array name and the address of the first element of the array are the same.
Summary:

The array name represents the address of the first element of the array

We can use pointers to access the array, for 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]);

	int *p = arr;	//指针变量p存放的数组首元素的地址
	int arrSize = sizeof(arr) / sizeof(arr[0]);
	for (int i = 0; i < arrSize; i++)
	{
    
    
		printf("%d ", p[i]);
		printf("%d ", *(p+i));
		printf("%d ", arr[i]);
		printf("%d \n", *(arr+i));
	}
	return 0;
}

Insert picture description here
It can be seen from the results that we actually calculate p+i is the array arr and the following table is the address of i

Six, secondary pointer

The pointer variable is a variable, then the variable will have an address, and the secondary pointer is usedStore pointer variable addressof.

It can be understood through a picture
Insert picture description here

The address of a is stored in pa, and the address of
pa is stored in ppa. Pa is a first-level pointer, and ppa is a second-level pointer.

For secondary pointer arithmetic

	int a = 10;

	int *pa = &a;
	printf("%d\n", *pa);
	int **ppa = &pa;

	int b = 20;
	*ppa = &b;		//等价于pa=&b
	printf("%d\n", *pa);
	**ppa = 30;	//	等价于*pa=30 等价于b=30
	printf("%d\n", *pa);
	printf("%d\n", b);

result
Insert picture description here

There are two steps to the operation of **ppa here

  • The first one dereferences *ppa and finds the address of pa, so the address of b is assigned to pa
  • The second dereference **ppa, first find pa through *ppa, and then dereference pa: *pa, find b

Guess you like

Origin blog.csdn.net/qq_40076022/article/details/111289771