[英]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.