[英]Pass a string in a struct to a function and return it
如果是第二個城市,我想返回人口最少的城市的名稱。 (請不要介意 if 語句,我知道它很乏味),缺少 return 是困擾我的問題。
我假設我應該在函數rSmallestCity
聲明一個指針,比如*rtrn
但我猜源變量在使用之前被銷毀了?
typedef struct Coordinate{
int x,y;
}Coordinate;
typedef struct city{
char name[20];
int population;
Coordinate coordinates;
}city;
char *rSmallestCity(city **cl, int n)
{
char *rtrn = NULL;
if(cl[n-2]->population>cl[n-1]->population)
{
rtrn = &cl[n-1]->name;
}
return rtrn;
}
int main()
{
city c1 ={.name="Mumbai", .population=310, .coordinates.x=3, .coordinates.y=4};
city c2 ={.name="Delhi", .population=300, .coordinates.x=3, .coordinates.y=2};
city *clist[2];
clist[0]=&c1;
clist[1]=&c2;
printf("\n%s is smallest\n",rSmallestCity(clist,2));
}
警告:從不兼容的指針類型 'char ( )[20]' [-Wincompatible-pointer-types]| 賦值給 'char '
我假設我應該在函數 rSmallestCity 中聲明一個指針,比如 *rtrn 但我猜源變量在使用之前被銷毀了?
一個好問題。 而且你的假設是正確的。 在函數內部創建一個變量,它的存在在離開函數時結束。 但在這種情況下,因為結構成員name
已經是一個char *
不需要創建另一個變量。 只需返回c1.name
。 (請參閱下面的代碼示例。)
其他一些建議:
在結構聲明中:
typedef struct Coordinate{
int x,y;
}Coordinate;
您已經對結構名稱和 typedef 使用了相同的符號 ( Coordinate
)。 這不是一個好的做法。 如果您需要結構名稱和類型定義,請選擇不同的符號。 順便說一句,在這個例子中,只需要一個或另一個。 假設您選擇了 typedef,那么該結構完全由以下定義:
typedef struct {
int x,y;
}Coordinate;
該建議適用於示例代碼中的兩個struct
聲明。
main
函數的簽名不包括int main(){...}
而不是
int main(void){..., return 0;}
和int main(int argc, char *argv[]){..., return 0;}
以下代碼示例說明了一些其他改進帖子下評論的建議,
typedef struct {
int x,y;
}Coordinate;
typedef struct {
char name[20];
int population;
Coordinate coordinates;
}city;
//return char * rather than char to allow for full null terminated char array (string)
char * rSmallestCity(city c1[],int cityCount)//generisize function prototype to
{ //to easily accommodate bigger arrays if needed
long long size, sizeKeep = 8e9; //index and population. initialize larger than possible population
int indexKeep = 0;
//note you do not need to define a char *, the struct already contains one
for(int i=0; i<cityCount; i++)//use a loop rather than a single comparison, keep the smalles
{
size = c1[i].population;
sizeKeep = (size < sizeKeep) ? indexKeep = i, size : sizeKeep;
}
printf("\n%s\n",c1[indexKeep].name);
return c1[indexKeep].name;
};
int main(void)//use minimum signature for main, and call return before leaving.
{
//combining your original declarations and assignments for struct
//into a single declaration/definition.
city c1[] = {{.name="Mumbai", .population=310, .coordinates.x=3, .coordinates.y=4},
{.name="Delhi", .population=300, .coordinates.x=3, .coordinates.y=2}};
int cityCount = sizeof(c1)/sizeof(c1[0]);
printf("\n%s is smallest",rSmallestCity(c1, cityCount));
return 0;
};
我最初在 OP 下的評論中留下的解決方案(刪除&
&cl[n-1]->name;
行中的&cl[n-1]->name;
)需要一些解釋以避免以后出現問題。
(這是一個有教育意義的答案,而不是關於指針、數組衰減等的完整答案……並且在 stackoverflow 上可以找到許多示例。我試圖簡化)
試試這個簡單的代碼。
int main()
{
char myString1[25]="Toulouse" ; // French City
printf("%p\n",myString1);
printf("%p\n",&myString1);
}
輸出是一樣的,但是數組名和數組名的地址不一樣。 數組名稱被評估為其第一個元素的地址。 所以它適用於您的情況,但在編譯期間會發出警告,這非常重要。 首先,不要刪除編譯警告。
現在,試試這個代碼:
int main()
{
char myString1[25]="Toulouse" ; // French City
printf("%p\n",myString1+1);
printf("%p\n",&myString1+1);
}
輸出不同。 因為myString1
被評估為char*
, &myString1
myString1
被評估為char [25]
。 所以+1
,在第一種情況下, case 添加一個( sizeof char
)到指針,在另一種情況下,它添加 25。
刪除行中的“&”: rtrn = &cl[n-1]->name;
為了極度簡化,您將“ char[]
地址”分配給了一個char*
,但無論如何數組語法使它都能工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.