繁体   English   中英

将结构体中的字符串传递给函数并返回

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM