无法理解sizeof

时间:2011-12-20 02:48:54

标签: c struct sizeof

#include <stdio.h>

int main (int argc, const char * argv[])
{
static struct item
{
    char code;
    float price;
}
table[] = 
{
    {'a', 3.29},
    {'b', 2.99},
    {'c', 0.59},
    {'d', 1.59},
    {'e', 2.39}
};

char item_code[2];
int quantity;
int i;

do {
    printf("Enter item code: ");
    scanf("%1s", item_code);

    if (*item_code != '.') {
        for (i=0; i< sizeof(table)/sizeof(struct item)
             && table[i].code != *item_code; i++);

        if (i < sizeof(table)/sizeof(struct item)) {
            printf("Enter quantity: ");
            scanf("%d", &quantity);
            printf("\nUnit price = %.2f, total price = %.2f.\n\n\n",
                   table[i].price, quantity * table[i].price);
        }
        else
            printf("\nItem code %c does not exist. \n\n\n", *item_code);
    }
} while (*item_code != '.');
printf("Thank you.\n");
return 0;
}

我是新手。我无法理解上述程序中的第二个“for循环”。为什么要使用sizeof?每次循环执行时,“i”的值究竟是什么? 感谢。

5 个答案:

答案 0 :(得分:4)

让我们检查系统中一些简单的代码,其中整数长度为四个字节:

int xyzzy[] = {3,1,4,1,5,9,2,6,5,3,5,8,9};       // 13 integers
printf ("%d\n"", sizeof(xyzzy));                 // 13 * 4 = 52
printf ("%d\n"", sizeof(int));                   //           4
printf ("%d\n"", sizeof(xyzzy) / sizeof(int));   // 52 / 4 = 13

根据最后一行,该计算是一种在数组中获取项数的方法。

顺便说一句,我更喜欢这个结构:

sizeof(xyzzy) / sizeof(*xyzzy)

因为即使我将xyzzy的类型更改为double,它仍将继续有效。这意味着我只需要更改声明变量的 one 行,而不是寻找所有的大小计算。

事实上,我甚至有一个最喜欢的宏:

#define numof(x) (sizeof(x) / sizeof(*x))

让我的代码变得更小。

关于for循环正在做什么(顺便说一下,从技术上来说,它不是第二个for循环,因为只有一个循环,但它第二个循环),它基本上遍历i的每个值(盯着0,第一个索引),直到它到达最后一个元素之外的点,或者它找到一个带有所需项目代码的元素。

退出该循环时,i将设置为元素数量(如果未找到商品代码)或设置为正确的索引 ,因此if循环之后的for语句。

答案 1 :(得分:3)

i从零(i=0)开始,每次迭代增加一(i++)。所以,0, 1, 2, 3...等。

sizeof以字节为单位返回参数的大小。 sizeof(table)/sizeof(struct item)是获取表格中项目数量的方法。就像,“每个城市街区都是200米。在1000米街道有多少个街区?” sizeof(street)/sizeof(block)。简单。

答案 2 :(得分:1)

paxdiablo's answer完美地解释了这种情况;我想提醒您不要对这种语言特性抱有(可能)乐观态度:数组不知道它们的长度。您不能在已传递给函数的数组上使用paxdiablo的有用宏:

#define numof(x) (sizeof(x) / sizeof(*x))

void f(char arr[]) {
    int len;

    len = numof(arr);  /* FAIL */
}

void bar() {
    char c[] = "initialized char array";

    f(c);
}

写入type name[]的函数原型实际衰减type *name 指针。最糟糕的是使用numof()实际上不会,它只会给你错误的答案:sizeof(arr) / sizeof (*arr)将返回8 / 14 / 1,因为它正在检查char *的大小与char的大小。

paxdiablo的宏对于检查封闭范围中定义的数组的大小非常有用,但不适用于参数。

答案 3 :(得分:1)

“为什么要使用sizeof?”

要理解为什么使用sizeof(),首先必须对结构及其用于定义的变量有基本的了解。

static struct item
{
    char code;
    float price;
}
table[] = 
{
    {'a', 3.29},
    {'b', 2.99},
    {'c', 0.59},
    {'d', 1.59},
    {'e', 2.39}
};

这声明了一个名为 item 的结构类型,它由两个变量组成 - code ,其类型为 char price < / em>的类型为 float 。使用以下语句:

sizeof(struct item)

提供结构本身的大小... char,1个字节和一个浮点数,4个字节。

然后代码定义一个名为table []的结构项数组,并用多个值初始化它。在这种特殊情况下,有五个字符和五个浮点数(总共25个字节)。因此,通过取sizeof(table)并将其除以sizeof(struct item),我们得到了数组中结构项的总值(25/5 = 5)。

你可能会问,为什么不说我&lt; 5?毕竟,您可以看到表数组中有五个结构项。但是,如果这是一个巨大的表,您可能不想计算数组中的结构数。这也使得以后更容易维护。

每次循环执行时“i”的值究竟是什么?

for(;;)循环的第一部分和最后部分提供了答案:

for (i = 0; 
     i < sizeof(table)/sizeof(struct item) && table[i].code != *item_code;
     i++);

所以,我用值0初始化。在循环的每次连续迭代中,i递增1(i ++)。

因此,我将继续增加1,直到达到以下边界之一:

i == 5                        //(sizeof(table) / sizeof(struct item))
table[i].code == *item_code

我希望这有帮助!

答案 4 :(得分:0)

sizeof(table)/sizeof(struct item)在编译时计算大小(以字节为单位),它会告诉您表格中的项目数,即sizeof(table)以字节为单位的sizeof(struct item)是数字数组中的项目为5。

你也可以把它写成

for (i=0; i < 5 && table[i].code != *item_code; i++);
{
   // ........
}

i变为5或您的条件table[i].code != *item_code评估为假时,循环终止。