C 我能';我不懂这种类型的铸件
我用C 我能';我不懂这种类型的铸件,c,arrays,pointers,type-conversion,C,Arrays,Pointers,Type Conversion,我用int和char进行了类型转换,但没有使用指针,所以我发布了这个问题 #include <stdio.h> int main() { int a[4] = { 1, 2, 6, 4 }; char *p; p = (char *)a; // what does this statement mean? printf("%d\n",*p); p = p + 1; printf("%d",*p); // after
int
和char
进行了类型转换,但没有使用指针,所以我发布了这个问题
#include <stdio.h>
int main() {
int a[4] = { 1, 2, 6, 4 };
char *p;
p = (char *)a; // what does this statement mean?
printf("%d\n",*p);
p = p + 1;
printf("%d",*p); // after incrementing it gives 0 why?
}
#包括
int main(){
inta[4]={1,2,6,4};
char*p;
p=(char*)a;//这句话是什么意思?
printf(“%d\n”,*p);
p=p+1;
printf(“%d”,*p);//递增后,它给出0为什么?
}
对
printf
的第一次调用给出数组的第一个元素。在p=p+1
之后,它给出0
。为什么?确切地说,第一个printf
并没有给出数组的第一个元素,它给出了第一个元素的第一个8位,恰好等于第一个元素的数值。
第二个printf给出第一个元素的下8位,在本例中为0
1=00000000000000000000000000000001(32位)您有一个由四个整数组成的数组。您尝试以字符“数组”的形式访问它们。这就是演员的意思 至于第二个
printf
打印零,请记住整数是四个字节,而字符只有一个。因此,增加指针p
将使p
指向第一个整数的第二个字节,即零。如果数字较大(即超过255),则第二个字节也会有一个值。但请注意,这只适用于英特尔类型的机器,即小端机器,而在大端机器上,printf
都将打印零
int a[4] = { 1, 2, 6, 4 };
将数组声明为数组a
此时存储数组第一个元素的地址
char *p;
将p声明为指向字符的指针
p = (char *)a;
现在由于p
和a
两个存储地址。因此存储在a
(address
数组第一个元素)的地址被分配给p
。当p
被声明为char*
它的作用是,假设存储在a
的地址是100,假设int
占用内存中的2个字节,char
占用内存中的1个字节
及
这将解释输出为
A.存储在A
的两个字节包含数组的第一个元素
char *p;
B.存储在p
的一个字节是整数1
的第一个字节的字符表示,即0
希望这有帮助。如果使用类似英特尔的处理器,堆栈上的字节将使用little-endian格式存储。在更多情况下,int类型(在您的计算机上)的大小可能为4字节,而char的长度为1字节(您可以使用c运算符“sizeof”验证这一点),因此整数数组的第一个元素是:
0x04 0x00 0x00 0x00
因此,当您使用char指针查看整数数组的值时,每次前进一个字节(不是4个字节),得到的结果显而易见
我希望这有帮助 a是指向内存数组的指针。该内存可能是以小端二进制补码格式排列的,作为一个16字节的连续块
当你施放它时,你基本上只是说“好吧,我知道这是一个指向int数组的指针,但是现在我们将把数据重新解释为一个char数组”。字符通常是一个字节。因此,当您向指针添加一个时,您增加了指针指向的位置。因为它是一个字符数组,所以它在数组的中间加了一个字节,它在int的中间,包含0。
为了澄清,根据我对您的计算机架构的假设:
小尾数(最低有效字节排在第一位):
0000000 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000100000000000000000000000二进制=2十进制
00000110000000000000000000000000二进制=6十进制
000001000000000000000000二进制=4十进制
您的整数数组如下所示:
000000000000000000000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000000000000000000
变量“a”指向第一个整数,即32位(即“*a”为0000000 10000000000000000000000
)。如果向变量“a”添加一个,则递增指针,因此*(a+1)指向第二个int0000000000000000000000000000000
)
现在,将变量“a”强制转换为“char*”指针。因此,现在,变量“p”指向相同的位置,但因为它是一个字符指针,所以指向第一个字符,即8位(即“*p”是00000001
,数组的第一个字节)
最后,当您递增“p”时,您递增指针。因为“p”是一个指向字符的指针,它前进一个字节,所以“*(p+1)”是00000000
让我们想象一个相当典型的平台,其中一个字节是八位的,内存使用小尾端字节顺序排列,int
表示内存中的四个字节。在此平台上,1
的值如下所示:
00000001 00000000 00000000 00000000
^
the first element of 'a'
p
声明为指向char
(非int
)的指针,并初始化为指向数组a
的第一个元素。此平台上的char
表示一个字节。上面解释为char
的int
值如下所示:
00000001 -------- -------- --------
| |
------
char is only 8 bits wide
因此,无论我们读取一个字节还是四个字节,也就是说,无论我们读取*p
还是a[0]
,值都是1
。但是,当您递增p
时,指向char
的指针现在指向内存中的下一个char,即下一个字节:
00000001 00000000 00000000 00000000
00000001 00000000 -------- --------
^ ^ ^ ^
p p+1 p+2 p+3 ...
a[1]
指向下一个int
(2
),p[1]
指向下一个char
,即0
另一方面,您实际上偶然发现了一种确定给定处理器使用的是小字节顺序还是大端字节顺序的方法。
00000001 00000000 00000000 00000000
00000001 00000000 -------- --------
^ ^ ^ ^
p p+1 p+2 p+3 ...
0000000 00000000 00000000 00000001
^
the first element of 'a'
0000000 -------- -------- --------
^
p
int n = 1;
if(*(char*)&n == 1)
// little endian
else
// big endian