C语言----指针与结构(高阶篇三十四)
结构与函数
程序1
结构变量与函数
// 34-1结构变量与函数.c #include <stdio.h> #include <string.h> struct Student { char name[9]; char sex[3]; int age; }; void fun(struct Student stu) { printf("姓名:%s,性别:%s,年龄:%d\n", stu.name, stu.sex, stu.age); } main() { struct Student stu; strcpy(stu.name, "李四"); strcpy(stu.sex, "男"); stu.age = 18; fun(stu); }
※与普通变量一样,使用结构变量当形式参数时,只能是单相传递。
它被系统分解为:
struct student stu;
s=stu;
试问,在这里你改变s的值,是否会改变stu的值?
※函数同样可以返回结构变量,返回形式与普通变量类似。
※无论是返回值还是传递参数,使用结构变量做函数参数,数据都会大量复制。比如student定义了50个成员,上面小小的s=stu这个表达式,就使系统自动进行了如下动作:
strcpy(stu.name,s.name);
strcpy(stu.sex,s.sex);
stu.age=s.age;
.....
直到把这50个成员复制完毕。
这大大耗费了CPU和内存资源,因此,在传送结构时,应多使用结构变量的指针
指向结构变量的指针
※指针用的最多,并且可以显著提高效率的一个用法,就是在函数间传送结构变量。
※使用一个“指向结构变量指针”的成员变量有所改变,将前面的程序代码修改一下:
struct student stu; /*定义一个结构变量*/
struct student *pstu; /*定义一个相同类型的结变量指针*/
※成员变量和普通变量一样可以用&号取地址。
pstu=&stu; /*给指针赋值*/
(*pstu).age=18; /*给结构成员变量赋值*/
pstu->age=18; /*括号和*号可以直接用->(减号+大于号)运行符替代*/
程序2
使用指针传送结构变量
// 34-2使用指针传送结构变量.c #include <stdio.h> #include <string.h> struct Student { char name[10]; char sex[3]; int age; }; void fun(struct Student *pstu) { strcpy(pstu->name, "李四"); strcpy(pstu->sex, "男"); pstu->age = 18; } main() { struct Student stu; fun(&stu); printf("姓名:%s,性别:%s,年龄:%d", stu.name, stu.sex, stu.age); }
※传递结构变量的指针与直接传送结构变量各有好处。使用指针传递结构变量的好处显而易见,父函数与子函数之间只要传递一个4字节的指针即可随意操纵父函数的结构变量。缺点就是:如果好几个函数都使用指针方式,这些函数都“共享”这个结构变量,都给它赋值的话,最后不知道这个结构变量会改成什么样子。
typedef的实用价值
运用“自定义类型”将typedef与结构指针联系起来:
struct student
{
...
}stu,*pstu;
这种变量定义可分解为:
struct student stu,*pstu;
省掉中间的花括号,就是它的定义形式。
同样,使用typedef可以将结构后面定义的变量提升成类型:
typedef struct student
{
char name[9];
int age;
}STU,*PSTU;
参照typedef的定义逻辑,以后用STU stu就相当于struct student stu;用PSTU pstu就相当于struct student *pstu。
程序3
用typedef定义结构指针
// 34-3用typedef定义结构指针.c #include <stdio.h> typedef struct Student //提升结构类型 { char name[10]; char sex[3]; int age; }STU,*PSTU; //定义STU结构类型 定义 *PSTU结构类型指针 main() { STU stu; PSTU pstu = &stu; //赋值地址 // pstu->name 不用加 & 是因为 :它本身是数组,也是指针 scanf("%s%s%d", pstu->name, pstu->sex, &pstu->age); printf("姓名:%s,性别:%s,年龄:%d\n", stu.name, stu.sex, stu.age); }