2011-12-20 53 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 

我希望這有助於!