例如,一名学生有学号、姓名、性别、年龄、地址等属性,如果针对学生的学号、姓名、年龄等都单独定义一个变量,那么在有多名学生时,变量就难以分清。
struct 结构体名{成员列表};
例如
struct student{int num;char name[20];char sex;int age;float score;char addr[30];};
先声明结构体类型,再定义变量名。例如,
struct student student1, student2;
#include struct student
{int num;char name[20];char sex;int age;float score;char addr[30];
};//结构体类型声明,注意最后一定要加分号int main()
{struct student s = { 1001, "lele", 'M', 20,85.4, "shenzhen" };//定义及初始化printf("%d %s %c %d %f %s\n", s.num, s.name, s.sex, s.age, s.score, s.addr);//混合读取,%c不会忽略任何字符scanf("%d%s %c%d%f%s",&s.num, s.name, &s.sex, &s.age, &s.score, s.addr);//数组名就是首地址struct student sarr[3];return 0;
}
注意
因为如果结构体变量已经定义,那么只能对他的每个成员单独赋值,如s.sum = 1003。
结构体输出必须单独访问内部的每一个成员。
printf不可以直接输出结构体,需要逐个成员访问,采用结构体变量名.成员名的形式来访问结构体成员。
例如用s.num访问学号。
printf中的%类型要与各成员匹配。
字符型数据(%c)不会忽略空格,如果要读取字符型数据,那么就要在待读取的字符数据和其他数据之间加入空格。
#include struct student
{int num;char name[20];char sex;int age;float score;char addr[30];
};int main()
{struct student sarr[3];//定义结构体数组变量 - 一个数组中有三个结构体int i;for (i = 0; i < 3; i++)//结构体数组输入{scanf("%d%s %c%d%f%s", &s.num, s.name, &s.sex, &s.age, &s.score, s.addr);}for (i = 0; i < 3; i++)//结构体数组输出{printf("%d %s %c %d %5.2f %s\n", s.num, s.name, s.sex, s.age, s.score, s.addr);}return 0;
}
结构体的大小必须是其最大成员的整数倍!
#include
struct student_type1
{double score;//double是一种浮点类型,8个字节,浮点分为float和double,记住有这两种即可short age; //2 - 8
};//16struct student_type1
{double score;//8int height;//4short age;//2
};//16
//如果两个小成员(4+2)小于最大成员(8),可以结合在一起。
//2+4 < 8,int和short占8个字节struct student_type1
{int height;//4char sex;//1short age;//2
};//8
//1+2 < 4,char和short占4个字节//结构体对齐 - 结构体占多大空间
int main()
{struct student_type1 s1;struct student_type2 s2;struct student_type3 s3;printf("s1 size=%d\n", sizeof(s1));printf("s2 size=%d\n", sizeof(s2));printf("s3 size=%d\n", sizeof(s3));return 0;
}
#include struct student
{int num;char name[20];char sex;
};int main()
{struct student s = { 1001,"wangle",'M' };struct student sarr[3] = { 1001,"lilei",'M',1005,"zhangsan",'M',1007,"lili,'F" };printf("%d\n",sizeof(s));//28struct student *p;//定义结构体指针变量int num;p = &s;//拿到起始地址赋给结构体指针printf("%d %s %c\n", p->num, p->name, p->sex);//对象指针->成员名p = sarr;//结构体数组 - 数组名存的就是数组的起始地址 - 等价于p = &sarr[0]//对象.成员名printf("%d %s %c\n", (*p).num, (*p).name, (*p).sex);//方式一获取成员 - 加括号成为整体 - 取值*的优先级没有.的优先级高printf("%d %s %c\n", p->num, p->name, p->sex);//方式二获取成员 - 这个方式更好printf("-----------------------------------------\n");p = p + 1;printf("%d %s %c\n", p->num, p->name, p->sex);return 0;
}
括号,因为“.”成员选择的优先级高于“*”(取值)运算符,所以必须加括号。高效
#include //原写法
//struct student
//{
// int num;
// char name[20];
// char sex;
//};//typedef的使用 - 起别名
// stu 等价于 struct student, pstu 等价于 struct student*
//结构体指针
typedef struct student
{int num;char name[20];char sex;
}stu,*pstu; //别名 - 结构体/结构体指针typedef int INTEGER;//特定的地方使用 - 给int起别名int main()
{//struct student s = { 0 };//原写法stu s = { 1001,"wangle",'M' };//别名stu* p = &s;//定义了一个结构体指针变量pstu p1 = &s;INTEGER i = 10;printf("i=%d,p->num=%d\n", i, p->num);return 0;
}
例子:
int a;
void modifynum(int &b)
{b = b + 1;
}
//调用:modifynum(a)int *p = NULL;
void modify_pointer(int *&p)
{......p = q;......
}
//调用:modify_pointer(p)
#include //兼容c的头文件//在子函数中修改主函数中变量的值,使用引用;不需要修改,不用。
void modify_num(int &b)//引用 - 形参中写&,要称为引用
{b = b + 1;
}//C++的引用的讲解
//在子函数内修改主函数的普通变量的值
int main()
{int a = 10;modify_num(a);printf("after modify_num a = %d\n", a);return 0;
}
将上面的代码改为纯C语言:
#include void modify_num(int *b)
{*b = *b + 1;
}int main()
{int a = 10;modify_num(&a);printf("after modify_num a = %d\n", a);return 0;
}
#include void modify_pointer(int *&p, int *q)//引用必须和变量紧邻
{p = q;
}int main()
{int *p = NULL;//0int i = 10;int *q = &i;modify_pointer(p, q);printf("after modify_pointer *p = %d\n", *p);return 0;//当进程已结束,退出代码不为0,那么代表进程异常结束
}
#include
void modify_pointer(int **p, int *q)//相对于C++这里是int **p;
{*p = q;//这里的写法和例1.3中的是非常类似的
}int main()
{int *p = NULL;int i = 10;int *q = &i;modify_pointer(&p, q);//相对于C++这里是&pprintf("after modify_pointer *p = %d\n", *p);return 0;
}
纯C使用了二级指针。
//设置布尔值的好处是提升了代码的可阅读性
int main()
{bool a = true;bool b = false;printf("a = %d, b = %d\n", a, b);//ture = 1; false = 0return 0;
}
括号,因为“.”成员选择的优先级高于“*”(取值)运算符,所以必须加括号。
上一篇:生涯之夜!本场轰下5记关键三分的功臣李虎翼接受队友“爱抚” 李虎翼隔扣 李虎翼18分3篮板3助攻
下一篇:意甲-米兰3-2补时逆转绝杀乌迪内斯 米兰联赛4连胜&先赛距榜首6分 意甲ac米兰不敌乌迪内斯 意甲第十一轮国际米兰对乌迪内斯