為什么C和C ++編譯器在從未強制實施時允許函數簽名中的數組長度?這是我在學習期間發現的:#include<iostream>using namespace std;int dis(char a[1]){
int length = strlen(a);
char c = a[2];
return length;}int main(){
char b[4] = "abc";
int c = dis(b);
cout << c;
return 0;}所以在變量中int dis(char a[1]),[1]似乎什么都不做,根本不起作用,因為我可以使用a[2]。就像int a[]或char *a。我知道數組名稱是一個指針,以及如何傳達一個數組,所以我的謎題不是這個部分。我想知道的是為什么編譯器允許這種行為(int a[1])。或者它有其他我不知道的含義?
3 回答

12345678_0001
TA貢獻1802條經驗 獲得超5個贊
這是將數組傳遞給函數的語法的怪癖。
實際上,無法在C中傳遞數組。如果您編寫的語法看起來應該通過數組,那么實際發生的是傳遞指向數組第一個元素的指針。
由于指針不包含任何長度信息,因此[]
實際上忽略了函數形式參數列表中的內容。
允許這種語法的決定是在20世紀70年代做出的,并且自從......以來引起了很大的混亂。

慕桂英4014372
TA貢獻1871條經驗 獲得超13個贊
忽略第一個維度的長度,但需要額外維度的長度以允許編譯器正確計算偏移量。在下面的示例中,foo
函數傳遞指向二維數組的指針。
#include <stdio.h>void foo(int args[10][20]){ printf("%zd\n", sizeof(args[0]));}int main(int argc, char **argv){ int a[2][20]; foo(a); return 0;}
[10]
忽略第一個維度的大小; 編譯器不會阻止你索引結束(請注意,正式需要10個元素,但實際只提供2個元素)。但是,第二個維度的大小[20]
用于確定每一行的步幅,這里,形式必須與實際匹配。同樣,編譯器也不會阻止您索引第二個維度的末尾。
從數組基址到元素的字節偏移量由下式args[row][col]
確定:
sizeof(int)*(col + 20*row)
請注意,如果col >= 20
,那么您將實際索引到后續行(或整個數組的末尾)。
sizeof(args[0])
,80
在我的機器上返回sizeof(int) == 4
。但是,如果我嘗試接受sizeof(args)
,我會得到以下編譯器警告:
foo.c:5:27: warning: sizeof on array function parameter will return size of 'int (*)[20]' instead of 'int [10][20]' [-Wsizeof-array-argument] printf("%zd\n", sizeof(args)); ^foo.c:3:14: note: declared herevoid foo(int args[10][20]) ^1 warning generated.
在這里,編譯器警告它只會給出數組已經衰減的指針的大小而不是數組本身的大小
- 3 回答
- 0 關注
- 855 瀏覽
添加回答
舉報
0/150
提交
取消