簡體   English   中英

如何修復函數及其聲明的“沖突類型”?

[英]How to fix “conflicting types” for a function and its declaration?

我想將二維char數組傳遞給函數,但不知道如何在main()之前聲明該函數。 在我聲明它之前,該函數可以編譯並運行良好。 但是在聲明之后,我遇到了編譯問題。

我在MacBook Pro上使用EMACS。 編譯器是gcc。我試圖通過各種方式聲明函數打印字符串,包括

void printstring(int, int,char **);

要么

void printstring(int, int,char *); 

但是它們都不起作用。 我的完整代碼是:

#include<stdio.h>

#include<stdlib.h>

void printstring(int, int,char **);

int main(){
  char word[3][6]= {"hello","world","I"};
  printstring(3,6,word);
  return 0;
}

void printstring(int n, int m, char (*w)[m]){
  for (int i = 0; i < n; i++){
    printf("%s\n",w[i]);
  }
  return;
}

我希望沒有編譯錯誤,但我收到一個錯誤和一個警告。 詳細信息可以在下面找到:

test.c: In function 'main':
test.c:9:19: warning: passing argument 3 of 'printstring' from incompatible pointer type [-Wincompatible-pointer-types]
   printstring(3,6,word);
                   ^~~~
test.c:5:6: note: expected 'char **' but argument is of type 'char (*)[6]'
 void printstring(int, int,char **);
      ^~~~~~~~~~~
test.c: At top level:
test.c:13:6: error: conflicting types for 'printstring'
 void printstring(int n, int m, char (*w)[m]){
      ^~~~~~~~~~~
test.c:5:6: note: previous declaration of 'printstring' was here
 void printstring(int, int,char **);
      ^~~~~~~~~~~

問題是您使用的是可變長度數組。 最后一個參數(字符串列表)取決於第二個參數( m )。 char **不適合,因為它只是指針上的指針。 因此,在2D數組上進行迭代時,字符串的最大尺寸將丟失。

使用標准的前向聲明,如果您不想將函數放在主聲明之前,則完全復制真實的聲明。

void printstring(int n, int m, char (*w)[m]);

int main(){
  char word[3][6]= {"hello","world","I"};
  printstring(3,6,word);
  return 0;
}
void printstring(int n, int m, char (*w)[m]){
  for (int i = 0; i < n; i++){
    printf("%s\n",w[i]);
  }
  return;
}

如果您有只讀字符串,建議您使用標准的常量指針數組代替:

void printstring(int n, const char *w[]);

int main(){
  const char *word[] = {"hello","world","I"};
  printstring(3,word);
  return 0;
}
void printstring(int n, const char *w[])
{
  for (int i = 0; i < n; i++){
    printf("%s\n",w[i]);
  }
  return;
}

注意

printstring(3,word);

可以替換為

printstring(sizeof(word)/sizeof(word[0]),word);

在數組衰減到指針之前(會自動計算字符串數)

以下應該可以正常工作:

void printstring(int n, int m, char (*w)[m]);

函數原型和定義應保持相同,除了某些限定符(例如C ++中的const和默認參數)外。

如果出於任何原因要保留無名稱聲明,則可以將*表示法(保留給函數原型作用域)用於可變類型

void printstring(int, int,char (*)[*]);

仍然是VLA,實際上與使用m的符號完全等效。 盡管從表面上看,它傳達的意圖不如在前向聲明中使用m清楚。

char**不能用於指向2D數組,它只能用於指向char*的1D數組的第一個元素,這是其他內容。

您的編譯器錯誤來自於聲明和定義不匹配。 正確的代碼:

void printstring(int n, int m, char w[n][m]);

...

void printstring(int n, int m, char w[n][m]){
  ...
}

或者,您可以編寫void printstring(int n, int m, char (*w)[m]) ,它是完全等效的。 但這很難讀,所以為什么呢?

暫無
暫無

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

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