C语言结构体

结构是一个或多个变量的集合,这些变量可能是不同的类型,为了处理的方便而将这些变量组织在一个名字之下。

结构体基础

一个简单的结构声明如下:

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  

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 

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时,它们内部的指针变量也指向相同的地址。

你可能感兴趣的:(C语言结构体)