2010-01-10 64 views
1

在(重新)学习C的阶段中,我经常遇到数组和结构(和指针)的问题。这是我写的一个小测试。C:结构和数组 - 概述和帮助需要

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

typedef struct { 
    char name[10]; 
} man; 

int main (int argc, const char * argv[]) { 
    int i; 
    man john; 
    strcpy(john.name, "john"); 

    // array of structures 
    man men[10]; 
    strcpy(men[3].name, "john"); 
    printf("*** %s ***\n", men[3].name); 

    // dynamic array of structures 
    man *men2; 
    men2 = malloc(10 * sizeof(man)); 
    strcpy(men2[3].name, "john"); 
    printf("*** %s ***\n", men2[3].name); 

    // multidimensional array of structures 
    man men3[10][10]; 
    strcpy(men3[3][3].name, "john"); 
    printf("*** %s ***\n", men3[3][3].name); 

    // dynamic multidimensional array of structures 
    man **men4; 
    men4 = malloc(10 * sizeof(man*)); 
    for (i = 0; i < 10; i++) 
     men4[i] = malloc(10 * sizeof(man*)); 
    strcpy(men4[3][3].name, "john"); 
    printf("*** %s ***\n", men4[3][3].name); 

    // array of pointer to structure 
    man *men5[10]; 
    men5[3] = &john; 
    printf("*** %s ***\n", men5[3]->name); 

    // dynamic array of pointers to structure 
    man **men6; 
    men6 = malloc(10 * sizeof(*men6)); 
    men6[3] = &john; 
    printf("*** %s ***\n", men6[3]->name); 

    // dynamic multidimensional array of pointers to structures 
    /* ? */ 

    return 0; 
} 

,您可以:

  1. 告诉我,如果一切是正确的
  2. 解释为什么men4我使用sizeof(man*)但men6它是sizeof(*men6)(星号位置)
  3. 解释如何使指向结构的动态多维数组(最后一点)
  4. 解释我men4?它可以工作,但在我看来,更多的是指向结构的指针数组,而不是多维的结构数组!

在此先感谢。

回答

1

首先,你的这两种情况

// dynamic multidimensional array of structures 
man **men4; 
men4 = malloc(10 * sizeof(man*)); 
for (i = 0; i < 10; i++) 
    men4[i] = malloc(10 * sizeof(man*)); 

// dynamic array of pointers to structure 
man **men6; 
men6 = malloc(10 * sizeof(*men6)); 
men6[3] = &john; 
printf("*** %s ***\n", men6[3]->name); 

在概念一样。在这两种情况下,您都有一个指向man的指针。您正在以不同的方式使用这些指针。另外,第一个有错误。相反的:

men4[i] = malloc(10 * sizeof(man*)); 

你应该写:

men4[i] = malloc(10 * sizeof(man)); 

因为每个men4[i]的类型是 “指向man”。这错误就是为什么我通常喜欢我的malloc()调用的形式为:

a = malloc(N * sizeof *a); 

所以,您的通话将成为:

men4[i] = malloc(10 * sizeof *men4[i]); 

这是不容易出错。

因此,您的问题(2)的答案是,您应该只在分配men4时使用sizeof(man *),但不能在循环中使用。 (或者,你现在知道一个更好的方式来调用malloc(),因此呼叫如雷贯耳循环将成为men4 = malloc(10 * sizeof *men4);

  1. 这是正确的,除了malloc()呼叫如上所述。
  2. 见上。
  3. 你想要一个指向struct的指针数组。要得到一个数组,你需要[],因为它是一个指向你想要的指针的指针(多维),所以你需要两个**。所以你得到:man **(men7[10]);,但由于[]无论如何都要比*更紧密地绑定,所以你可以把它写成man **men7[10];
  4. men4不是一个多维数组,也不是一个指针数组。它是指向man的指针。当您为men4分配内存时,需要为指向man的10个指针分配空间。然后,为每个指针分配空间10 man。事实上,您可以将men4索引为多维数组是这种分配的结果。在你的循环中,如果你愿意的话,每个men4[i]可能已经被分配了不同数量的man值的空间,这对于多维数组是不可能的。

指针不是数组。数组不是指针。有关详细信息,请阅读section 6 of the C FAQ中的所有问题和答案。

0
  1. 语义正确
  2. IS指针数组,所以你必须分配指针大小的元件,并且指针的大小是sizeof(void*)等于sizeof(man*)
  3. man ***men;
  4. 是的。应该man **men[10];
1
  • 2:这是两个例子做同样的事情:sizeof(*men6) == sizeof(man*)
  • 3:与men5例子相同,但多维。
  • 4:men4例子并不完全正确。据我了解,应该是说,例如必须阅读:

man ***men4; // 10x10 multidimensional 
men4 = malloc(10 * sizeof(man**)); 
for (i = 0; i < 10; i++) 
{ 
    men4[i] = malloc(10 * sizeof(man*)); 
    for(j = 0; j < 10; ++j) 
     men4[i][j] = malloc(sizeof(man)); 
}  
strcpy(men4[3][3]->name, "john"); 
printf("*** %s ***\n", men4[3][3]->name);