编辑:“大错误”部分更新。
C风格的快速教训(从C++不同!)类型定义,以及为什么它是怎么回事,以及如何使用它。
首先,一个基本的typedef把戏。
typedef int* int_pointer;
int_pointer ip1;
int *ip2;
int a; // Just a variable
ip1 = &a; // Sets the pointer to a
ip2 = &a; // Sets the pointer to a
*ip1 = 4; // Sets a to 4
*ip2 = 4; // Sets a to 4
IP1和IP2是相同的类型:一个指针到类型INT,即使你没有把一个* IP1的声明。这*代替了声明。
切换主题。 你说话声明数组作为
int array1[4];
要做到这一点在运行时动态,你可以这样做:
int *array2 = malloc(sizeof(int) * 4);
int a = 4;
array1[0] = a;
array2[0] = a; // The [] implicitly dereferences the pointer
现在,如果我们想要什么指针数组?它看起来像这样:
int *array1[4];
int a;
array1[0] = &a; // Sets array[0] to point to variable a
*array1[0] = 4; // Sets a to 4
让我们动态地分配这个数组。
int **array2 = malloc(sizeof(int *) * 4);
array2[0] = &a; // [] implicitly dereferences
*array2[0] = 4; // Sets a to 4
注意int **。这意味着指针指向int。如果我们选择,我们可以使用指针typedef。
typedef int* array_of_ints;
array_of_ints *array3 = malloc(sizeof(array_of_ints) * 4);
array3[0] = &a; // [] implicitly dereferences
*array3[0] = 4; // Sets a to 4
看看在最后的声明中只有一个*吗?这是因为其中之一是“在typedef”。与去年的声明,你现在有一个包含4个指向整数(INT *)大小为4的数组。
这里必须指出的运算符优先级是很重要的。解引用运算符[]优先于*之一。所以我们要做的就是:
*(array3[0]) = 4;
现在,让我们将主题更改为structs和typedefs。
struct foo { int a; }; // Declares a struct named foo
typedef struct { int a; } bar; // Typedefs an "ANONYMOUS STRUCTURE" referred to by 'bar'
为什么你会输入一个匿名结构?那么,为了可读性!
struct foo a; // Declares a variable a of type struct foo
bar b; // Notice how you don't have to put 'struct' first
声明函数...
funca(struct foo* arg1, bar *arg2);
看看我们怎么没有把 '结构' 在arg2的前面?现在
,我们看到,你必须使用的代码定义的结构以这种方式:
typedef struct { } * foo_pointers;
这类似于我们是怎么做的指针之前的数组:
typedef int* array_of_ints;
比较并排
typedef struct { } * foo_pointers;
typedef int* array_of_ints;
唯一的区别是一个是struct {},另一个是int。
随着我们foo_pointers,我们可以声明数组的指针到foo这样:
foo_pointers fooptrs[4];
现在我们有了一个数组,商店4个指向一个匿名的结构,我们无法访问。
TOPIC SWITCH!
不适合你,你的老师犯了一个错误。如果查看上面的foo_pointers类型的sizeof(),会发现它返回指向该结构的指针的大小,而不是结构的大小。对于32位平台,这是4个字节,对于64位平台是8个字节。这是因为我们输入了一个指向结构的指针,而不是结构本身。 sizeof(pStudentRecord)将返回4.
因此,您不能以明显的方式为结构本身分配空间!然而,编译器允许这种愚蠢。 pStudentRecord不是可以用来有效分配内存的名称/类型,它是指向匿名“概念”结构的指针,但我们可以将其大小提供给编译器。
pStudnetRecord g_ppRecords [2]; pStudentRecord * record = malloc(sizeof(* g_ppRecords [1]));
一个更好的做法是做到这一点:
typedef struct { ... } StudentRecord; // Struct
typedef StudentRecord* pStudentRecord; // Pointer-to struct
现在,我们不得不做出结构StudentRecord的,以及指向他们pStudentRecord的,以明确的方式的能力。
虽然你不得不使用的方法是非常糟糕的做法,但目前这不是一个问题。让我们回到我们使用整数的简单示例。
如果我想要使typedef复杂化我的生活但解释这里发生的概念怎么办?让我们回到旧的int代码。
typedef int* array_of_ints;
int *array1[4];
int **array2 = malloc(sizeof(int *) * 4); // Equivalent-ish to the line above
array_of_ints *array3 = malloc(sizeof(array_of_ints) * 4);
int a, b, c, d;
*array1[0] = &a; *array1[1] = &b; *array1[2] = &c; *array1[3] = &d;
*array2[0] = &a; *array2[1] = &b; *array2[2] = &c; *array2[3] = &d;
*array3[0] = &a; *array3[1] = &b; *array3[2] = &c; *array3[3] = &d;
正如你所看到的,我们可以用我们的pStudentRecord使用:
pStudentRecord array1[4];
pStudentRecord *array2 = malloc(sizeof(pStudentRecord) * 4);
把一切融合在一起,它遵循逻辑上:
array1[0]->firstName = "Christopher";
*array2[0]->firstName = "Christopher";
是等价的。 (注意:不要像上面那样完成;如果你知道你已经有了足够的空间,那么在运行时将一个char *指针赋给一个字符串只是确定的)。
这只是真正带来了最后一点。我们如何处理所有这些我们malloc'd的内存?我们如何释放它?
free(array1);
free(array2);
还有一个关于指针,匿名结构的typedefs和其他东西的深夜课程的结束。
指针只是指向一个地址。您可以根据需要从该地址开始保留尽可能多的内存(直到空间用完为止)。 – chris
我认为这是一个很差的问题,你明白可以用这种方式定义数组,因为你尝试为它分配一个空间,所以你在问什么?,仅仅为指针分配一个空间是不够的结构,这是btw pStudentRecord而不是pSt ... ord *,为了使用它,你还需要为struct it自己分配一个地方! – Michael