结构体是C语言的一项难点内容,这篇文章将带大家初步了解入门结构体,以及可以简单的使用它。
目录
一. 结构体类型的声明
1.结构体的基础知识
2.结构体的声明
3.结构成员的类型
二. 结构体变量的定义和初始化
三. 结构体成员访问
四. 结构体传参
五、总结
一. 结构体类型的声明
1.结构体的基础知识
结构体是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
我们可以将结构体和数组类比一下:数组:一组相同类型元素的集合。
结构体:一组不一定相同类型元素的集合。
2.结构体的声明
我们先来了解一下结构体的写法:
struct tag//tag是根据实际情况给名字
{
member - list;//成员列表(1个或多个)
}variable - list;//变量列表
我们来写一个关于描述一个学生的代码:
struct stu//学生有名字、年龄、性别等等
{
//这些是成员变量,用来描述结构体对象的相关属性的
char name[20];//一个中文占两个字符,姓名
int age;//年龄
char sex[5];//性别
};//分号切记不能忘
int main()
{
struct stu s1;//这是第一种方法,通过类型创建的变量,但s1是局部变量
return 0;
}
这是第一种方法创建一个结构体s1,但是它是一个局部变量。下面我们介绍第二种方法,它可以让声明的结构体为全局变量:
struct stu
{
char name[20];
int age;
char sex[5];
}s2, s3, s4;//这种方法创建的结构体变量就是全局变量
当然,我们还有第三种方法:
typedef struct Stu //typedef是重命名的意思,它可以对这个结构体重命名为下面分号后的Stu
{
char name[20];//名字
int age;//年龄
char sex[5];//性别
char id[20];//学号
}Stu;//typedef重命名的名字Stu
int main()
{
Stu s5; // Stu s5 == struct Stu s1
//在C语言中,没有对结构体类型typedef(重命名),struct这个关键字不能省略。
return 0;
}
3.结构成员的类型
结构的成员可以是标量、数组、指针,甚至是其他结构体。
二. 结构体变量的定义和初始化
有了结构体类型,那如何定义变量,其实很简单
比如我们刚刚写的关于学生的代码:我们假设他的名字叫张三,年龄18,性别男,那我们可以这样子来初始化表示:
struct s
{
char name[20];//名字
int age;//年龄
char sex[5];//性别
}s = { "张三",18,"male" };//"张三"是初始化name的结果,18是初始化age的结果,"male"是初始化sex的结果
当然,我们同样有其他方法进行初始化表示:
第二种:
struct s
{
char name[20];//名字
int age;//年龄
char sex[5];//性别
};
int main()
{
struct s s2 = { "张三",18,"male" };
return 0;
}
第三种:
struct s
{
char name[20];//名字
int age;//年龄
char sex[5];//性别
};
int main()
{
struct s s2 = { .name="张三",.age=18,.sex="male" };//.是结构成员操作符
return 0;
}
注意:结构体是可以嵌套访问的!
三. 结构体成员访问
结构变量的成员是通过点操作符(.)访问的。点操作符接受两个操作数。
我们举个例子:
struct s
{
char name[20];//名字
int age;//年龄
char sex[5];//性别
};
int main()
{
struct s s1;
strcpy(s1.name, "张三");//使用.访问name成员
s1.age = 18;//使用.访问age成员
strcpy(s1.sex, "male");//使用.访问sex成员
printf("%s,%d,%s\n", s1.name, s1.age, s1.sex);
return 0;
}
那如果我们想用一个函数set_stu对结构体成员进行访问,随后用printf函数输出呢?
我们先尝试写一个代码:
我们将结构体s传给set_stu函数,随后运行,但是我们却发现,运行的结果在屏幕上打印的是错误的,这是为什么呢?因为数组传递的是首元素的地址,所以我们使用的传值调用是错误的,我们应该使用传值调用,下面来看正确代码:
现在我们使用传址调用,成功的将结果打印了出来。
我们不仅可以使用.来访问结构体变量的成员,同时我们也可以用->,来看代码:
四. 结构体传参
结构体传参分为传值调用和传址调用,我们看一眼代码进行对比:
struct S
{
int data[1000];
int num;
};
struct S s = { {1,2,3,4}, 1000 };
//结构体传参
void print1(struct S s)
{
printf("%d\n", s.num);
}
//结构体地址传参
void print2(struct S* ps)
{
printf("%d\n", ps->num);
}
int main()
{
print1(s); //传结构体
print2(&s); //传结构体地址
return 0;
}
printf1函数和printf2函数哪个好呢? 答案是首选printf2函数。
原因:
函数传参的时候,参数是需要压栈的。
如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。
结论:
结构体传参的时候,要传结构体的地址。
五、总结
通过以上的学习,我们已经入门了结构体,我们已经了解了关于结构体类型的声明、定义和初始化,同时我们也学会了结构体成员的访问和结构体的传参,现在我们已经可以使用结构体完成一些简单的代码编写要求啦!