2017-09-19 37 views
1

私にとって厄介な部分は、データが正しく入力されたかどうかをテストするためにちょうど使用したforのループで、最後にprintfを使って出力されます。私が入力したデータを印刷するために使用される3つのアクセス方法は、私にはあまり明確ではありません。構造体にポインタを持つ構造体へのポインタの配列

アクセス方法#1名前にアクセスする矢印演算子を1つだけ使用してデータを正しく印刷できました。私の周りを包み込むことができない部分は、なぜエラーなしでデータにアクセスできるのですか?私はそれぞれのproduction_plant_employees構造体にアクセスするためにインデックスを使用しました。私は括弧が参照解除を行うことを知っていますが、まだ何が起こっているのか分かりません。私はこのような部分を書こうとしました:*(production_plant_employees + i)、しかしそれは動作しませんでした。

アクセス方法#2は私にはっきりと分かります。

アクセス方法#3これは私が動作すると思ったものですが、拒否します。書き込まれると、IDEにエラーは表示されませんが、プログラムを実行すると停止します。

私はを通じて行ってきたとき、私は、その後、(production_plant_employeesです)最初のポインタの最初のデータへのアクセスになって、その後、その後、(構造体employeeであるポインタbasic_infoである)第2のポインタ内のデータにアクセスし、しています2ポインタ、私は後に(名前、年齢など...)、非常にデータにアクセス、右か?

また、私が行ったデータにアクセスする他の方法を教えてください。

typedef struct basicdata{ 
    char name[15]; 
    char last_name[15]; 
    char gender[2]; 
    int age; 
    char birthplace[15]; 
    char address[15]; 
} BASICDATA; 

typedef struct job_info { 
    int employment_year; 
    char job_position[20]; 
    char employee_pay_grade[10]; 
    int employee_grade; 
} JOB_INFO; 

typedef struct employee{ 
    BASICDATA *basic_info; 
    JOB_INFO *job_info; 
} EMPLOYEE; 


int main() { 

    int i; 
    int choice = 0; 

    EMPLOYEE *production_plant_employees; 

    printf("Enter number of employees : \n"); 
    scanf("%d", &choice); 

    production_plant_employees = (EMPLOYEE*)calloc(choice, sizeof(EMPLOYEE)); 
    if (production_plant_employees == NULL) { 
     printf("An error occured during memory allocation\n"); 
    } 

    for(i = 0; i < choice; ++i) { 
     production_plant_employees[i].basic_info = (BASICDATA*)calloc(choice, sizeof(BASICDATA)); 
     if(production_plant_employees[i].basic_info == NULL) { 
      printf("An error occured during memory allocation\n"); 
     } 

     production_plant_employees[i].job_info = (JOB_INFO*)calloc(choice, sizeof(JOB_INFO)); 
     if(production_plant_employees[i].job_info == NULL) { 
      printf("An error occured during memory allocation\n"); 
     } 

     printf("production_plant_employees[%d].basic_info = %d\t%x\n", i, production_plant_employees[i].basic_info, production_plant_employees[i].basic_info); 
     printf("production_plant_employees[%d].job_info = %d\t%x\n", i, production_plant_employees[i].job_info, production_plant_employees[i].job_info); 
    } 

    for(i = 0; i < choice; ++i) { 
     fflush(stdin); 
     printf("Enter name : \n"); 
     fgets(production_plant_employees[i].basic_info->name, 15, stdin); 

     printf("Name of %d. employee : %s", i, production_plant_employees[i].basic_info->name) //access method#1 
     printf("Name of %d. employee : %s", i, (production_plant_employees + i)->basic_info->name); //access method #2 
     printf("Name of %d. employee : %s", i, *(*(production_plant_employees +i)).basic_info->name); //access method #3 ---> why isn't this working? 
     printf("\n\n"); 
    } 
    return 0; 
} 
+4

ポインタを印刷し、 '%p'書式指定子とキャストを使用それらを 'void * 'に置き換えます:' printf( "production_plant_employees [%d] .basic_info =%p"、i、(vo id *)production_plant_employees [i] .basic_info); 'fflush(stdin);は未定義の動作です。 – yano

+0

関連する演算子の相対的な優先順位と結合性を調べます。特に、メンバ選択( '.')と間接メンバ選択(' - ')演算子に対する逆参照演算子(' * ')の優先順位を見てください。 –

答えて

3

それを行うための正しい方法は、(アクセス方法3用)です:私たちは、ポインタproduction_plant_employees +iを参照解除することから始め

printf("Name of %d. employee : %s", i, (*(*(production_plant_employees +i)).basic_info).name); 

まず、今、我々はする必要が&ポインタでもあるメンバーbasic_infoアクセス2番目の*を使用して参照解除され、ローカルメンバーnameにアクセスします。

ptr1 = production_plant_employees +i 
ptr2 = (*ptr1).basic_info 
data = (*ptr2).name 

そしてこうして(dataptr2を代入:

data = (*(*ptr1).basic_info).name 

&を最後にptr1を代入して:

data = (*(*(production_plant_employees +i)).basic_info).name 
+0

ああ、少年...とても早く答えるとありがとう、ありがとう:D Btw。私は数分前にとても近づきました。どうもありがとう! – Apollo

関連する問題