指针
说明
指针是存放着数据地址的数据。
#include<stdio.h>
int main(void)
{
int Data = 0x7FFF;
int* DataPo = &Data;
printf("Data: %X\n", Data);
printf("&Data: %p\n", &Data);
printf("DataPo:%p\n", DataPo);
printf("&DataPo:%p\n", &DataPo);
return 0;
}
在输出结果中,我们看到 DataPo
中存储着 Data
的地址,而指针本身也是一个占用内存的数据。
其中指针占用内存的大小与当前应用程序的位数有关,例如 32
位程序其地址的大小为 32Bit
也就是 4Byte
, 64
位程序其地址的大小为 64Bit
也就是 8Byte
。
由此可知,我们当前程序为 64
位程序。
运算
指针可以进行4种算数运算:+
、-
、++
、--
。那他们的运算结果又是如何呢?
#include<stdio.h>
int main(void)
{
int Data = 0x7FFF;
int* DataPo = &Data;
printf("DataPo :%p\n", DataPo);
printf("\n");
printf("DataPo + 2:%p\n", DataPo + 2);
printf("DataPo - 4:%p\n", DataPo - 4);
printf("++DataPo :%p\n", ++DataPo);
printf("--DataPo :%p\n", --DataPo);
return 0;
}
此程序编译的版本为 64
位。
我们可以看到,指针进行过加减递增递减运算后,并不是单纯的 +1
或 -1
,而是增加或减少了一个 4
的倍数。
我们知道,在 Windows 下一个 int
的长度为 4byte
{具体参阅 数据类型范围 },而增加或减少 1
之后会使指针指向的地址增加或减少 4
。
简而言之就是,指针在增加或减少 Numb
之后,指针指向的数据会增加或减少 Numb * 数据长度
。
数组
/*声明一个拥有四个整数的数组*/
int Ar[4];
我们可以为数组进行赋值:
/*声明一个拥有四个整数的数组,其中第一个值为1,其他的自动填充为0*/
int Ar[4]={1};
/*使数组第二个值为2*/
Ar[1] = 2;
要注意C语言数组索引是从 0
开始的。至于为什么是从 0
开始,那就要和接下来要说的数组指针有关了。
数组指针
C语言数组的本质是指针。
int Ar[4];
索引
Ar
可以视作是指向数组地址的指针,数组的索引操作也就可以视作是 *(Ar + 偏移)
。
#include<stdio.h>
int main(void)
{
int DataAr[4] = { 1,2,3,4 };
int DataArIndex = 2;
printf("DataAr[DataArIndex] :%d\n", DataAr[DataArIndex]);
printf("*(DataAr + DataArIndex):%d\n", *(DataAr + DataArIndex));
return 0;
}
可以看到它们指向的地址都是同一个数值。
Ar
、 &(Ar[0])
和 (Ar + 0)
Ar
指向整个数组的地址,但是它同时也指向着数组首个元素。
我们可以得到如下的关系:Ar
<=> &(Ar[0])
<=> (Ar + 0)
。
为了证明我们的推理,进行如下测试:
#include<stdio.h>
int main(void)
{
int DataAr[4] = { 0 };
printf("DataAr :%p\n", DataAr);
printf("&(DataAr[0]):%p\n", &(DataAr[0]));
printf("DataAr + 0 :%p\n", DataAr + 0);
return 0;
}
根据输出可以看到,和我们推理的一样,它们指向着同一个地址。