我在C学习期间遇到过以下代码。我已将其粘贴到CodeBlocks中,因此我知道输出但是(这是我的问题)它是如何完成的?你能解释一下吗?
#include <stdio.h>
int main()
{
unsigned char t[10] = {0,1,2,3,4,5,6,7,8,9};
unsigned short *w;
w = (unsigned int*) &t;
printf("%d\n",*w++);
printf("%d\n",*w++);
printf("%d\n",*w++);
return 0;
}
答案 0 :(得分:2)
请注意,此代码包含错误:错误转换,未定义行为和平台相关结果......
这是指针算术。 w
最初指向t
的第一个元素地址处的内容(这是w = (unsigned short *)&t
的含义)。然后,此后,您将此内存作为包含成功short
的内容访问。同时指针从short
移动到其后继者。
答案 1 :(得分:2)
请注意您发布的代码存在问题;我不会把它作为编写良好的代码的例子。除了彻头彻尾的错误之外,它一般都不安全。
首先,让我们至少使类型保持一致;我们假设意图是使用unsigned short
而不是unsigned int
:
#include <stdio.h>
int main()
{
unsigned char t[10] = {0,1,2,3,4,5,6,7,8,9};
unsigned short *w;
w = (unsigned short *) t;
printf("%hu\n",*w++);
printf("%hu\n",*w++);
printf("%hu\n",*w++);
return 0;
}
除非它是sizeof
或一元&
运算符的操作数,或者是用于在声明中初始化数组的字符串文字,否则表达式为“N-element array of of T
“将被转换(”衰减“)为”指向T
的指针“类型的表达式,表达式的值将是数组中第一个元素的地址。
所以,在行
w = (unsigned short *) t;
表达式t
从“{10}元素数组unsigned char
”转换为“指向unsigned char
”,表达式的值是{{1}的地址} 1 。我们将此指针值指定给t[0]
,但我们将其视为指向w
而非unsigned short
的指针(这称为类型惩罚)。 IOW,我们现在将unsigned char
视为t
的5元素数组,而不是unsigned short
2 的10元素数组。
该行
unsigned char
打印出printf("%hu\n",*w++);
当前指向 3 的unsigned short
值,然后将w
提前指向 next 无符号短值(对应w
) 4 。
根据您的平台是big-endian还是little-endian,这将得到不同的输出(这是此代码不是一个很好的例子的原因之一)。
<小时/> 1。请注意,表达式
t[2]
将为我们提供与&t
相同的值(数组的第一个元素的地址与数组的地址相同),但是类型应该是“指向t
”或char
的10个元素数组的指针,这不是我们想要的。char (*)[10]
映射到两个unsigned short
。这通常是 的情况,但并非如此;短裤可能比两个字符宽。unsigned char
期望相应的参数具有类型%d
;要打印int
值,请使用unsigned short
。 %hu
会导致w++
指向w
类型的下一个对象,它至少为两个字节。同样,在这种情况下,我们假设unsigned short
映射到两个unsigned short
s
答案 2 :(得分:-1)
更改这些行:
unsigned short *w;
w = (unsigned int*) &t;
使用:
unsigned char *w;
w = (unsigned char*) &t;
您将获得存储在数组中的值:
0
1
2