C语言基础【26】:结构体2
1.结构体指针变量
1.1结构体变量名不代表其首地址,所以在定义结构体指针变量时需要对其&才能得到它的地址
struct stu
{int age;int num;char name[32];
};
struct stu lucy = {22,114,"lucy"};
struct stu *p = &lucy;
1.2通过指针变量访问结构体成员时,需要先*操作,再确定成员,所以需要()括住*p,否则就是结构体成员指针变量。
(*p).age = 20;
lucy.num = 314;
1.3另外一种直接通过指针变量名访问成员的方法,不需要对指针变量*操作
strcpy(p->name,"Lucy");
2.结构体数组元素的指针变量
2.1作为函数参数
#include<stdio.h>
#include<string.h>struct stu{int num;char name[32];};
void input_stu( struct stu *p,int n)
{ for(int i=0;i<n;i++){printf("请输入第%d名学生的学号和姓名:\n",i+1);scanf("%d %s",&p[i].num,p[i].name);}
}
void sort_stu( struct stu *p,int n)
{for(int i=0;i<n-1;i++){int min=i;for(int j=i+1;j<n;j++){if(p[j].num<p[min].num)min = j; }struct stu mid = p[min];p[min] = p[i];p[i] = mid;}
}
void look_stu( struct stu *p,int n)
{for(int i=0;i<n;i++){printf("%s的学号为%d\n",p[i].name,p[i].num); }
}
int main()
{struct stu class[3];int n = sizeof(class)/sizeof(class[0]);input_stu(class,n);sort_stu(class,n);look_stu(class,n);return 0;
}
3.结构体中的指针成员
考虑到使用数组存放字符串常量,有内存溢出和浪费的两种可能,所以使用指针变量存放可以解决这些问题。每次调用访问字符常量区的地址,就不需要使用数组空间存放字符串。
3.1指针成员指向文字常量区
不能随意更改。
3.2指针成员指向堆区
回忆空间申请的函数calloc和malloc,还记得注意事项中的1.返回值需要强转 2.使用完需要释放 3.一定要有指针接强转后的返回值,并且不能指向其他位置,避免内存泄漏。
3.3要把文字常量区的字符串弄到堆区,应该使用strcpy而不应该直接赋值。
Tip:字符串操作统一使用字符串操作函数
4.指针作为结构体成员容易造成浅拷贝
浅拷贝:有指针作为成员的结构体,相同类型结构体通过直接赋值使得多个指针成员指向同一个堆区空间,导致free的时候会重复free一个堆区空间,造成浅拷贝现象。
要解决浅拷贝,就要进行深拷贝。
所谓深拷贝,就是单个成员依次赋值,对于指针成员,每个结构体都需要申请新的堆区空间,并且注意字符串要用字符串拷贝函数strcpy进行拷贝。