簡體   English   中英

為什么當我在主 function 之外初始化結構成員時,這個 c 程序會出錯?

[英]Why this c-program gives error when I initialize structure member outside the main function?

為什么當我在main function 之外初始化結構成員( user.usernameuser.pin )時,這個 c 程序會出錯?但是當我在main function 中初始化它時,一切都會好起來的。

還有什么方法可以初始化 char 數組(結構成員)?

#include <stdio.h>

typedef struct {
    int pin;
    char username[20];
} portal;

portal user;

// user.username = "alex"; 
// user.pin[20] = 1234;  //Why this gives error when I intialize it here(i.e outside the main function)?

int main() {
    user.username = "alex"; //How to intialize a memeber(having type char) of structure?
    user.pin[20] = 1234;

    printf("WELCOME TO PORTAL\n");
    printf("ENTER YOUR USERNAME:\n");
    scanf("%[^\n]%*c", user.username);
    .
    .
    .

實際上,當我在main function 之外初始化user.username時,我得到了這個 output。

在此處輸入圖像描述

// user.username = "alex"; // user.pin[20] = 1234; //為什么我在這里初始化它時會出錯(即在主函數之外)?

這不是初始化。 這是賦值語句。 外部函數您只能放置聲明而不是語句。

此外,即使作為陳述,它們也是不正確的。

查看您的結構定義

typedef struct
{
 int pin;
 char username[20];
}portal;

數據成員pin的類型為int 它不是一個數組。 所以這個任務

user.pin[20] = 1234;

沒有意義。 你至少應該寫

user.pin = 1234;

另一方面,數據成員username是一個字符數組。 Arrays 沒有賦值運算符。 您必須將字符串復制到字符數組中。 例如

#include <string.h>

//...

strcpy( user.username, "alex" );

但是您可以在聲明 object user時對其進行初始化。 例如

portal user = { 1234, "alex" };

或者

portal user = { .pin = 1234, .username = "alex" };

這是一個演示程序

#include <stdio.h>

typedef struct
{
    int pin;
    char username[20];
} portal;

portal user = { .pin = 1234, .username = "alex" };

int main(void) 
{
    printf( "pin = %d, user name = %s\n", user.pin, user.username );

    return 0;
}

程序 output 是

pin = 1234, user name = alex

全局變量可以初始化為定義點,但不能作為獨立語句:

portal user = { 1234, "alex" };  // definition with an initializer

user.pin = 1234;        // assignment is invalid outside a function
user.username = "Alex"; // assignment is invalid outside a function and assigning to an array is invalid as well

結構成員可以在 function 中設置,但 arrays 內容不能用=運算符分配,您需要顯式分配數組元素或使用 function 調用:

int main() {
    char extra[20];

    user.pin = 1234;         // OK

    user.username[0] = 'A';  // tedious, but OK
    user.username[0] = 'l';
    user.username[0] = 'e';
    user.username[0] = 'x';
    user.username[0] = '\0'; 

    strcpy(user.username, "Alex"); // OK if username has at least 5 elements

    snprintf(user.username, sizeof user.username, "%s", "Alex"); // overkill, but OK

    // read values from stdin:
    // scanf will return the number of members successfully converted:
    switch (scanf("%d%19s%19[^\n]", &user.pin, user.username, extra)) {
      case EOF:
        printf("premature end of file\n");
        break;
      case 0:
        printf("input is not a number for user.pin\n");
        break;
      case 1:
        printf("user.pin=%d, no input for user.username\n", user.pin);
        break;
      case 2:
        printf("user.pin=%d, user.username=%s\n", user.pin, user.username);
        break;
      case 3:
        printf("user.pin=%d, user.username=%s, extra input=%s\n", user.pin, user.username, extra);
        break;
    }
    return 0;
}

在 C 中,在函數之外,您只能有聲明和預處理器指令。 源文本user.username = "alex"; 是一個語句, user.pin[20] = 1234; . 出現編譯器錯誤消息是因為編譯器需要聲明,而您的語句不符合預期。

要在定義對象時對其進行初始化,請使用帶有定義的初始化語法,而不是編寫單獨的語句。 user可以使用以下任一方式定義和初始化:

portal user = { "alex", 1234 };
portal user = { .username = "alex", .pin = 1234 };

盡管定義在初始化中使用= ,但這不是賦值。 這是對類似效果的=符號的不同用法(將此值放在那個位置)。 另一個區別是,在初始化中,您可以使用字符串文字來初始化字符數組。 在一份聲明中,你不能。

user提供初始值的另一種方法是在main中編寫語句:

int main(void)
{
    strcpy(user.username, "alex");
    user.pin = 1234;
    …
}

該結構成員已經初始化。 當您在main之外執行此操作時,編譯器可以通過立即將其設置為字符串文字來對其進行優化。

如果輸入了main ,那么初始化為時已晚。 編譯器不假設main保證被調用或立即調用。 因此main中的語句不是初始化而是賦值。 您不能分配給字符數組,這就是strcpy和相關函數的用途。

這應該有效:

strcpy(user.username, "Alex")

或者

snprintf(user.username, sizeof user.username, "Alex");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM