[Fundação da linguagem C 11 - ponteiro (2)]


prefácio

Este artigo continua o conteúdo anterior e continua a aprender sobre pontos de conhecimento relacionados a ponteiros.


4. Operação do ponteiro

  • ponteiro ± inteiro
  • ponteiro - ponteiro
  • Operações Relacionais em Ponteiros

4.1 Ponteiro ± Inteiro

#define VALUE 5
int main()
{
    
    
	float values[VALUE];
	float *vp;
	//指针+-指针,关系运算
	for (vp = &values[0]; vp < &values[VALUE];)
	{
    
    
		*vp++ = 0;//通过这样完成初始化
	}
	for (int i = 0; i < VALUE; i++)
	{
    
    
		printf("%d ", values[i]);
	}
	return 0;
}

insira a descrição da imagem aqui

4.2 Ponteiro-Ponteiro

int main()
{
    
    
	int arr[10] = {
    
     0 };
	printf("%d\n", &arr[9] - &arr[0]);//得到元素的个数
	printf("%d\n", sizeof(arr)/sizeof(arr[0]));//计算元素个数
	int* p0 = &arr[0];
	int* p9 = &arr[9];
	printf("%d\n", (p9 - p0));//得到元素的个数
	return 0;
}

Ao subtrair os endereços do primeiro e do último elemento do array, obtém-se o número de elementos do array.

-int* indica que o endereço apontado pelo ponteiro, o tipo de dado armazenado é um inteiro, ocupando 4 bytes

  • O endereço do elemento array +1 é para encontrar o endereço do próximo elemento, e ele irá mover 4 bytes
    insira a descrição da imagem aqui
    . Esse fenômeno é mais claramente observado através da depuração. Cada elemento do array int ocupa quatro bytes:
  • &arr[0]: 0x005cf7f8
  • &arr[0]+1: 0x005cf7fc, o endereço é movido em 1 bit, ou seja, o ponteiro int* é movido em 1 bit e os bytes são aumentados em 4.
    insira a descrição da imagem aqui
    Pré-condição: Ambos os ponteiros devem apontar para o mesmo espaço :
char ch[5];
int arr[6];
%arr[4]-&ch[3];//错误的

O artigo anterior introduziu o método de comprimento de string de duas maneiras:

  • ciclo
  • recursão

O terceiro método é introduzido aqui, ponteiro

int mylen(char* pa)//传参是数组首元素的地址
{
    
    
	char* p = pa;//首元素地址
	while (*pa)//元素不是‘0’
	{
    
    
		pa++;//通过地址访问字符串
	}
	//结尾字符0的地址减首元素地址
	return pa - p;//指针相减是元素的个数
}
int main()
{
    
    
	char arr[] = "abcdef";
	int len = mylen(arr);
	printf("%d", len);
	return 0;
}

4.3 Operações relacionais em ponteiros

O padrão afirma: Um ponteiro para um elemento de array pode comparar com um ponteiro para um local de memória após o último elemento do array, mas a comparação com um
ponteiro para um local de memória antes do primeiro elemento não é permitida

int main()
{
    
    
	//
	for (vp = &values[5]; vp > &values[0];)
	{
    
    
		*--vp = 0;
	}
	for (vp = &values[5-1]; vp >= &values[0];vp--)//不允许
	//地址会指向首元素前面的地址,这是不允许的
	{
    
    
		*vp = 0;
	}
	return 0;
}

5. Ponteiros e matrizes

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存放的是数组首元素的地址
	return 0;
}

O nome do array é o mesmo que o endereço do primeiro elemento do array. O nome do array representa o endereço do primeiro elemento do array. (Exceto para 2 casos, os artigos da série de arrays são apresentados em detalhes)
insira a descrição da imagem aqui
Como o nome do array pode ser armazenado em um ponteiro como um endereço, é possível usar o ponteiro para acessar um

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(int i=0; i<sz; i++)
	{
    
    
		printf("&arr[%d] = %p <====> p+%d = %p\n", i, &arr[i], i, p+i);
	}
	return 0;
}

insira a descrição da imagem aqui
Observe a figura acima, então p+i realmente calcula o endereço do elemento cujo índice é i no array arr. Então você pode acessar a matriz diretamente através do ponteiro:

int main()
{
    
    
	int arr[10] = {
    
     1,2,3,4,5,6,7,8,9,10 };
	int* p = arr;
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (int i = 0; i < sz; i++)
	{
    
    
		printf("%d ",*(p + i));
	}
	printf("\n");
	for (int i = 0; i < sz; i++)
	{
    
    
		printf("%d ", *(p++));
	}
	printf("\n");
	for (int i = 0; i < sz; i++)
	{
    
    
		printf("%d ", arr[i]);
	}
	return 0;
}

insira a descrição da imagem aqui

6. Ponteiro secundário

Uma variável ponteiro também é uma variável, e uma variável tem um endereço Onde o endereço da variável ponteiro é armazenado? Este é o ponteiro secundário

