我正在嘗試使用 2d 陣列的指標創建一個減法函式,但是當我運行它時,我得到了
運算式必須具有指向物件的型別,但它的型別為“int”C/C (142)
誰能解釋為什么我會收到此錯誤以及解決此問題的更好方法是什么?
這是我的代碼
讀取陣列的函式
int *readMatrix(int *arr)
{
for (int i = 0; i < 3; i)
{
for (int j = 0; j < 4; j)
{
printf("row %d, col %d: ", i 1, j 1);
scanf("%d", &arr[i * 4 j]);
}
}
printf("\n");
return arr;
}
減去 2 個二維陣列的函式
int *subM(int *arrA, int*arrB, int *arrC){
for (int i = 0; i < 3; i)
{
for (int j = 0; j < 4; j)
{
//printf("row %d, col %d: ", i 1, j 1);
&arrC[i][j] = &arrA[i][j] - &arrB[i][j]; //code where I am getting error
}
}
return arrC;
}
主功能
int main()
{
int arrA[3][4];
int arrB[3][4];
int arrC[3][4];
readMatrix(&arrA[3][4]);
readMatrix(&arrB[3][4]);
subM(&arrA[3][4],&arrB[3][4],&arrC[3][4]);
return 0;
}
uj5u.com熱心網友回復:
我是 StackOverflow 的新手。如果我不能很好地表達自己,我很抱歉,但我想我找到了解決你問題的方法。
讓我們一步一步地運行它。
- 將陣列傳遞給函式時,不需要撰寫下標。
這意味著,而不是這個:
readMatrix(&arrA[3][4]);
寫這個:
readMatrix(arrA);
您還可以(實際上應該)洗掉指標運算子 (&),因為當僅使用陣列名稱時,它會自動充當指標。
現在讓我們看一下readMatrix的定義。
int *readMatrix(int *arr)
對多維陣列使用指標是可以的,但是編譯器會發出很多警告。
最標準的方法是在函式定義中使用下標:
int *readMatrixStandard(int arr[3][4])
{
for (int i = 0; i < 3; i)
{
for (int j = 0; j < 4; j)
{
printf("row %d, col %d: ", i 1, j 1);
scanf("%d", &arr[i][j]);
}
}
printf("\n");
return arr;
}
- subM 中的下標
對于您的情況,有兩種方法可以訪問多維陣列。
要么告訴編譯器這個函式需要一個多維陣列:
而不是這個:
int *subM(int *arrA, int*arrB, int *arrC)...
做這個:
int *subM(int arrA[3][4], int arrB[3][4], int arrC[3][4])...
然后代碼看起來像這樣:
int *subMMultiDimension(int arrA[3][4], int arrB[3][4], int arrC[3][4]){
for (int i = 0; i < 3; i)
{
for (int j = 0; j < 4; j)
{
//printf("row %d, col %d: ", i 1, j 1);
arrC[i][j] = arrA[i][j] - arrB[i][j]; //code where I am getting error
printf("]", arrC[i][j]);
}
puts(""); // for newline
}
return arrC;
}
或者使用一些 C/C 獨有的指標魔法 :) (不要與上面的解決方案結合使用)
而不是這個:
int *subM(int *arrA, int*arrB, int *arrC){
for (int i = 0; i < 3; i)
{
for (int j = 0; j < 4; j)
{
//printf("row %d, col %d: ", i 1, j 1);
&arrC[i][j] = &arrA[i][j] - &arrB[i][j]; //code where I am getting error
}
}
return arrC;
}
嘗試這個:
int *subM(int *arrA, int *arrB, int *arrC){
for (int i = 0; i < 3; i)
{
for (int j = 0; j < 4; j)
{
//printf("row %d, col %d: ", i 1, j 1);
arrC[i * 4 j] = arrA[i * 4 j] - arrB[i * 4 j]; //code where I am getting error
}
}
return arrC;
}
使用其中一種方式,但第一種似乎更標準,因為編譯器不會在第一種上拋出警告。
- 回傳值
您可能會看到這是怎么回事。我現在只是拍打代碼。
代替:
return arr;
return arrC;
我更喜歡這個來減少警告:
return arr[0];
return arrC[0];
原因很簡單。它實際上指向同一個地址,但它讓編譯器閉嘴。
我想就是這樣。最終代碼如下所示:
#include <stdio.h>
int * readMatrixStandard(int arr[3][4])
{
for (int i = 0; i < 3; i)
{
for (int j = 0; j < 4; j)
{
printf("row %d, col %d: ", i 1, j 1);
scanf("%d", &arr[i][j]);
}
}
printf("\n");
return arr[0];
}
int * subMMultiDimension(int arrA[3][4], int arrB[3][4], int arrC[3][4])
{
for (int i = 0; i < 3; i)
{
for (int j = 0; j < 4; j)
{
//printf("row %d, col %d: ", i 1, j 1);
arrC[i][j] = arrA[i][j] - arrB[i][j]; //code where I am getting error
printf("]", arrC[i][j]);
}
puts(""); // for newline
}
return arrC[0];
}
int main(void) // I recommend to always write void here if you are not using
// an old compiler
{
int arrA[3][4];
int arrB[3][4];
int arrC[3][4];
readMatrixStandard(arrA);
readMatrixStandard(arrB);
subMMultiDimension(arrA,arrB,arrC);
return 0;
}
編譯良好,沒有警告。
這些代碼片段只是我的建議。如果您想知道在 C 中做某事的最標準方法,您可能需要查找它。還推薦一本好書。例如,我用 Stephan Prata 的 C Primer Plus 學習了 C。一本很棒的書,其中包含大量示例和插圖,可幫助您了解情況。
再次對不起我的英語。估計還有很長的路要走。
如果我遺漏了什么或在某處犯了錯誤,請告訴我。
uj5u.com熱心網友回復:
幾個問題...
readMatrix
使用int *arr
arg [正確]。但是,我們希望這與sumM
sumM
使用int *
args,但嘗試使用 2D 陣列語法取消參考它們。- 在
sumM
中,使用 (eg)&arr[i][j]
是元素的地址,而不是它的值[這是我們想要的]。 - 在
main
中,我們正在傳遞 (eg)&arr[3][4]
。這指向陣列的末尾,所以這是 UB(未定義的行為)。我們想要傳遞陣列的起始地址(例如arr
or&arr[0][0]
)。 - 無需將指標傳回結果陣列,因為呼叫者將地址作為 args 傳入。
這是重構的代碼。注釋如下:
#include <stdio.h>
// Function to read array
#if 0
int *
readMatrix(int *arr)
#else
void
readMatrix(int arr[3][4])
#endif
{
for (int i = 0; i < 3; i) {
for (int j = 0; j < 4; j) {
printf("row %d, col %d: ", i 1, j 1);
#if 0
scanf("%d", &arr[i * 4 j]);
#else
scanf("%d", &arr[i][j]);
#endif
}
}
printf("\n");
#if 0
return arr;
#endif
}
// Function to subtract 2 2d arrays
#if 0
int *
subM(int *arrA, int *arrB, int *arrC)
#else
void
subM(int arrA[3][4], int arrB[3][4], int arrC[3][4])
#endif
{
for (int i = 0; i < 3; i) {
for (int j = 0; j < 4; j) {
// printf("row %d, col %d: ", i 1, j 1);
// NOTE/BUG: we want to use the _values_ and _not_ the _addresses_ of the
// array elements
#if 0
&arrC[i][j] = &arrA[i][j] - &arrB[i][j];
#else
arrC[i][j] = arrA[i][j] - arrB[i][j];
#endif
}
}
// NOTE/BUG: since caller passed in the array, it knows where it is
#if 0
return arrC;
#endif
}
// Main Function
int
main(void)
{
int arrA[3][4];
int arrB[3][4];
int arrC[3][4];
// NOTE/BUG: doing (e.g.) &arrA[3][4] points past the _end_ of the 2D array
// and, so, is UB (undefined behavior) -- we want to pass the start address
#if 0
readMatrix(&arrA[3][4]);
readMatrix(&arrB[3][4]);
subM(&arrA[3][4], &arrB[3][4], &arrC[3][4]);
#else
readMatrix(arrA);
readMatrix(arrB);
subM(arrA, arrB, arrC);
#endif
return 0;
}
在上面的代碼中,我使用cpp
條件來表示舊代碼和新代碼:
#if 0
// old code
#else
// new code
#endif
#if 1
// new code
#endif
注意:這可以通過運行檔案來清理unifdef -k
uj5u.com熱心網友回復:
根據下標運算子[]
的定義,運算式
A[B]
相當于:
*(A B)
所以,
A[B][C]
相當于:
*( *(A B) C )
如果您將此應用于該行
&arrC[i][j] = &arrA[i][j] - &arrB[i][j];
它相當于:
&( *( *(arrC i) j ) ) = *( *(arrA i) j ) - *( *(arrB i) j );
表達方式
&( *( *(arrC i) j ) )
無效,原因如下:
子運算式
*(arrC i)
有 type int
,因為取消參考 an會int *
產生一個int
. 因此,子運算式
*(arrC i) j
也將評估為int
.
在評估該子運算式之后,您然后嘗試int
使用*
運算子取消參考該子運算式,這是非法的。只有指標型別可以被取消參考。
子運算式
*( *(arrA i) j )
和
*( *(arrB i) j )
有完全相同的問題。您還在int
這兩個運算式中取消參考 an 。
實際問題是您subM
使用以下引數宣告了該函式:
int *subM(int *arrA, int *arrB, int *arrC)
在 C 中,陣列通常通過將(可能衰減的)指標傳遞給(外部)陣列的第一個元素來傳遞給函式。
因此,如果您將一維陣列傳遞給函式,則引數型別int *
將是正確的,但對于二維陣列則不正確。這是因為指向 2Dint
陣列的外部陣列的第一個元素的指標具有您的情況的型別int (*)[4]
,即指向 4 個int
元素的 1D 陣列的指標。但是,您傳遞的是指向單個int
物件(而不是陣列)的指標,因此您傳遞的指標型別錯誤。
因此,您應該將引數型別更改為以下內容:
int *subM( int (*arrA)[4], int (*arrB)[4], int (*arrC)[4] )
用下面的方式寫這個可能更清楚:
int *subM( int arrA[3][4], int arrB[3][4], int arrC[3][4] )
這兩行是等效的,因為陣列在用作函式引數時會衰減為指標。
此外,您應該更改呼叫函式的方式。你應該換行
subM(&arrA[3][4],&arrB[3][4],&arrC[3][4]);
至:
subM( arrA[3], arrB[3], arrC[3] );
由于陣列到指標衰減,這一行相當于:
subM( &arrA[3][0], &arrB[3][0], &arrC[3][0] );
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/527917.html
標籤:数组C指针