简体   繁体   English

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

[英]Pass a string in a struct to a function and return it

I want to return the name of the smallest city population-wise, if it is the second city.如果是第二个城市,我想返回人口最少的城市的名称。 (Please don't mind the if statement, I know it's bland), the missing return is what bothers me. (请不要介意 if 语句,我知道它很乏味),缺少 return 是困扰我的问题。

I assume I should declare a pointer inside the function rSmallestCity , like *rtrn but I guess the source variable is destroyed before it is used?我假设我应该在函数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));
}

warning: assignment to 'char ' from incompatible pointer type 'char ( )[20]' [-Wincompatible-pointer-types]|警告:从不兼容的指针类型 'char ( )[20]' [-Wincompatible-pointer-types]| 赋值给 'char '

I assume I should declare a pointer inside the function rSmallestCity, like *rtrn but I guess the source variable is destroyed before it is used?我假设我应该在函数 rSmallestCity 中声明一个指针,比如 *rtrn 但我猜源变量在使用之前被销毁了?

A good question.一个好问题。 And your assumption is correct.而且你的假设是正确的。 Creating a variable inside a function it's existence ends upon leaving the function.在函数内部创建一个变量,它的存在在离开函数时结束。 But in this case, because the struct member name is already a char * you do not need to create another variable.但在这种情况下,因为结构成员name已经是一个char *不需要创建另一个变量。 Just return c1.name .只需返回c1.name (see code example below.) (请参阅下面的代码示例。)

A few other suggestions:其他一些建议:

In the struct declaration:在结构声明中:

typedef struct Coordinate{
    int x,y;
}Coordinate;

You've used the same symbol ( Coordinate ) for the struct name, and for it's typedef.您已经对结构名称和 typedef 使用了相同的符号 ( Coordinate )。 This is not a good practice.这不是一个好的做法。 If you need both a struct name and a typedef, pick different symbols.如果您需要结构名称和类型定义,请选择不同的符号。 BTW, in this this example, only one or the other is needed.顺便说一句,在这个例子中,只需要一个或另一个。 Say you pick the typedef, then the struct is completely defined by:假设您选择了 typedef,那么该结构完全由以下定义:

typedef struct {
    int x,y;
}Coordinate;

That suggestion applies to both struct declarations in your example code.该建议适用于示例代码中的两个struct声明。

The signatures for the main function do not include int main(){...} rather main函数的签名不包括int main(){...}而不是
int main(void){..., return 0;} and int main(int argc, char *argv[]){..., return 0;} int main(void){..., return 0;}int main(int argc, char *argv[]){..., return 0;}

The following code example illustrates some of the other suggestions for improvements in comments under your post,以下代码示例说明了一些其他改进帖子下评论的建议,

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;
};

The solution that I originally left in comment under OP (remove & in the line &cl[n-1]->name; ) needs some explanations to avoid problems later.我最初在 OP 下的评论中留下的解决方案(删除& &cl[n-1]->name;行中的&cl[n-1]->name; )需要一些解释以避免以后出现问题。

(It is an educational answer not a full answer on pointers, array decay, ... And many examples can be found on stackoverflow. I tried to simplify) (这是一个有教育意义的答案,而不是关于指针、数组衰减等的完整答案……并且在 stackoverflow 上可以找到许多示例。我试图简化)

Try this simple code.试试这个简单的代码。

int main()
{
    char myString1[25]="Toulouse" ; // French City
    printf("%p\n",myString1);
    printf("%p\n",&myString1);
}

The output is the same, but an array name and the address of an array name are not the same.输出是一样的,但是数组名和数组名的地址不一样。 The array name is evaluated to the address of its first element.数组名称被评估为其第一个元素的地址。 So it works in your case but a warning is issued during compilation and it is very important.所以它适用于您的情况,但在编译期间会发出警告,这非常重要。 Firstly, do not remove compilation warnings.首先,不要删除编译警告。

Now, try this code :现在,试试这个代码:

int main()
{
    char myString1[25]="Toulouse" ; // French City
    printf("%p\n",myString1+1);
    printf("%p\n",&myString1+1);
}

The outputs are different.输出不同。 Because myString1 is evaluated to char* and &myString1 to char [25] .因为myString1被评估为char*&myString1 myString1被评估为char [25] So +1 , in the first, case adds one ( sizeof char ) to the pointer and in the other case, it adds 25.所以+1 ,在第一种情况下, case 添加一个( sizeof char )到指针,在另一种情况下,它添加 25。

Delete the "&" in the line: rtrn = &cl[n-1]->name;删除行中的“&”: rtrn = &cl[n-1]->name;

To extremely simplify, you assigned an "address of char[] " to a char* , but array syntax makes it work regardless.为了极度简化,您将“ char[]地址”分配给了一个char* ,但无论如何数组语法使它都能工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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