结构是一个或多个变量的集合,这些变量可能是不同的类型,为了处理的方便而将这些变量组织在一个名字之下。
结构体基础
一个简单的结构声明如下:
struct point {
int x;
int y;
};
struct point p1, p2; //结构体变量声明,
可以通过p1.x, p1.y等引用成员。
结构与函数
当结构体参数作为函数参数时,是值传递。比如下面的函数并不能让p1的成员增加1,实际上addone函数没有任何作用。
void addone(struct point p)
{
p.x ++;
p.y ++;
}
struct point p1 = {100, 200};
addone(p1);
一个改进是通过返回值,比如:
struct point addone(struct point p)
{
p.x ++;
p.y ++;
return p;
}
struct point p1 = {100, 200};
p1 = addone(p1);
#include <stdio.h>
struct point{
int x;
int y;
};
void addone_01(struct point p)
{
// 错误的实现,因为结构体作为参数是值传递
p.x ++;
p.y ++;
}
struct point addone_02(struct point p)
{
//实现正确,但是糟糕的设计
p.x ++;
p.y ++;
return p;
}
void addone(struct point *pp)
{
// 实现正确,推荐设计,使用指针避免分配结构空间
(*pp).x ++;
(*pp).y ++;
}
void printptr(struct point *pp)
{
printf("x = %d \n", pp->x);
printf("y = %d \n", pp->y);
printf("\n");
}
int main()
{
struct point p = {100, 200};
printptr(&p);
addone_01(p);
printptr(&p);
p = addone_02(p);
printptr(&p);
addone(&p);
printptr(&p);
return 0;
}
当传递给函数的结构很大时,推荐使用指针方式,效率更高,不会分配额外的空间。
另一个例子:
#include <stdio.h>
struct point{
int *p1;
int *p2;
};
void printptr(struct point *pp)
{
printf("%d, %d\n\n", *(pp->p1), *(pp->p2));
return;
}
int main()
{
int a1 = 12;
int a2 = 13;
int b1 = 22;
int b2 = 23;
struct point pa;
pa.p1 = &a1;
pa.p2 = &a2;
printptr(&pa);
struct point pb;
pb.p1 = &b1;
pb.p2 = &b2;
printptr(&pb);
pa = pb;
printptr(&pa);
printptr(&pb);
(*(pa.p1)) ++;
printptr(&pa);
printptr(&pb);
return 0;
}
output:
12, 13
22, 23
22, 23
22, 23
23, 23
23, 23
可见,当pa=pb
时,它们内部的指针变量也指向相同的地址。