#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”的值究竟是什么? 感谢。
答案 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 / 1
或4 / 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
评估为假时,循环终止。