該程式在 C 中作業:
#include <stdio.h>
int main(void) {
char a[10] = "Hello";
char *b = a;
printf("%s",b);
}
我希望有兩件事會有所不同。一種是我們在main的第二行寫:“char *b = &a”,那么程式是這樣的:
#include <stdio.h>
int main(void) {
char a[10] = "Hello";
char *b = &a;
printf("%s",b);
}
但這不起作用。這是為什么?這不是用地址初始化指標的正確方法嗎?
我遇到的第二個問題是我們應該有的最后一行: printf("%s",*b) 所以程式是這樣的:
#include <stdio.h>
int main(void) {
char a[10] = "Hello";
char *b = a;
printf("%s",*b);
}
但這會產生分段錯誤。為什么這不起作用?我們不應該在指標前面寫“*”來獲取它的值嗎?
uj5u.com熱心網友回復:
C中有一個特殊的規則。當你寫
char *b = a;
你得到的效果和你寫的一樣
char *b = &a[0];
也就是說,您會自動獲得指向陣列第一個元素的指標。每當您嘗試獲取陣列的“值”時,都會發生這種情況。
我們不應該在指標前面寫“*”來獲取它的值嗎?
是的,如果您想獲得 指向的單個字符b,則需要*. 這段代碼
printf("first char: %c\n", *b);
將列印字串的第一個字符。但是當你寫
printf("whole string: %s\n", b);
你得到整個字串。 %s列印多個字符,它需要一個指標。在里面printf,當你使用時%s,它會回圈并列印字串中的所有字符。
uj5u.com熱心網友回復:
擴展史蒂夫的答案(這是正確的接受)......
這是他所說的特殊規則:
6.3.2.1 左值、陣列和函式指示符C 2011 預發布草案
...
3 除非它是運算sizeof符、運算子_Alignof或一元&運算子的運算元,或者是用于初始化陣列的字串字面量,否則為 '' 型別的運算式''型別的陣列被轉換為型別為 '' 指向型別 '' 的指標的運算式,它指向陣列物件的初始元素并且不是左值。如果陣列物件具有暫存器存盤類,則行為未定義。
陣列很奇怪,不像其他型別。在其他聚合型別(如型別)中,您不會得到這種“指向第一個元素的指標的衰減”行為struct。您不能=像使用struct型別那樣使用運算子分配整個陣列的內容;例如,你不能做類似的事情
int a[5] = {1, 2, 3, 4, 5};
int b[5];
...
b = a; // not allowed; that's what "is not an lvalue" means
為什么陣列很奇怪?
C 派生自一種名為 B 的早期語言,當您在 B 中宣告一個陣列時:
auto arr[5];
編譯器留出一個額外的單詞來指向陣列的第一個元素:
---
arr: | | ----------
--- |
... |
--- |
| | arr[0] <--
---
| | arr[1]
---
| | arr[2]
---
| | arr[3]
---
| | arr[4]
---
陣列下標操作arr[i]被定義為*(arr i)- 給定存盤在的起始地址arr,從該地址偏移i元素并取消參考結果。這也意味著&arr它將產生與 不同的值&arr[0]。
在設計 C 時,Ritchie 想保留 B 的陣列下標行為,但他不想為該行為所需的單獨指標留出存盤空間。因此,他沒有存盤單獨的指標,而是創建了“衰減”規則。在 C 中宣告陣列時:
int arr[5];
唯一留出的存盤空間是用于陣列元素本身:
---
arr: | | arr[0]
---
| | arr[1]
---
| | arr[2]
---
| | arr[3]
---
| | arr[4]
---
下標操作arr[i]仍定義為*(arr i),但不是將指標值存盤在 中,而是從運算式計算arr指標值。這意味著并且將產生相同的地址值,但運算式的型別將不同(分別為vs )。arr&arr&arr[0]int (*)[5]int *
此規則的一個實際效果是,您可以[]在指標運算式和陣列運算式上使用運算子 - 給定您可以撰寫的代碼b[i],它的行為將與a[i].
另一個實際效果是,當您將陣列運算式作為引數傳遞給函式時,函式實際接收的是指向第一個元素的指標。這就是為什么您經常必須將陣列大小作為單獨的引數傳遞的原因,因為指標僅指向指定型別的單個物件;無法從指標值本身知道您是否指向陣列的第一個元素,陣列中有多少元素等。
陣列不攜帶元資料,因此無法在運行時查詢陣列的大小、型別或其他任何內容。sizeof運算子是在編譯時計算的,而不是在運行時計算的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/483994.html
上一篇:指標陣列的動態分配/釋放
