這是我用來學習指向 struct 作業方式的代碼。正如您在下面看到的,變數的值s不等于它指向的結構的地址(&amity),奇怪 *s的是等于它。
這里還有一些我也有的問題:
為什么所有 struct 實體(甚至&instance.name)的地址都相同?
雖然s和是相同的,但為什么值與i和不同?j*j*s*i
最后,為什么結構的值只等于它的第一個欄位的值?
該代碼是從書 Head First C 中修改的代碼。
#include <stdio.h>
typedef struct island {
char *name;
char *open;
char *close;
struct island *next;
} island;
void text(island *s);
int main(void) {
island amity = { "Amity", "09:00", "17:00", NULL };
island craggy = { "Craggy", "09:00", "17:00", NULL };
island isla_nublar = { "Isla Nublar", "09:00", "17:00", NULL };
island shutter = { "Shutter", "09:00", "17:00", NULL };
amity.next = &craggy;
craggy.next = &isla_nublar;
isla_nublar.next = &shutter;
printf("amity: %s\t &amity: %p\t &amity.name:%p \n", amity, &amity, &amity.name);
printf("craggy: %s\t &craggy: %p\t &craggy.name:%p \n", craggy, &craggy, &craggy.name);
printf("shutter: %s &shutter: %p\t &shutter.name:%p \n\n", shutter, &shutter, &shutter.name);
text(&amity);
}
void text(island *s) {
island *i = s;
island *j = i;
printf("s: %p\t i: %p\t j:%p\n", s, i, j);
printf("&s: %p\t &i: %p\t &j:%p\n", &s, &i, &j);
printf("*s: %p\t *i: %p\t *j:%p\n\n", *s, *i, *j);
for (; i != NULL; i = i->next) {
printf("Name: %s open: %s-%s\n", i->name, i->open, i->close);
}
}
結果如下:
amity: Amity &amity: 0040302A &amity.name:00403030
craggy: Craggy &craggy: 0040302A &craggy.name:00403030
shutter: Shutter &shutter: 0040302A &shutter.name:00403030
s: 0060FEF0 i: 0060FEF0 j:0060FEF0
&s: 0060FEA0 &i: 0060FE8C &j:0060FE88
*s: 00403024 *i: 0040302A *j:00403030
Name: Amity open: 09:00-17:00
Name: Craggy open: 09:00-17:00
Name: Isla Nublar open: 09:00-17:00
Name: Shutter open: 09:00-17:00
uj5u.com熱心網友回復:
在編譯器中打開警告,注意并修復它們。使用 GCC,從-Wall. 使用 Clang,從-Wmost. 對于 Microsoft Visual C (MSVC),從/W4. 還將警告提升為錯誤。使用 GCC 或 Clang,使用-Werror. 使用 MSVC,使用/Wx.
為什么所有結構實體(甚至 &instance.name)的地址都相同?
他們不是。在您的printf呼叫中,您傳遞了與轉換說明符不匹配的型別的引數。這有效地破壞了printf操作的資料,因此它的輸出不會顯示引數的實際值。例如,在:
printf("amity: %s\t &amity: %p\t &amity.name:%p \n", amity, &amity, &amity.name);
%s需要一個char *引數,但相應的引數是一個結構。在您的 C 實作中,結構可能已通過將其位元組復制到堆疊來傳遞。這導致指標位于期望找到指標amity.name的位置,因此通過使用該指標列印字串來“作業”。但是, then需要一個指標,但在第一個指標之后的堆疊上是結構的更多位元組,而不是引數。因為結構是在堆疊上傳遞的,所以它占用了空間,并且引數稍后出現。所以,在尋找指標時,沒有找到%sprintf%p%s&amity&amityprintf%p&amity爭論; 它在結構的后面找到一些位元組,并將它們轉換為指標。
因此,您的輸出已損壞,并且未向您顯示&amityor的值&amity.name。
雖然 s 和 i 和 j 相同,但為什么 *j 的值與 *s 和 *i 不同?
在printf("*s: %p\t *i: %p\t *j:%p\n\n", *s, *i, *j);中,您再次傳遞期望指標的結構( *s、、*i和*j是每個結構) 。printf輸出已損壞。
修復printf呼叫以使引數型別與轉換說明符匹配后,您將看到正確的地址。
最后,為什么結構的值只等于它的第一個欄位的值?
結構的值不等于其第一個欄位的值。由于輸出損壞,您從問題中顯示的測驗程式中獲得的任何印象都是不正確的。
但是,結構的地址確實等于第一個欄位的地址,因為第一個欄位從結構的開頭開始,這當然是結構開始的地方。
uj5u.com熱心網友回復:
一開始可能很難考慮指標。但是,并不能真正幫助理解它們的一種方法是寫下 和 的所有組合,&并*在結果中尋找模式。您發布的代碼包含許多無意義的組??合,基本上不可能說出它的作用。
每當您使用&or*時,您應該能夠解釋它的作用。 &獲取某物的地址——創建一個指向某物的指標——如果你想列印這個地址,你總是會使用%p. *獲取指標的“內容”——它指向的值——如果你想列印這個東西,你會使用printf與指向的東西型別相對應的格式。
這是您的程式的修改版本,它僅列印有意義的組合,并且我認為它解釋了您試圖回答的問題型別。
int main (void) {
island amity = {"Amity", "09:00", "17:00", NULL};
island craggy = {"Craggy", "10:00", "17:00", NULL};
island isla_nublar = {"Isla Nublar", "09:00", "18:00", NULL};
island shutter = {"Shutter", "10:00", "18:00", NULL};
amity.next = &craggy;
craggy.next = &isla_nublar;
isla_nublar.next = &shutter;
printf("&amity: %p\t &amity.name:%p \t &amity.open:%p \n",
&amity, &amity.name, &amity.open);
printf("&craggy: %p\t &craggy.name:%p \t &craggy.open:%p \n",
&craggy, &craggy.name, &craggy.open);
printf("&shutter: %p\t &shutter.name:%p \t &shutter.open:%p \n",
&shutter, &shutter.name, &shutter.open);
text(&amity);
}
void text (island *s) {
island *i;
printf("s: %p\n", s);
for(i = s ; i !=NULL ; i = i->next){
printf("Name: %s open: %s-%s\n", i->name, i->open , i->close);
}
}
在main中,該程式列印結構的地址、第一個成員的地址和第二個成員的地址。在我的電腦上,它列印
&amity: 0x7ffee17349b0 &amity.name:0x7ffee17349b0 &amity.open:0x7ffee17349b8
&craggy: 0x7ffee1734990 &craggy.name:0x7ffee1734990 &craggy.open:0x7ffee1734998
&shutter: 0x7ffee1734950 &shutter.name:0x7ffee1734950 &shutter.open:0x7ffee1734958
s: 0x7ffee17349b0
Name: Amity open: 09:00-17:00
Name: Craggy open: 10:00-17:00
Name: Isla Nublar open: 09:00-18:00
Name: Shutter open: 10:00-18:00
在每種情況下,結構的第一個成員的地址與預期的結構的地址相同。第二個成員的地址稍大,由sizeof(char *),在我的機器上是 8。
在text()中,我只列印傳入的指標的值amity,正如預期的那樣,它與 的地址相同。(我還讓四個島嶼的開閉時間不同,所以我們可以確認它們列印正確。)
printf正如您在撰寫時所要求的那樣,嘗試使用 列印整個結構完全沒有意義
printf("amity: %s\t &amity: %p\t &amity.name:%p \n", amity, &amity, &amity.name);
我很驚訝你的編譯器讓你逃脫了。
有關更多解釋,請參閱 Eric Postpischil 的回答。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/415831.html
標籤:
上一篇:在檢索發件人ID的FCM令牌之前未設定FirebaseAPNS設備令牌-FlutteriOS
下一篇:這段代碼與指標有什么關系嗎?
