57

私は新しいCプログラマーでありstruct、関数にパススルーする方法を知りたいと思っていました。エラーが発生し、それを行うための正しい構文を理解できません。これがそのコードです。

構造体:

struct student{
    char firstname[30];
    char surname[30];
};

struct student person;

電話:

addStudent(person);

プロトタイプ:

void addStudent(struct student);

および実際の機能:

void addStudent(person)
{
    return;
}

コンパイラエラー:

21行目:警告:疑わしいタグ宣言:struct student
行223:引数#1はプロトタイプと互換性がありません:

4

5 に答える 5

118

これは、参照によって渡す方法structです。これは、関数が関数のstruct外部にアクセスしてその値を変更できることを意味します。これを行うには、構造体へのポインターを関数に渡します。

#include <stdio.h>
/* card structure definition */
struct card
{
    int face; // define pointer face
}; // end structure card

typedef struct card Card ;

/* prototype */
void passByReference(Card *c) ;

int main(void)
{
    Card c ;
    c.face = 1 ;
    Card *cptr = &c ; // pointer to Card c

    printf("The value of c before function passing = %d\n", c.face);
    printf("The value of cptr before function = %d\n",cptr->face);

    passByReference(cptr);

    printf("The value of c after function passing = %d\n", c.face);

    return 0 ; // successfully ran program
}

void passByReference(Card *c)
{
    c->face = 4;
}

structこれは、関数がのコピーを受け取り、structそれを変更するために外部構造にアクセスできないように、by値を渡す方法です。外部とは、機能の外部を意味します。

#include <stdio.h>


/* global card structure definition */
struct card
{
    int face ; // define pointer face
};// end structure card

typedef struct card Card ;

/* function prototypes */
void passByValue(Card c);

int main(void)
{
    Card c ;
    c.face = 1;

    printf("c.face before passByValue() = %d\n", c.face);

    passByValue(c);

    printf("c.face after passByValue() = %d\n",c.face);
    printf("As you can see the value of c did not change\n");
    printf("\nand the Card c inside the function has been destroyed"
        "\n(no longer in memory)");
}


void passByValue(Card c)
{
    c.face = 5;
}
于 2012-11-25T21:45:02.027 に答える
47

ライン関数の実装は次のようになります。

void addStudent(struct student person) {

}

personは型ではなく変数であるため、関数パラメーターの型として使用することはできません。

また、プロトタイプが使用する関数のプロトタイプの前に、構造体が定義されていることを確認してくださいaddStudent

于 2012-04-29T05:54:08.287 に答える
10

構造体を別の関数に渡すときは、通常、Donnellが上記で提案したように実行し、代わりに参照によって渡す方が適切です。

これの非常に良い理由は、インスタンスを作成した関数に戻ったときに反映される変更を加えたい場合に、作業が簡単になることです。

これを行う最も簡単な方法の例を次に示します。

#include <stdio.h>

typedef struct student {
    int age;
} student;

void addStudent(student *s) {
    /* Here we can use the arrow operator (->) to dereference 
       the pointer and access any of it's members: */
    s->age = 10;
}

int main(void) {

    student aStudent = {0};     /* create an instance of the student struct */
    addStudent(&aStudent);      /* pass a pointer to the instance */

    printf("%d", aStudent.age);

    return 0;
}

この例では、関数の引数はstruct-addStudent()のインスタンスへのポインターです。では、構造体のインスタンスを作成し、参照演算子()を使用してそのインスタンスへの参照を関数に渡します。studentstudent *smain()studentaddStudent()&

このaddStudent()関数では、矢印演算子(->)を使用してポインターを間接参照し、そのメンバーのいずれかにアクセスできます(機能的には:と同等です(*s).age)。

関数に加えた変更は、addStudent()に戻るときに反映されmain()ます。これは、ポインターが、構造体のインスタンスstudentが格納されているメモリ内の場所への参照を提供するためです。これはprintf()、この例では「10」を出力するで示されています。

参照を渡さなかった場合、実際には関数に渡した構造体のコピーを使用していることになります。つまりmain、新しいバージョンを渡す方法を実装しない限り、に戻ったときに変更が反映されることはありません。それらの線に沿ってメインまたは何かに戻って構造化してください!

ポインターは最初は不快に思えるかもしれませんが、ポインターがどのように機能するのか、なぜポインターが非常に便利なのかを理解すると、ポインターが第二の性質になり、ポインターなしでどのように対処したのか疑問に思います。

于 2013-03-11T02:43:29.633 に答える
4

あなたは人のタイプを指定する必要があります:

void addStudent(struct student person) {
...
}

また、構造体をtypedefして、使用するたびに構造体を入力する必要がないようにすることもできます。

typedef struct student{
...
} student_t;

void addStudent(student_t person) {
...
}
于 2012-04-29T06:00:13.143 に答える
0

それ以外の:

void addStudent(person)
{
    return;
}

これを試して:

void addStudent(student person)
{
    return;
}

'student'という構造体をすでに宣言しているので、関数の実装で次のように指定する必要はありません。

void addStudent(struct student person)
{
    return;
}
于 2013-11-25T01:28:24.057 に答える