c将指向字符数组的指针强制转换为int*会得到与将字符*强制转换为int*相同的结果*

c将指向字符数组的指针强制转换为int*会得到与将字符*强制转换为int*相同的结果*,c,C,考虑以下C程序: #include <stdio.h> #include <stdlib.h> int main(){ char c[1] = {'Q'}; printf("%c ",*(char*)(c)); // line 1 printf("%c\n",*(char*)(&c)); // line 2 } 我得到了这个:a在声明中 char c[1] = {'Q'}; c是字符数组&array name即c本身表示该数组的基

考虑以下C程序:

#include <stdio.h>
#include <stdlib.h>
int main(){
    char c[1] = {'Q'};
    printf("%c ",*(char*)(c));   // line 1
    printf("%c\n",*(char*)(&c));  // line 2
}
我得到了这个:
a
在声明中

char c[1] = {'Q'};
c
是字符数组&
array name
c
本身表示该数组的基址。如果打印
c
&c
,两者都会给出相同的结果

旁注:-
c
表示指向数组第一个元素的指针,
&c
表示指向整个数组的指针

int main(void){
        char c[1] = {'Q'};
        printf("%p %p\n",(void*)c,(void*)&c); /* bot results the same */
        return 0;
}
这就是为什么
*(char*)(c)
*(char*)(&c)
产生相同的结果。例如

char c[10] = "asdf"; /* lets assume base address of c is 0x100 */
看起来像

 --------------------------------------
 |  a   |   s   |   d   |  f   | \0   |
 --------------------------------------
0x100   0x101   0x102 ..
c
接下来,这两个表达式是如何执行的

*(char*)(c)  =>  *(char*)(0x100)  => typecasted as char* means c points to 1 byte memory 
             =>   *(0x100)        => value in the first byte from 0x100 to 0x101 => a

在声明中

char c[1] = {'Q'};
c
是字符数组&
array name
c
本身表示该数组的基址。如果打印
c
&c
,两者都会给出相同的结果

旁注:-
c
表示指向数组第一个元素的指针,
&c
表示指向整个数组的指针

int main(void){
        char c[1] = {'Q'};
        printf("%p %p\n",(void*)c,(void*)&c); /* bot results the same */
        return 0;
}
这就是为什么
*(char*)(c)
*(char*)(&c)
产生相同的结果。例如

char c[10] = "asdf"; /* lets assume base address of c is 0x100 */
看起来像

 --------------------------------------
 |  a   |   s   |   d   |  f   | \0   |
 --------------------------------------
0x100   0x101   0x102 ..
c
接下来,这两个表达式是如何执行的

*(char*)(c)  =>  *(char*)(0x100)  => typecasted as char* means c points to 1 byte memory 
             =>   *(0x100)        => value in the first byte from 0x100 to 0x101 => a


如果您考虑一下等式
(void*)c==(void*)&c
,您就会意识到它在逻辑上是正确的。以静态分配的整数为例:

int myvar = 2;
打印
myvar
的值是有意义的,因为它是一个整数,并且“通用”可识别

现在如何识别数组?很明显,它有一个指向内存的地址

但是你怎么能把它打印出来呢?这是没有规定的。如果没有理由这样做,那么区分
c
&c
有什么意义呢。可以推测
c
可以解释为数组的第一个元素,但是您可以想象这种选择的所有缺点

编译器的推理实际上是不同的,特别是因为它不存在变量,所以它用它可以使用的东西替换它们

以这个片段为例:

int a = 2;
char c[6] = {'a', 'b', 'c', 'd', 'e', '\0'};

printf("%p\n",  c);
printf("%p\n", (void*) &c);
printf("%d\n", a);
printf("%p\n", (void*) &a);
以下是
gcc
生成的程序集(英特尔语法):


编译器以相同的方式解释
c
&c

如果你考虑一下等式
(void*)c==(void*)&c
,你就会意识到它在逻辑上是正确的。以静态分配的整数为例:

int myvar = 2;
打印
myvar
的值是有意义的,因为它是一个整数,并且“通用”可识别

现在如何识别数组?很明显,它有一个指向内存的地址

但是你怎么能把它打印出来呢?这是没有规定的。如果没有理由这样做,那么区分
c
&c
有什么意义呢。可以推测
c
可以解释为数组的第一个元素,但是您可以想象这种选择的所有缺点

编译器的推理实际上是不同的,特别是因为它不存在变量,所以它用它可以使用的东西替换它们

以这个片段为例:

int a = 2;
char c[6] = {'a', 'b', 'c', 'd', 'e', '\0'};

printf("%p\n",  c);
printf("%p\n", (void*) &c);
printf("%d\n", a);
printf("%p\n", (void*) &a);
以下是
gcc
生成的程序集(英特尔语法):



编译器以相同的方式解释
c
&c

提示:
c
是一个数组。我知道这一点,但仍然感到困惑,我怀疑这与字符串有关,但我不明白如何使用长度为5的数组进行解释,我想你会看到一些不同的情况。;)@请试试看;)好的,我已经做了,我将在问题提示中进一步解释:
c
是一个数组。我知道这一点,但仍然感到困惑,我怀疑这与字符串有关,但我不明白如何使用长度为5的数组来做,我想你会看到一些不同的东西@请试试看;)好的,我已经做了,我会在问题中详细解释:在用“%p”撬动它之前,你应该至少将&c转换为(void*)。你能提供更多细节吗?我还是很困惑@PSkocik我忘了加上这个。谢谢指点that@fred你不明白哪一部分?为什么c和c是一样的?我对指针的理解是它们存储一个值(指向内存中某个位置的指针),并且它们在内存中有自己的位置,所以如果你使用&c,你会得到c在内存中的位置,但如果使用c,你会得到存储在cNitpicking的值:在使用“%p”撬动它之前,你至少应该将&c转换为(void*)。你能给出更多细节吗?我还是很困惑@PSkocik我忘了加上这个。谢谢指点that@fred你不明白哪一部分?为什么c和c是一样的?我对指针的理解是,它们存储一个值(指向内存中某个位置的指针),并且它们在内存中有自己的位置,因此,如果使用&c,则得到内存中c的位置,如果使用c,则得到存储在c中的值