int main()
{
    
    
	int a = 10;
	int* pa = &a;
	int** ppa = &pa;
	return 0;
}
  • O endereço de a é armazenado no ponteiro pa, que é um ponteiro de primeiro nível
  • O endereço de pa é armazenado em ppa, que é um ponteiro secundário
    insira a descrição da imagem aqui

As operações para ponteiros secundários são:

  • *ppa cancela a referência do endereço em ppa para encontrar pa, e *ppa realmente acessa pa.
int b = 20;
*ppa = &b;//等价于 pa = &b;
  • **ppa primeiro encontra pa até *ppa, e então desreferencia pa: *pa, que encontra um
**ppa = 30;
//等价于*pa = 30;
//等价于a = 30;

7. Matriz de ponteiros

Um array de ponteiros é um ponteiro ou um array?

  • é uma matriz. é uma matriz de ponteiros

Nos artigos da série de matrizes, matrizes de inteiros, matrizes de caracteres foram introduzidas:

int arr1[5];//占用20个字节
char arr2[5];//占用5个字节

insira a descrição da imagem aqui

7.1 Exemplo 1

matriz de ponteiros:

int main()
{
    
    
	int data1[] = {
    
     1,2,3,4,5 };
	int data2[] = {
    
     2,3,4,5,6 };
	int data3[] = {
    
     3,4,5,6,7 };
	//看成二维数组
	int* arr[3] = {
    
     data1,data2,data3 };
	for (int i = 0; i < 3; i++)
	{
    
    
		for (int j = 0; j < 5; j++)
		{
    
    //[]是操作符
			printf("%d ", arr[i][j]);//不需要解引用
		}
		printf("\n");
	}
	   
	return 0;
}

arr3 é um array com cinco elementos, cada elemento é um ponteiro inteiro, que é um endereço:

  • arr[0], que é o elemento data1, é uma variável de ponteiro, e ele próprio é o nome do array de um array unidimensional { 1,2,3,4,5 }, representando o endereço do primeiro elemento
  • arr[1], o elemento data2, é uma variável de ponteiro, que também é o nome do array de um array unidimensional { 2,3,4,5,6 }, representando o endereço do primeiro elemento
  • arr[2], que é o elemento data3, é uma variável de ponteiro, e ele próprio é o nome do array unidimensional { 3,4,5,6,7 }, representando o endereço do primeiro elemento

insira a descrição da imagem aqui
insira a descrição da imagem aqui
Também pode ser encontrado depurando:

  • O primeiro elemento do array de ponteiros, data, é uma variável de ponteiro e o endereço do primeiro elemento de um array unidimensional.
  • Elementos no array podem ser acessados ​​pelo nome do array + i
  • Uma matriz de ponteiros pode ser vista como uma matriz bidimensional
arr[0]=data1;//指针数组首元素data,是指针变量,也是一维数组首元素的地址
arr[0][0]=data1[0];//看成一维数组
arr[0][1]=data1[1];
arr[0][2]=data1[2];
arr[0][3]=data1[3];
arr[0][4]=data1[4];

insira a descrição da imagem aqui
O resultado da impressão é mostrado na figura abaixo:
insira a descrição da imagem aqui
o código é substituído pelo seguinte efeito, e é escrito na perspectiva de desreferenciamento de endereço:

int main()
{
    
    
	int data1[] = {
    
     1,2,3,4,5 };
	int data2[] = {
    
     2,3,4,5,6 };
	int data3[] = {
    
     3,4,5,6,7 };
	//看成二维数组
	int* arr[3] = {
    
     data1,data2,data3 };
	for (int i = 0; i < 3; i++)
	{
    
    
		for (int j = 0; j < 5; j++)
		{
    
    
			printf("%d ", *(arr[i]+j));//地址访问解引用
		}
		printf("\n");
	}   
	return 0;
}

insira a descrição da imagem aqui

7.2 Exemplo 2

Os elementos na matriz de ponteiros são variáveis ​​de ponteiro, que é o endereço

int main()
{
    
    
	int a = 10;
	int b = 11;
	int c = 12;
	int d = 13;
	int e = 14;
	int* arr[5] = {
    
     &a,&b,&c,&d,&e };//指针数组存放的元素是指针变量,就是地址
	for (int  i = 0; i < 5; i++)
	{
    
    
		printf("%d ", *(arr[i]));//地址解引用
	}
	return 0;
}

insira a descrição da imagem aqui


Resumir

Este artigo continua a aprender os pontos de conhecimento relacionados a ponteiros. Ponteiros são a parte mais importante da linguagem C. Na fase básica, o aprendizado de ponteiros chega ao fim.

O próximo artigo aprenderá os pontos de conhecimento das estruturas.

Acho que você gosta

Origin blog.csdn.net/taibudong1991/article/details/123963476
Recomendado
Clasificación