我是C编程的新手,我还在尝试理解使用指针和使用typedef结构的概念。
我在下面的代码片段中需要在程序中使用:
typedef struct
{
char* firstName;
char* lastName;
int id;
float mark;
}* pStudentRecord;
我不确定这是做什么的 - 对我而言似乎与使用Objective-C中的接口相似,但我不认为是这种情况。
然后我有这条线
pStudentRecord* g_ppRecords;
我基本上需要根据数字将pStudentRecord
添加到g_ppRecords
。我理解如何为pStudentRecord
类型的对象创建和分配内存,但我不确定如何实际向g_ppRecords
添加多个对象。
答案 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]
可能指向另一个pStudentRecord
和g_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;