对于C中的结构,下面的代码是什么意思?

时间:2012-09-09 19:01:47

标签: c pointers struct

我是C编程的新手,我还在尝试理解使用指针和使用typedef结构的概念。

我在下面的代码片段中需要在程序中使用:

typedef struct
{
    char* firstName;
    char* lastName;
    int id;
    float mark;
}* pStudentRecord;

我不确定这是做什么的 - 对我而言似乎与使用Objective-C中的接口相似,但我不认为是这种情况。

然后我有这条线

pStudentRecord* g_ppRecords;

我基本上需要根据数字将pStudentRecord添加到g_ppRecords。我理解如何为pStudentRecord类型的对象创建和分配内存,但我不确定如何实际向g_ppRecords添加多个对象。

4 个答案:

答案 0 :(得分:2)

定义了一个指向花括号中描述的结构的指针,这里有一个更简单的例子

typedef struct {
    int x;
    int y;
}Point,* pPoint;

int main(void) {
   Point point = {4,5};
   pPoint point_ptr = &point;
   printf("%d - %d\n",point.x,point_ptr->x);

   pPoint second_point_ptr = malloc(sizeof(Point));
   second_point_ptr->x = 5;
   free(second_point_ptr);
}

答案 1 :(得分:2)

第一个声明一个未命名的结构,一个类型pStudentRecord是指向它的指针。第二个声明g_ppRecords是指向pStudentRecord的指针。换句话说,指向指向结构的指针。

将第二个想象成“指针数组”可能更容易。因此,g_ppRecords[0]可能指向另一个pStudentRecordg_ppRecords[1]。 (反过来,它指向记录结构。)

为了添加它,你需要知道它如何存储指针,也就是说,如何知道指针存储了多少指针。在某个地方有一个大小,其大小为N,表示至少分配了N * sizeof(pStudentRecord*)个内存,而g_ppRecords[0]g_ppRecords[N-1]保留了N个项目。或者,它是NULL终止的,对于大小N,表示至少分配(N+1) * sizeof(pStudentRecord*)个内存,g_ppRecords[0]g_ppRecords[N-1]保存N个项目,{ {1}}保留g_ppRecords[N],标记字符串的结尾。

在此之后,创建或添加NULL应该很简单。

答案 2 :(得分:1)

struct是复合数据类型,这意味着它是包含其他变量的变量。你熟悉Objective C,所以你可能会认为它有点像'仅数据'类;也就是说,没有方法的类。这是一种将相关信息存储在一起的方法,您可以将其作为一个单元传递。

Typedef是一种将自己的数据类型命名为C中内置类型的同义词的方法。它使代码更具可读性,并允许编译器捕获更多错误(您有效地向编译器教授有关您的错误)程序的意图。)经典的例子是

typedef int BOOL;

(旧的ANSI C中没有内置的BOOL类型。)

这意味着您现在可以执行以下操作:

BOOL state = 1;

并声明带有BOOL参数的函数,然后让编译器确保你传递BOOL s,即使它们只是int s:

void flipSwitch(BOOL isOn); /* function declaration */
...
int value = 0;
BOOL boolValue = 1;
flipSwitch(value); /* Compiler will error here */
flipSwitch(boolValue); /* But this is OK */

因此,您的typedef正在创建学生记录结构的同义词,因此您可以传递学生记录,而无需每次都调用它们struct StudentRecord。它使代码更清晰,更易读。除了在这里有更多内容,在你的例子中。我刚刚描述的是:

typedef struct {
  char * firstName;
  char * lastName;
  int id;
  float mark;
} StudentRecord;

您现在可以执行以下操作:

StudentRecord aStudent = { "Angus\n", "Young\n", 1, 4.0 };

void writeToParents(StudentRecord student) {
    ...
}

但是你在typedef之后得到了*。那是因为你想要输入一个保存指向StudentRecord的指针的数据类型,而不是typedef StudentRecord本身。嗯?请继续阅读...

你需要这个指向StudentRecord的指针,因为如果你想传递StudentRecords并且能够修改它们的成员变量,你需要传递指向它们的指针,而不是变量本身。 typedef对此非常有用,因为编译器也可以捕获细微的错误。上面我们创建了writeToParents,它只读取了StudentRecord的内容。说我们想改变他们的成绩;我们无法使用简单的StudentRecord参数设置函数,因为我们无法直接更改成员。所以,我们需要一个指针:

void changeGrade(StudentRecord *student, float newGrade) {
  student->mark = newGrade;
}

很容易看出你可能会错过*,所以相反,请为StudentRecord输入一个指针类型,编译器会有所帮助:

typedef struct { /* as above */ } *PStudentRecord;

现在:

void changeGrade(PStudentRecord student, float newGrade) {
  student->mark = newGrade;
}

同时宣布两者更为常见:

typedef struct {
  /* Members */
} StudentRecord, *PStudentRecord;

这为你提供了普通的struct typedef和一个指针typedef。

那是什么指针?一个变量,它将地址保存在另一个变量的内存中。听起来很简单;从表面上看,它变得非常微妙并且非常迅速地参与其中。试试this tutorial

答案 3 :(得分:0)

这定义了指向结构的指针的名称,但不定义结构本身的名称。 尝试更改为:

typedef struct
{
    char* firstName;
    char* lastName;
    int id;
    float mark;
} StudentRecord;

StudentRecord foo;
StudentRecord *pfoo = &foo;