3 回答
TA貢獻1843條經驗 獲得超7個贊
首先,一些標準:
6.7.5.3函數聲明符(包括原型)
...
7參數聲明為'' 類型數組''應調整為''限定指向 類型 '',其中類型限定符(如果有)是指定的那些內的[與]所述陣列型推導。如果關鍵字static也出現在數組類型派生的[和]中,那么對于每次對函數的調用,相應的實際參數的值應該提供對數組的第一個元素的訪問,其中至少有與該大小指定的元素一樣多的元素。表達。
因此,簡而言之,任何函數參數聲明T a[]或T a[N]進行處理,就好像它被宣布T *a。
那么,為什么數組參數被視為聲明為指針?原因如下:
6.3.2.1左值,數組和功能指示器
...
3除了當它是的操作數sizeof操作者或一元&運算符,或者是用于初始化數組文本的字符串,其具有輸入“”的陣列的表達類型 ' '被轉換成類型的表達式‘’指針鍵入指向陣列對象的初始元素,不是左值‘’。如果數組對象具有寄存器存儲類,則行為未定義。
給出以下代碼:
int main(void){
int arr[10];
foo(arr);
...}在調用中foo,數組表達式arr不是任何一個sizeof或的操作數&,因此根據6.2.3.1/3 ,它的類型從“10元素數組int” 隱式轉換為“指向int”。因此,foo將接收指針值,而不是數組值。
因為6.7.5.3/7,你可以寫foo為
void foo(int a[]) // or int a[10]{
...}但它將被解釋為
void foo(int *a){
...}因此,這兩種形式是相同的。
6.99.5.3/7中的最后一句是用C99引入的,基本上意味著如果你有一個參數聲明
void foo(int a[static 10]){
...}對應的實際參數a必須是一個至少包含 10個元素的數組。
TA貢獻1831條經驗 獲得超4個贊
不,他們之間沒有區別。為了測試我在Dev C ++(mingw)編譯器中編寫了這個C代碼:
#include <stdio.h>
void function(int* array) {
int a =5;
}
void main() {
int array[]={2,4};
function(array);
getch();
}
當我在IDA中的兩個調用版本的二進制文件的.exe中反匯編主函數時,我得到完全相同的匯編代碼,如下所示:
push ebp
mov ebp, esp
sub esp, 18h
and esp, 0FFFFFFF0h
mov eax, 0
add eax, 0Fh
add eax, 0Fh
shr eax, 4
shl eax, 4
mov [ebp+var_C], eax
mov eax, [ebp+var_C]
call sub_401730
call sub_4013D0
mov [ebp+var_8], 2
mov [ebp+var_4], 4
lea eax, [ebp+var_8]
mov [esp+18h+var_18], eax
call sub_401290
call _getch
leave
retn
所以這個調用的兩個版本沒有區別,至少編譯器會同等地威脅它們。
- 3 回答
- 0 關注
- 420 瀏覽
添加回答
舉報
