为什么建议将C指针作为它们所使用的数据类型';如果他们';是否有8个字节大?

为什么建议将C指针作为它们所使用的数据类型';如果他们';是否有8个字节大?,c,pointers,C,Pointers,所以我正在学习C指针,我有点困惑。指针只指向特定的内存地址 sizeof(char*),sizeof(int*),sizeof(double*)所有输出8。因此,它们都需要8字节来存储内存地址 但是,如果我尝试编译如下内容: int main(void) { char letter = 'A'; int *a = &letter; printf("letter: %c\n", *a); } 我从编译器(gcc)收到警告: 但是,char*a=&letter,不会

所以我正在学习C指针,我有点困惑。指针只指向特定的内存地址

sizeof(char*)
sizeof(int*)
sizeof(double*)
所有输出
8
。因此,它们都需要
8
字节来存储内存地址

但是,如果我尝试编译如下内容:

int main(void)
{
    char letter = 'A';
    int *a = &letter;
    printf("letter: %c\n", *a);
}
我从编译器(
gcc
)收到警告:

但是,
char*a=&letter,不会导致警告


如果指针的长度是
8
字节,那么指针的类型为什么重要呢?为什么声明指针的类型与其指向的数据类型不同会产生警告?

这与字节长度无关,而与指向的数据类型有关
Char
int
完全不同。此外,
sizeof(char)
equal 1和
sizeof(int*)
equal 8。

问题不在于指针的大小,而在于指针的类型

如果您有一个指向
int
的指针,指针将占用一定数量的字节(似乎您有一个64位系统,其中该指针占用8个字节)。但是,如果您取消引用该指针以读取或写入它所指向的内容,因为指针的类型是
int*
,则读取或写入操作将尝试在目标处操作
sizeof(int)
字节,并将尝试像操作
int
一样操作它们

如果您有一个类型为
char
的对象,根据定义,该对象的大小为1,并且您试图通过类型为
int
的指针读取或写入该对象,该指针(在许多系统上)的大小为4,然后,读取指针会将一些垃圾数据连同
char
一起拉回来,写入指针会用不相关的值将
char
周围的随机内存区域击垮

此外,C还有一个称为严格别名规则的规则,该规则规定,不允许通过与所指向对象类型不匹配的类型的指针进行读写(除非指针的类型为
char*
signed char*
unsigned char*
)。打破严格的别名会打乱各种编译器优化,并导致代码的行为不符合预期


简而言之,指针的大小并不是问题所在。它是关于当你试图读或写被指向的东西时会发生什么的语义学。

想想你要用指针做什么

int n = 42;
char *p = &n; // BAD
如果编译成功(编译器可以直接拒绝它,而不是打印非致命警告),则会有一个指针指向
int
对象
n
占用的内存。你要如何得到这个对象的值
*p
为您提供一个
char
结果,很可能是
n
的第一个字节,它可能是高阶字节,也可能是低阶字节

指针类型取决于指针指向的对象的类型,因此您可以访问该对象


(另外,不要根据特定实现的行为进行假设。32位系统有4字节的指针,并且该语言不能保证所有指针大小相同。)

重要的是您指向的对象的类型,并且
char
不是
int
.a)类型安全/nice编译警告b)。不要从实现的行为中概括,并且一般地假设C。在大多数实现中,指针的大小是相同的——但不是全部更改?42是否应该表示为浮点数?如果没有指针类型,编译器无法知道这一点。谢谢!我现在完全明白了。当然,我尝试了一个
char*
指针,指向大于255的
int
,但它打印了错误的值。非常感谢。
int n = 42;
char *p = &n; // BAD