提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
一、结构体定义
struct stu{
char *name; //姓名
int num; //学号
int age; //年龄
char group; //所在学习小组
float score; //成绩
};
结构体是一种集合,它里面包含了多个变量或数组,
结构体是一种数据类型,可以用来定义变量
struct stu stu1, stu2;
stu1 它是 stu 类型,由 5 个成员组成。
结构体和数组类似,也是一组数据的集合。数组使用下标[ ]
获取单个元素,结构体使用点号.
获取单个成员。
#include <stdio.h>
int main(){
struct{
char *name; //姓名
int num; //学号
int age; //年龄
char group; //所在小组
float score; //成绩
} stu1;
//给结构体成员赋值
stu1.name = "Tom";
stu1.num = 12;
stu1.age = 18;
stu1.group = 'A';
stu1.score = 136.5;
//读取结构体成员的值
printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!\n", stu1.name, stu1.num, stu1.age, stu1.group, stu1.score);
return 0;
}
Tom的学号是12,年龄是18,在A组,今年的成绩是136.5!
二、结构题数组
struct stu{
char *name; //姓名
int num; //学号
int age; //年龄
char group; //所在小组
float score; //成绩
}class[5];
表示一个班级有5个学生。
#include <stdio.h>
struct {
char* name; //姓名
int num; //学号
int age; //年龄
char group; //所在小组
float score; //成绩
}class[] = {
{"Li ping", 5, 18, 'C', 145.0},
{"Zhang ping", 4, 19, 'A', 130.5},
{"He fang", 1, 18, 'A', 148.5},
{"Cheng ling", 2, 17, 'F', 139.0},
{"Wang ming", 3, 17, 'B', 144.5}
};
int main() {
int i, num_140 = 0;
float sum = 0;
for (i = 0; i < 5; i++) {
sum += class[i].score;
if (class[i].score < 140) num_140++;
}
printf("sum=%.2f\naverage=%.2f\nnum_140=%d\n", sum, sum / 5, num_140);
return 0;
}
计算全班学生的总成绩、平均成绩和以及 140 分以下的人数
sum=707.50
average=141.50
num_140=2
三、结构体指针
//结构体
struct stu{
char *name; //姓名
int num; //学号
int age; //年龄
char group; //所在小组
float score; //成绩
} stu1 = { "Tom", 12, 18, 'A', 136.5 };
//结构体指针
struct stu *pstu = &stu1;//指向结构体的指针
获取结构体成员的两种形式:
1.(*pointer).memberName///(*pstu).name
2.pointer->memberName///pstu->name
这是->的唯一用途
#include <stdio.h>
int main(){
struct{
char *name; //姓名
int num; //学号
int age; //年龄
char group; //所在小组
float score; //成绩
} stu1 = { "Tom", 12, 18, 'A', 136.5 }, *pstu = &stu1;
//读取结构体成员的值
printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!\n", (*pstu).name, (*pstu).num, (*pstu).age, (*pstu).group, (*pstu).score);
printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!\n", pstu->name, pstu->num, pstu->age, pstu->group, pstu->score);
return 0;
}
Tom的学号是12,年龄是18,在A组,今年的成绩是136.5!
Tom的学号是12,年龄是18,在A组,今年的成绩是136.5!
结构体指针作为函数参数
#include <stdio.h>
struct stu {
char* name; //姓名
int num; //学号
int age; //年龄
char group; //所在小组
float score; //成绩
}stus[] = {
{"Li ping", 5, 18, 'C', 145.0},
{"Zhang ping", 4, 19, 'A', 130.5},
{"He fang", 1, 18, 'A', 148.5},
{"Cheng ling", 2, 17, 'F', 139.0},
{"Wang ming", 3, 17, 'B', 144.5}
};
void average(struct stu* ps, int len);
int main() {
int len = sizeof(stus) / sizeof(struct stu);
average(stus, len);//因为是数组,所以可以不加&
return 0;
}
void average(struct stu* ps, int len) {
int i, num_140 = 0;
float average, sum = 0;
for (i = 0; i < len; i++) {
sum += (ps + i)->score;
if ((ps + i)->score < 140)
{
num_140++;
}
}
printf("sum=%.2f\naverage=%.2f\nnum_140=%d\n", sum, sum / 5, num_140);
}
sum=707.50
average=141.50
num_140=2
四、枚举
enum week{ Mon, Tues, Wed, Thurs, Fri, Sat, Sun };
枚举值默认从 0 开始,week 中的 Mon、Tues … Sun 对应的值分别为 0、1 … 6。
enum week{ Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun };
举值就从 1 开始递增,Mon、Tues … Sun 对应的值分别为 1、2 … 7。
五、共用体
union data{
int n;
char ch;
double f;
};
union data a, b, c;
共用体 data 中,成员 f 占用的内存最多,为 8 个字节,所以 data 类型的变量(也就是 a、b、c)也占用 8 个字节的内存
这是与结构体不同的地方。
#include <stdio.h>
union data{
int n;
char ch;
short m;
};
int main(){
union data a;
printf("%d, %d\n", sizeof(a), sizeof(union data) );
a.n = 0x40;
printf("%X, %c, %hX\n", a.n, a.ch, a.m);
a.ch = '9';
printf("%X, %c, %hX\n", a.n, a.ch, a.m);
a.m = 0x2059;
printf("%X, %c, %hX\n", a.n, a.ch, a.m);
a.n = 0x3E25AD54;
printf("%X, %c, %hX\n", a.n, a.ch, a.m);
return 0;
}
4, 4
40, @, 40
39, 9, 39
2059, Y, 2059
3E25AD54, T, AD54
共用体成员之间会相互影响,修改一个成员的值会影响其他成员。
Name | Num | Sex | Profession | Score / Course |
---|---|---|---|---|
HanXiaoXiao | 501 | f | s | 89.5 |
YanWeiMin | 1011 | m | t | math |
LiuZhenTao | 109 | f | t | English |
ZhaoFeiYan | 982 | m | s | 95.0 |
#include <stdio.h>
#include <stdlib.h>
#define TOTAL 4 //人员总数
struct{
char name[20];
int num;
char sex;
char profession;
union{
float score;
char course[20];
} sc;
} bodys[TOTAL];
int main(){
int i;
//输入人员信息
for(i=0; i<TOTAL; i++){
printf("Input info: ");
scanf("%s %d %c %c", bodys[i].name, &(bodys[i].num), &(bodys[i].sex), &(bodys[i].profession));
if(bodys[i].profession == 's'){ //如果是学生
scanf("%f", &bodys[i].sc.score);
}else{ //如果是老师
scanf("%s", bodys[i].sc.course);
}
fflush(stdin);
}
//输出人员信息
printf("\nName\t\tNum\tSex\tProfession\tScore / Course\n");
for(i=0; i<TOTAL; i++){
if(bodys[i].profession == 's'){ //如果是学生
printf("%s\t%d\t%c\t%c\t\t%f\n", bodys[i].name, bodys[i].num, bodys[i].sex, bodys[i].profession, bodys[i].sc.score);
}else{ //如果是老师
printf("%s\t%d\t%c\t%c\t\t%s\n", bodys[i].name, bodys[i].num, bodys[i].sex, bodys[i].profession, bodys[i].sc.course);
}
}
return 0;
}
据表格写代码,Score / Course在这的类型用到共用体
Input info: HanXiaoXiao 501 f s 89.5↙
Input info: YanWeiMin 1011 m t math↙
Input info: LiuZhenTao 109 f t English↙
Input info: ZhaoFeiYan 982 m s 95.0↙
Name Num Sex Profession Score / Course
HanXiaoXiao 501 f s 89.500000
YanWeiMin 1011 m t math
LiuZhenTao 109 f t English
ZhaoFeiYan 982 m s 95.000000
struct llm_act_info
{
/// Pointer to parameters received from the Host (advertising, scanning or initiating)
void const * host_params;
/// Interval element linked to this activity
struct sch_plan_elt_tag plan_elt;
union
{
/// Scanning specific activity info
struct llm_scan_info scan;
/// Advertising specific activity info
struct llm_adv_info adv;
/// Periodic advertising specific activity info
struct llm_per_adv_info per_adv;
/// Periodic sync specific activity info
struct llm_sync_info sync;
/// Connection specific activity info
struct llm_con_info con;
} info;
/// State
uint8_t state;
};
项目中用到的共用体
六、位域
struct bs{
unsigned m;
unsigned n: 4;
unsigned char ch: 6;
};//n、ch它们分别占用 4、6 位(Bit)的内存//m 它占用 4 个字节(Byte)的内存
有些数据在存储时并不需要占用一个完整的字节,只需要占用一个或几个二进制位即可。例如开关只有通电和断电两种状态,用 0 和 1 表示足以,也就是用一个二进位。正是基于这种考虑,C语言又提供了一种叫做位域的数据结构。
七、位运算
&:参与&
运算的两个位都为 1 时,结果才为 1
|:参与|
运算的两个二进制位有一个为 1 时,结果就为 1
‘异’或^:参与^
运算两个二进制位不同时,结果为 1,相同时结果为 0
~:~1
为0,~0
为1
<<:高位丢弃,低位补0
:低位丢弃,高位补 0 或 1。如果数据的最高位是 0,那么就补 0;如果最高位是 1,那么就补 1。
八、typedef和const
struct stu stu1;
使用typedef 给 struct stu 起了一个别名 STU
STU stu1;
typedef int INTEGER;
INTEGER a, b;
a = 1;
b = 2;
INTEGER a, b;
等效于int a, b;
。
typedef 和 #define 差不多,但是有区别。
const被它修饰的变量不能改变,和 #define 差不多
const修饰指针会有不同
const int *p1;
int const *p2;
int * const p3;
在最后一种情况下,指针是只读的,也就是 p3 本身的值不能被修改;在前面两种情况下,指针所指向的数据是只读的,也就是 p1、p2 本身的值可以修改(指向不同的数据),但它们指向的数据不能被修改。