这个C代码如何工作?

时间:2016-01-18 15:41:32

标签: c

我在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;
}

3 个答案:

答案 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个元素数组的指针,这不是我们想要的。

2.我们假设一个char (*)[10]映射到两个unsigned short。这通常是 的情况,但并非如此;短裤可能比两个字符宽。

3.转换说明符unsigned char期望相应的参数具有类型%d;要打印int值,请使用unsigned short

指针arithemtic是根据指向类型的大小完成的; %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