2011-12-20 58 views
2
#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”的值是什么? 谢谢。无法理解sizeof

回答

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例如工作。这意味着我只需要更改声明该变量的一行而不是查找所有大小计算。

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

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

使我的一点点小。

在什么for循环做的正是(而且,顺便说一下,这不是技术上的第二for循环,因为这里只有一个,但它第二循环),它主要通过对每一个值迭代i(盯着0,第一个索引),直到它到达超出最后一个元素的点或它找到具有所需项目代码的元素。

在从循环退出,如果该项目的代码没有被发现或者设置为正确的索引,如果它发现,因此if声明以下是for循环i将被设置为元素的数量。

3

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

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

0

sizeof(table)/sizeof(struct item)在编译时以字节为单位计算大小,它告诉你表中的表中的项数,即sizeof(表项)的大小(sizeof(struct item))是你拥有的项目数阵列中是5

你也可以只把它写成

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

i变为5或你的病情table[i].code != *item_code计算结果为假,循环终止。

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的宏对于检查封闭范围中定义的数组的大小非常有用,但不适用于参数。

+2

只有一个nitpick:数组_do_知道他们的长度。在许多情况下,数组_decay_指向的数组的指针不知道指向数组的第一个元素的长度。但从技术上讲,他们不再是那种情况下的阵列:-) – paxdiablo 2011-12-20 04:50:21

+0

恩,说,谢谢。 :) – sarnold 2011-12-20 06:12:01

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

这声明称为它由两个变量的结构类型 - 代码具有类型价格具有类型浮子的。使用以下语句:

sizeof(struct item) 

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

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

您可能会问,为什么不直接说我< 5?最后,您可以看到表格数组中有五个结构项目。但是,如果这是一个巨大的表格,您可能不想计算数组中的结构数量。这也使得后续维护更容易。

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

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

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

所以,i被初始化为值0在每次通过循环连续的迭代中,i递增由1(i ++)。

因此,我将继续通过1增加,直到已经达到下列边界之一:

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

我希望这有助于!