簡體   English   中英

函數中的C指針

[英]C pointers in functions

在我的c應用程序中,我有以下聲明:

typedef double mat[MAX_SIZE][MAX_SIZE];

我還有一個全局變量:

mat aaa;

在函數中,我想執行以下操作:

void func2(mat ccc)
{
   ccc = aaa;
}

void func1()
{
    mat bbb;
    func2(bbb);
    bbb[1][2] = 3;
}

我希望在func2()之后對bbb進行的操作會影響全局變量aaa ,但它們不會。

關於為什么這種行為不是我期望的任何建議?

您需要使bbb成為指針並發送bbb的地址。

void func1()
{
    mat *bbb;
    func2(&bbb);
    (*bbb)[1][2] = 3;
}

然后像這樣編輯func2

void func2(mat **ccc){
    *ccc=&aaa;
}

您的類型mat不是指針類型,而是數組。 您不能在C中為數組變量賦值。解決問題的常用方法是使用指針:

void func1(void)
{
  mat *bbb = &aaa;
  (*bbb)[1][2] = 3;
}

您的意思是bbb[1][2] = 3; 會在aaa上完成嗎? 然后,您必須這樣做:

mat aaa;

mat* func2() {
    return &aaa;
}
void func1() {
    mat* bbb = func2();
    (*bbb)[1][2] = 3;
}

這段代碼中存在概念錯誤-數組表達式可能不是賦值的目標。 如果你想寫

void func1(void)
{
   mat bbb;
   bbb = aaa; 
   bbb[1][2] = 3;
}

編譯器將對表達式bbb = aaa進行診斷(gcc給出了“分配中的不兼容類型”診斷信息,因為aaa轉換為指針類型;更多內容請參見下文)。 通過將bbb傳遞給func2來嘗試執行的操作實際上是同一件事,並且最終將不起作用。

讓我們擺脫typedef,以便我們可以看到實際的類型

double aaa[MAX_SIZE][MAX_SIZE];
...
void func2(double (*ccc)[MAX_SIZE])
{
   ccc = aaa;
}

void func1()
{
  double bbb[MAX_SIZE][MAX_SIZE];
  func2(bbb);
  bbb[1][2] = 3;
}

除非它是sizeof的操作數或一元&運算符,或者是用於在聲明中初始化另一個數組的字符串文字,否則“ N的T元素數組”類型的表達式將被“指針”類型的表達式替換到T “,其值為數組的第一個元素的地址。 當你調用func2 ,表達bbb從類型“轉換MAX_SIZE的陣列MAX_SIZE的陣列double ”到“指針MAX_SIZE的陣列double ”; 因此,將ccc聲明為double (*ccc)[MAX_SIZE]

類似地,在func2 ccc = aaa中,表達式aaadouble [MAX_SIZE][MAX_SIZE]類型轉換為double (*)[MAX_SIZE]

到目前為止, func2是潔凈的,因為ccc是指針表達式,而不是數組表達式,因此允許分配。 ccc也恰好是與bbb完全不同的實體(它接收bbb求值的指針值的副本),因此寫入cccbbb沒有影響。 如果您嘗試通過傳遞指向bbb的指針來解決該問題,則如下所示:

void func2(double (*ccc)[MAX_SIZE][MAX_SIZE])
{
  *ccc = aaa;
}

void func1(void)
{
  double bbb[MAX_SIZE][MAX_SIZE];
  func2(&bbb);
  bbb[1][2] = 3;
}

編譯器將對*ccc = aaa拋出診斷,這可能是因為*ccc具有數組類型,或者是因為*cccaaa的類型不兼容(請記住, aaa被轉換為指針表達式)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM