2012-07-20 98 views
0

我收到以下警告:數組c和指針參數

expected ‘float **’ but argument is of type ‘float (*)[6]’ 

這裏是我的代碼:

//state and error are output parameters 
void func(float* state[6], float* err[6][6]); 

int main() 
{ 
    float state[6]; 
    float err[6][6]; 

    func(&state, &err); 

    return 0; 
} 

我想狀態,犯錯是ouptut參數,所以狀態應該是一個指針到一個數組,而err應該是一個指向2維數組的指針。

+0

它期待着一個指向指針的指針,但你給它一個指針。你不應該需要參數中的指針,只需要float state []。 – Julio 2012-07-20 15:16:07

+0

狀態和錯誤是輸出參數。我想修改它們是什麼。 – CodeKingPlusPlus 2012-07-20 15:18:37

回答

2
#include <stdio.h> 

void func(float (*state)[6], float (*err)[6][6]){ 
    printf("%f, %f\n", (*state)[2], (*err)[1][2]);//3.000000, 3.300000 
} 

int main() 
{ 
    float state[6]={1.0f,2.0f,3.0f}; 
    float err[6][6]={{1.0f,2.0f,3.0f},{1.1f,2.2f,3.3f}}; 

    func(&state, &err); 

    return 0; 
} 
+0

我只需要知道如何使它成爲(* state)[2]數組的指針。謝謝! – CodeKingPlusPlus 2012-07-23 19:06:34

+0

我的回答很好,能夠幫助。 – BLUEPIXY 2012-07-23 23:10:21

5

你的代碼更改爲:

void func(float state[], float err[][6]); 

int main() 
{ 
    float state[6]; 
    float err[6][6]; 

    func(state, err); 

    return 0; 
} 

要了解爲什麼,你需要知道float* err[6][6]是指針的6x6的陣列浮動,而不是一個指針浮動的6x6的陣列。

+0

因爲C按價值傳遞了所有東西,現在不會改變和錯誤嗎? – CodeKingPlusPlus 2012-07-20 15:29:12

+1

該數組的地址不會改變,但裏面的值將會改變。傳遞'state'實際上等同於傳遞數組中第一個元素的地址'&state [0]'。可能有些情況下,你會希望你的函數分配一個新的數組,在這種情況下,你必須使你的參數成爲'float **',但是之後沒有必要在堆棧上創建一個數組。 – Taum 2012-07-20 15:42:15

+0

爲什麼匿名倒票,我想知道? – 2012-07-20 21:32:49

1

儘管在一個函數內部,T [] []和T **幾乎可以互換使用,當它們作爲參數傳遞的時候有一些注意事項。 '指針指針'模式只使用足夠的內存來存儲變量本身(通常與處理器的字大小相同),並依賴程序員以某種方式爲數據生成正確的偏移量,而使用數組語法,編譯器也需要知道結構的步幅,以便它可以正確地處理行。就我個人而言,我不喜歡將數組作爲參數傳遞給它,只是因爲這個原因:它使編譯時的步長固定下來。在我看來,更好的做法是始終使用行和列輔助參數的T **路線。

2

在大多數情況下,數組類型的表達式將被轉換爲指針類型的表達式;這意味着當您將數組表達式作爲參數傳遞給函數時,函數將接收的是一個指針。數組表達式是sizeof或一元運算符&的操作數,或者是用於在聲明中初始化數組的字符串文字時,此規則的例外情況。

在函數參數聲明的上下文中,T a[]T a[N]的處理方式與T *a相同;所有這三個都聲明a作爲指向T的指針,而不是作爲T的數組。

因此,通過您聲明

float state[6]; 
float err[6][6]; 

表達state的類型去是「的float 6-元件陣列」,這在大多數情況下將被轉換爲「指針float」,或float *。類似地,表達式err的類型是「float的6元件陣列的6元件陣列」,其將被轉換爲「指向6元件陣列float」或float (*)[6]

類型表達&state的是「指針至6個元素的數組的float」,或float (*)[6],以及&err類型是「指針至6個元素的數組的float 6-元件陣列的」,或float (*)[6][6]

因此,如果調用func

func(&state, &err); 

那麼原型必須

void func(float (*state)[6], float (*err)[6][6]) 

,你需要明確取消引用stateerr應用任何標前:

(*state)[i] = ...; 
(*err)[i][j] = ...; 

如果電話是

func(state, err); 

那麼原型必須

void func (float *state, float (*err)[6]) 

,你會不會需要明確取消引用要麼stateerr

state[i] = ...; 
err[i][j] = ...; 

那麼,你用哪個呢?就我個人而言,我會選擇第二種選擇。它有點乾淨。

0
void func(float* state[6], float* err[6][6]); 


int main() 
{ 
    float state[6]; 
    float err[6][6]; 

    func(&state, &err); 

    return 0; 
} 

以下兩個聲明的兩個是相同的......

char *message = "Hello World!"; 
char message[13] = "Hello World!"; /* "Hello World!" is 12 chars + \0 termination */ 

數組是指針,只是區別對待。 因此,要將這兩個聲明中的message的地址傳遞給func1(char *)或func1(char []),則表示您通過地址傳遞func1(message);

數組只能作爲地址傳遞給第一個值。運行以下程序來證明這一事實。

#include <stdio.h> 
void func(float* array); 

int main() 
{ 
    float state[6]; 
    int i = 0; 
    printf ("Sizeof state: %d\n", sizeof(state)); 
    for (i = 0; i < 6; i ++) { state[i] = i+1; } 
    func(state); 

    return 0; 
} 

void func (float *array) 
{ 
printf ("Sizeof float: %d\n", sizeof(float)); 
printf ("Sizeof array: %d\n", sizeof(array)); 
printf ("Value in array[0] = %f\n", array[0]); 
printf ("Value in *array = %f\n", *array); 
array++; 
printf ("Value in array[-1] = %f\n", array[-1]); 
printf ("Value in array[0] = %f\n", array[0]); 
printf ("Value in *array = %f\n", *array); 
} 

,那麼你對func(float* state[6], float* err[6][6]);呼叫聲明2級指針,和一個3級指針。類似的功能,但相同的呼叫,可以實現與func(float **state, float ***err);

不用說,而不是你的目標。