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;
}
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
. 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.
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)
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;
}
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;
}
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
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个字节
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
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];
O resultado da impressão é mostrado na figura abaixo:
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;
}
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;
}
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.