结构体的声明 | 结构体的创建 | 结构体成员的访问 |
---|---|---|
结构体传参 |
(注意:文章最后有一定的对比解释,以理解结构体创建 声明 指针)
1 结构体的声明与创建
结构体是一些值的集合,这些值称为成员变量,结构体的每个成员可以是不同类型的变量
结构体的声明语法:
第一种声明:
在创建结构体对象时候,必须写全称 struct target.
第二种声明:
在创建结构体对象时候,可以写全称,也可以写new-name
请看下面两种不同声明的创建方法:
很明显,第一种创建方法代码量就很多,但是如果不这样写就会报错
第二种创建方法就会省下代码量,而且创建方式还拥有第一种
2 结构体成员的访问 . 和 ->
注意:结构体的成员变量可以拥有 标量 数组 指针 结构体等等.
点 . 访问结构体成员:
#include <stdio.h>
typedef struct s /*结构体s*/
{
int a;
char c;
char arr[20];
double d;
}S;
typedef struct t /*结构体t*/
{
char ch[10];
S s;/*简式创建*/
char* pc; /*指针*/
}T;
int main()
{
char arr[]="你好啊,憨憨!";
T t = {"heihie", {10, 'A', "青山处处埋忠骨", 3.1415926}, arr}; /*创建结构体对象t*/
printf("%s\n", t.ch);
printf("%s\n",t.s.arr);/*访问结构体t里面的结构体s里面的字符数组arr*/
printf("%lf\n",t.s.d);/*访问结构体t里面的结构体s里面的双精度浮点数d*/
printf("%s",t.pc);
return 0;
}
运行结果:
heihie
青山处处埋忠骨
3.141593
你好啊,憨憨!
有人可能不理解上面printf("%s",t.pc); 这个为何能打印出字符串 “你好啊,憨憨!”.
这里稍微解释下
数组名就是首元素地址,如果我这样写想必就有人能理解 printf("%s",arr); 在上面创建的时候,pc就是指针变量,而pc里面存的就是arr
箭头 -> 访问结构体成员 (结构体指针访问):
#include <stdio.h>
typedef struct student
{
char name[20];
short age;
char tele[12];
char sex[5];
}student;
int main()
{
student xiaoming={"小明", 20,"18328061659", "男"};
student* p = &xiaoming;
printf("名字: %s\n", p->name);
printf("年龄: %d\n", p->age);
printf("电话: %s\n", p->tele);
printf("性别: %s\n", p->sex);
return 0;
}
运行结果:
名字: 小明
年龄: 20
电话: 18328061659
性别: 男
3函数 结构体传参 以及两种传参的效率
编写函数print1()和print2(),前者.访问 后者->访问
#include <stdio.h>
typedef struct student
{
char name[20];
short age;
char tele[12];
char sex[5];
}student;
void print1(student tmp) /*函数1 采用结构体传参,点式访问*/
{
printf("名字: %s\n", tmp.name);
printf("年龄: %d\n", tmp.age);
printf("电话: %s\n", tmp.tele);
printf("性别: %s\n", tmp.sex);
}
void print2(student* tmp) /*函数2 采用结构体指针传参,箭头访问*/
{
printf("名字: %s\n", tmp->name);
printf("年龄: %d\n", tmp->age);
printf("电话: %s\n", tmp->tele);
printf("性别: %s\n", tmp->sex);
}
int main()
{
student xiaoming={"小明", 20,"18328061659", "男"};
print1(xiaoming);
print2(&xiaoming); /*传递结构体指针*/
return 0;
}
运行结果:
名字: 小明
年龄: 20
电话: 18328061659
性别: 男
名字: 小明
年龄: 20
电话: 18328061659
性别: 男
如果student结构体里面包含大量的数组, long long,double 等,我们会发现如果给函数直接传结构体过去,内存资源将会消耗极大,而我们知道一个指针的大小(无论什么类型指针)在32位机上才4个字节,在64位上才8个字节,因此采用 print2的传参将会大大节约资源
(主要原因是因为函数传参是在进行压栈操作)
对比解释
我们在创建 整数 ,数组 ,等会首先进行声明,然后写变量名
比如:
int a; char ch[10];
而我们的结构体 struct tatget_name 就相当于int , char 等,
比如:
struct student a; 类似于 int a;
如果有typedef把struct student改成其他名字(即结构体末分号前面的名字)比如stu
就可以这样写 stu a; 类似于 int a;
同理,指针变量创建时候,int* char* double*等等 结构体指针也是 struct student *
struct student* pc; 类似于 int* pc;