所以我正在学习C指针,我有点困惑.指针只指向特定的内存地址.
sizeof(char*),sizeof(int*),sizeof(double*)所有输出8.所以它们都占用8字节来存储内存地址.
但是,如果我尝试编译这样的东西:
int main(void)
{
char letter = 'A';
int *a = &letter;
printf("letter: %c\n", *a);
}
Run Code Online (Sandbox Code Playgroud)
我收到编译器(gcc)的警告:
warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
int *a = &letter;
Run Code Online (Sandbox Code Playgroud)
但是,char *a = &letter;不会导致警告.
为什么指针的类型很重要,如果它的8字节长呢?为什么声明一个类型不同于它所指向的数据类型的指针会在警告中产生?
问题不在于指针的大小 - 它与指针的类型有关.
如果你有一个指向a的指针int,那么指针会占用一些字节数(好像你有一个64位系统,那个指针占用8个字节).但是,如果您取消引用该指针以读取或写入它所指向的内容,因为指针的类型是int*,读取或写入将尝试操纵sizeof(int)目标上的字节,并且它将尝试操纵它们,就好像它们是int.
如果您有一个类型的对象char,根据定义,它的大小为1,并且您尝试通过类型的指针读取或写入它int(在许多系统上)的大小为4,那么读取指针将拉回一些垃圾数据随着char和指针的写入将破坏char与不相关的值周围的存储器的随机区域.
此外,C有一个称为规则严格别名规则,说你是读不准或通过类型的指针不匹配的正指向(除非该指针的类型是一个什么样的类型写char *,signed char*或unsigned char*).打破严格的别名可能会破坏各种编译器优化,并导致代码无法按预期运行.
所以简而言之,指针的大小确实不是问题所在.这是关于当你试图读或写什么时会发生什么的语义.