目录
1.结构体:
1,结构体的定义
2,结构体的初始化
3,结构体的访问
4.结构体的存储:
内存对齐:
char 按照1字节对齐
short 按照2字节对齐
int 按照4字节对齐
double 按照4字节对齐
结构体整体的大小必须为最大基本类型长度的整数倍
例如:
struct student
{
char name[32];
char sex;
int age;
int score;
} ;
该结构体所占空间为32*1(char name[32]所占空间)+1(char sex所占空间)+3(为对齐下一个int型变量空着的空间)+4(int age所占空间)+4(int score所占空间)个字节
5.结构体作为函数参数
练习:定义一个学生的类型,封装一个函数GetStuInfo获得学生信息放入结构体中,
再封装一个函数PutStuInfo打印学生信息
struct student
{
char name[32];
char sex;
int age;
int score;
};
参考如下:
#include<stdio.h>
#include<string.h>
struct student
{
char name[32];
char sex;
int age;
int score;
};
int Getstudent(struct student *pst)
{
gets(pst->name);
pst->sex = getchar();
scanf("%d%d",&pst->age,&pst->score);
return 0;
}
int Outstduent(struct student *pst)
{
printf("姓名:%s\n性别:%c\n年龄:%d\n成绩:%d\n",pst->name,pst->sex,pst->age,pst->score);
return 0;
}
int main(void)
{
struct student st;
memset(&st,0,sizeof(st));
Getstudent(&st);
Outstduent(&st);
return 0;
}
6.结构体数组:
struct student s[5];
参考如下:
#include<stdio.h>
struct student
{
char name[32];
char sex;
int age;
int score;
};
int Instudent(struct student *pst,int len)
{
int i = 0;
int curlen = 0;
printf("请输入学生个数:");
scanf("%d",&curlen);
for(i = 0;i < curlen;i++)
{
scanf("%s",pst[i].name);
scanf(" %c",&pst[i].sex);
scanf("%d",&pst[i].age);
scanf("%d",&pst[i].score);
}
return curlen;
}
int Putstudent(struct student *pst,int len)
{
int i = 0;
for(i = 0;i < len;i++)
{
printf("姓名:%s\n",pst[i].name);
printf("性别:%c\n",pst[i].sex);
printf("年龄:%d\n",pst[i].age);
printf("成绩:%d\n",pst[i].score);
}
return 0;
}
int main(void)
{
struct student st[100];
int n = 0;
n = Instudent(st,100);
Putstudent(st,n);
return 0;
}
2.共用体:
共用体定义
共用体的定义,结构,初始化,访问,传参都可以参考结构体
union 共用体名
{
数据类型1 成员变量1;
数据类型2 成员变量2;
数据类型3 成员变量3;
...
};
共用体所有成员变量共享同一片空间
共用体使用场景
内存大小端:
1.内存小端:
内存低地址存放低数据位
内存高地址存放高数据位
2.内存大端:
内存低地址存放高数据位
内存高地址存放低数据位
参考如下:
#include<stdio.h>
int main(void)
{
int num = 0x11223344;
char *p = NULL;
p = (char *)#
if(0x11 == *p)
{
printf("大端!\n");
}
else if(0x44 == *p)
{
printf("小端!\n");
}
return 0;
}
采用union测试:
#include<stdio.h>
union c
{
int a;
char b;
};
int main(void)
{
union c c1;
c1.a = 1;
if(c1.b)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
3.枚举:
enum 枚举类型名
{
枚举常量1,
枚举常量2,
枚举常量3,
..
};
1.枚举类型一般说明将来变量的值在给定的常量中选择其一作为它的值
2.枚举常量的值总是前一个枚举常量的值+1,第一个默认为0值
3.枚举常量默认为int类型,可以直接在程序中使用
参考如下:
#include<stdio.h>
enum weekday
{
monday = 1,
tuseday,
wednesday,
thurday,
friday,
saturday,
sunday
};
int main(void)
{
enum weekday day;
scanf("%d",(int *)&day);
switch(day)
{
case monday:printf("限1,6\n");break;
case tuseday:printf("限2,7\n");break;
case wednesday:printf("限3,8\n");break;
case thurday:printf("限4,9\n");break;
case friday:printf("限0,5\n");break;
case saturday:
case sunday:printf("不限\n");break;
}
return 0;
}
4.位运算运算符:
& 按位与
全1为1,有0出0
| 按位或
全0为0,有1出1
^ 按位异或
相同为0 相异为1
~ 按位取反
>> 右移
右移n位 等价于 让该数 / 2^n
<< 左移
左移n位 等价于 让该数 * 2^n
参考原理:
9 & 3
0000 0000 0000 0000 0000 0000 0000 1001 &
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 0001
9 | 3
0000 0000 0000 0000 0000 0000 0000 1001 |
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 1011
9 ^ 3
0000 0000 0000 0000 0000 0000 0000 1001 ^
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 1010
~9
0000 0000 0000 0000 0000 0000 0000 1001
1111 1111 1111 1111 1111 1111 1111 0110
111 1111 1111 1111 1111 1111 1111 0101
000 0000 0000 0000 0000 0000 0000 1010
9
00000000000000000000000000000001
1 << 3
00000000000000000000000000000001
00000000000000000000000000001000
参考如下:
#include<stdio.h>
int main(void)
{
printf("9 & 6 = %d\n",9 & 6);
printf("9 | 6 = %d\n",9 | 6);
printf("9 ^ 6 = %d\n",9 ^ 6);
printf("~9 = %d\n", ~ 9);
printf("9 >> 6 = %d\n",9 >> 6);
printf("9 << 6 = %d\n",9 << 6);
return 0;
}
一些位运算的使用方法:
按位异或实现数据交换:
a = a ^ b;
b = a ^ b;
a = a ^ b;
参考如下:
#include<stdio.h>
int main(void)
{
int a = 100;
int b = 200;
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("a = %d,b = %d\n",a,b);
return 0;
}
将变量的第n位置0:
num = num & ~(1 << n);
将变量的第n位置1:
num = num | (1 << n);
作业:
有一个班的5个学生,有3门课程。
1、求第一门课的平均分;
2、找出有两门以上课程不及格的学生,输出他们的学号和全部课程成绩及平均分
3、找出平均分在90分以上或全部课程成绩在85分以上的学生。
分别编写三个函数来实现以上三个要求
struct student
{
char name[32];
int no;
int score[3];
};
参考答案:
#include<stdio.h>
struct student
{
char name[32];
int xuehao;
int score[3];
};
int averscore(struct student *pst,int len)
{
int j = 0;
int sum = 0;
for(j = 0;j < len;j++)
{
sum += pst[j].score[0];
}
return sum / len;
}
int badstudent(struct student *pst,int len)
{
int i = 0;
int j = 0;
int t[5] = {0};
int sum[5] = {0};
for(i = 0;i < len;i++)
{
for(j = 0;j < 3;j++)
{
if(pst[i].score[j] <= 60)
{
t[i]++;
}
sum[i] += pst[i].score[j];
}
}
for(i = 0;i < len;i++)
{
if(t[i] >= 2)
{
printf("姓名:%s\n学号:%d\n成绩1:%d\n成绩2:%d\n成绩3:%d\n平均分:%d\n",pst[i].name,pst[i].xuehao,pst[i].score[0],pst[i].score[1],pst[i].score[2],sum[i] / 3);
}
}
return 0;
}
int goodstudent(struct student *pst,int len)
{
int i = 0;
int j = 0;
int t[5] = {0};
int sum[5] = {0};
for(i = 0;i < len;i++)
{
for(j = 0;j < 3;j++)
{
if(pst[i].score[j] > 85)
{
t[i]++;
}
sum[i] += pst[i].score[j];
}
}
for(i = 0;i < len;i++)
{
if((sum[i] / 3) > 90 || t[i] == 3)
{
printf("姓名:%s\n",pst[i].name);
}
}
return 0;
}
int main(void)
{
struct student st[5] = {{"张三",1001,90,99,86},{"李四",1002,89,87,86},{"王五",1003,78,77,90},{"老六",1004,64,29,48},{"阿giao",1005,25,49,37}};
int aver = 0;
aver = averscore(st,5);
printf("第一科平均分为:%d\n",aver);
printf("==============================\n");
printf("两门及以上课程不及格的学生:\n");
badstudent(st,5);
printf("==============================\n");
printf("平均分在90以上或全部成绩超过85的学生:\n");
goodstudent(st,5);
return 0;
}