当我运行此代码时:
int arr[3] = {2,3,4};
char *p;
p = (char*)arr;
printf("%d", *p);
p = p+1;
printf("%d", *p);
输出为2和0.第二个结果有点令人困惑。有人可以解释为什么会这样吗?
答案 0 :(得分:9)
让我们打破这个:
int arr[3] = {2,3,4};
创建一个包含3个整数的数组。假设你的系统是32位小端,这就是它在内存中的样子:
02 00 00 00 03 00 00 00 04 00 00 00
char *p; p = (char*)arr;
p
现在指向arr
但是指向char*
的指针。换句话说,p
指向02
。
printf("%d", *p);
您正在int
p
引用的位置打印。因此,当您取消引用 p
时(通过撰写*p
),您正在访问char
(因为p
类型为char*
)由p
引用。这是02
。
p = p+1;
p
现在指向00
之后的02
,因为p
是char*
。因此,当您添加1时,它将在内存中移动1 * sizeof(char) = 1 * 1 = 1
个字节。
printf("%d", *p);
您正在int
p
引用的位置打印。因此,当您取消引用 p
时(通过撰写*p
),您正在访问char
(因为p
类型为char*
)由p
引用。这是00
。
如果您想打印3
而不是0
,则必须将指针类型更改为int*
而不是char*
,使指针移动1 * sizeof(int) = 1 * 4 = 4
内存中的字节。
答案 1 :(得分:4)
您获得的结果取决于您的实施中int
的大小及其字节顺序。
假设32位整数,8位字符和一个litte-endian环境(比如x86),arr
在内存中会是这样的:
< arr[0] > < arr[1] > < arr[2] >
02 00 00 00 03 00 00 00 04 00 00 00
^ ^ ^
p p+1 ... p+4
如果您使用char指针指向该内存的开头,并打印出第一个元素,则应输出2
。如果递增该指针,则接下来将输出0。您需要将其增加几倍才能看到&#39; 3。
请注意,在具有相同类型大小的大端环境中,您的程序将输出两个零,因为布局应该是:
< arr[0] > < arr[1] > < arr[2] >
00 00 00 02 00 00 00 03 00 00 00 04
^ ^ ^
p p+1 ... p+4
答案 2 :(得分:2)
这是因为endianness。
创建像int arr[3] = {2, 3, 4};
这样的数组时,它会在内存中创建,如下所示
Big endian:
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+--------+---+---+---+--------+---+---+---+--------+
| | | | ..0010 | | | | ..0011 | | | | ..0100 |
+---+---+---+--------+---+---+---+--------+---+---+---+--------+
<-- 2 --><-- 3 --><-- 4 -->
Little endian:
0 1 2 3 4 5 6 7 8 9 10 11
+--------+---+---+---+---------+---+---+---+--------+---+---+---+
| ..0010 | | | | ..0011 | | | | ..0100 | | | |
+--------+---+---+---+---------+---+---+---+--------+---+---+---+
<-- 2 --><-- 3 --><-- 4 -->
要了解更多信息,您需要按如下方式修改程序:
int main(void)
{
int arr[3] = {2, 3, 4};
char *p = (char*) arr;
int i;
int size = (int)sizeof(arr);
for (i=0; i<size ; i++) {
printf("%d", *p);
p++;
}
return 0;
}
并且,要检查硬件的字节顺序,可以使用以下功能。
void endian(void)
{
int i = 1;
if (*(char *) &i == 1)
printf("Little endian \n");
else
printf("Big endian \n");
return;
}
答案 3 :(得分:1)
以下是一种可让您更好地了解问题的粘贴:http://codepad.org/ClrrwjKY
如您所见,连续整数的值以三个零分隔。这是因为整数长度为4个字节,而char只有1个字节长。因此,当int数组转换为char时,您将逐字节(或char by char)迭代它,而不是四个字节(int by int)。
答案 4 :(得分:0)
这里'p'是一个字符指针.. p + 1仅将p的当前值递增1。 由于数组是整数,为了逐个访问数组的每个值,您必须将字符数组递增2。 如果整数数组的地址是1000 因此,
arr[0] is at 1000
arr[1] is at 1002
arr[2] is at 1004
,arr的值是arr [0]的地址; 所以最初
p=arr=1000
当p递增时,p为1001而arr [1]为1002
..因此,为了访问所有值,您每次必须增加p值两次..