簡體   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