Linux(七)
- 结构体---位域/位段 (为了节省空间)
- 字节对齐:一次性分配多少个字节 (64/32)
- 基本数据类型对齐方式
- 结构体对齐方式:按照成员中最大的对齐方式
- 共用体
- 如何定义共用体
- 如何定义一个共用体的变量
- 大小端
- 什么是大端序和小端序
- 如何测试计算机是小端序还是大端序
- 枚举:定义常量的一种方式,为了让程序更加语义话
- 定义一个枚举数据类型
- 定义一个枚举变量
- 函数指针
- 定义一个指向函数的指针
- 定义一个函数指针数组
- 函数指针作为函数的参数
- 给函数指针取了别名
- 指针函数
- 堆区的使用
- 申请空间
- 递归
- 存储类型
- auto 自动的
- register 寄存器 (CPU中的存储器)
- static 静态的
- 修饰全局变量 (隐藏)
- 修饰函数 (隐藏)
- 修饰局部变量
- extern 外部的
- 修饰全局变量,表示引入外部变量
- extern修饰函数
结构体—位域/位段 (为了节省空间)
#include <stdio.h>
//1.定义一个日期的数据类型
typedef struct date
{
//用一个变量的某几位来保存某个值 位域 /位段
unsigned int year:11;//0---2048 //unsigned int (0----2^32-1)
unsigned int month:4; //0--15
unsigned int day:5; //0---31
}Date;
//2.定义一个学生的结构体数据类型
typedef struct student
{
char name[20]; //姓名
int height; //身高
Date birDay; //出生日期
}Stu;
int main(void)
{
//位域 优点:节省空间
// 缺点:输入的时候不能使用scanf(),因为找不到首地址,只能用赋值
printf("sizeof(Date)=%ld\n",sizeof(Date));
printf("sizeof(Stu):%ld\n",sizeof(Stu));
Stu s1={"zhangsan",178,{1998,8,8}};
printf("%s %d
%04d:%02d:%02d\n",s1.name,s1.height,s1.birDay.year,s1.birDay.month,s1.birDay.day
);
return 0;
}
字节对齐:一次性分配多少个字节 (64/32)
基本数据类型对齐方式
结构体对齐方式:按照成员中最大的对齐方式
#pragma pack(2) 和默认的对齐方式取最小
共用体
如何定义共用体
union 共用体名
{
成员列表;
}
union job
{
char dept[20];
int class;
};
//定义了一个共用体数据类型,该共用体数据类型的名字叫 union job
如何定义一个共用体的变量
//类型名 变量名;
union job j1;
大小端
什么是大端序和小端序
如何测试计算机是小端序还是大端序
枚举:定义常量的一种方式,为了让程序更加语义话
定义常量的方式
<1>.宏定义 #define N 20
<2>.const const int a=20;
a=30; error (只读变量,不能被修改)
<3>.枚举
定义一个枚举数据类型
enum 名字
{
值1,值2
};
enum color
{
RED,BLUE,GREEN,WHIRE,BLACK
};
//定义了一个枚举数据类型,该枚举数据类型的名字叫enum color
//enum color中的值默认从0开始,后面的值依次加1 #define RED 0
定义一个枚举变量
//类型名 变量名
enum color e1;
e1=RED;
#include <stdio.h>
//1.定义一个枚举数据类型
enum color
{
RED,BLUE,GREEN,WHITE=100,BLACK
};
//枚举中的值默认从0开始,后面依次加1
//定义一个枚举数据类型,该数据类型的名字叫enum color
int main(void)
{
//2.定义一个枚举变量
//类型名 变量名
enum color e1;
e1=BLUE;
printf("e1=%d\n",e1);
return 0;
}
函数指针
//定义一个指向int的指针 int * pi
//定义一个指向char的指针 char * pc
//定义一个指向char的指针的指针 char ** ppc
//定义一个指向数组的指针,该数组是一个长度为5的int数组 int [5] int (*pArr)[5]
定义一个指向函数的指针
#include <stdio.h>
int add(int num1,int num2)
{
return num1+num2;
}
int sub(int num1,int num2)
{
return num1-num2;
}
int mul(int num1,int num2)
{
return num1*num2;
}
int div(int num1,int num2)
{
return num1/num2;
}
int main(void)
{
//定义一个指向数组的指针,该数组是一个长度为5的int数组
// int [5]
int ( *pArr) [5];
//函数的数据类型 返回值类型 (形参列表)
// int (int,int)
//1.定义一个指向函数的指针
int (*pFun) (int,int)=NULL;
//pFun=//函数的首地址 &+函数的名字
//pFun=&add; //add<====>*pFun
//为了简化操作,函数名代替了函数的首地址
pFun=add;
printf("add=%d\n",add(12,3));
//函数指针去调用
printf("add=%d\n",(*pFun)(12,3));
printf("add=%d\n",pFun(12,3));
return 0;
}
定义一个函数指针数组
#include <stdio.h>
int add(int num1,int num2)
{
return num1+num2;
}
int sub(int num1,int num2)
{
return num1-num2;
}
int mul(int num1,int num2)
{
return num1*num2;
}
int div(int num1,int num2)
{
return num1/num2;
}
int main(void)
{
//函数的数据类型 返回值类型 (形参列表)
// int (int,int)
//1.定义一个指向函数的指针变量
int (*pFun) (int,int)=NULL;
//int a;
//为了简化操作,函数名代替了函数的首地址
pFun=add;
printf("add=%d\n",pFun(12,3));
//2.定义一个函数指针数组,该数组中有4个元素,每个元素是一个指向函数的指针 int
arr[4]={12,34,56,78}
int (*pFunArr[4]) (int,int)={add,sub,mul,div};
//add <---> pFunArr[0]
int i=0;
for(i=0;i<4;i++)
{
printf("%d ",pFunArr[i](12,3));
}
printf("\n");
return 0;
}
函数指针作为函数的参数
#include <stdio.h>
int add(int num1,int num2)
{
return num1+num2;
}
int sub(int num1,int num2)
{
return num1-num2;
}
int mul(int num1,int num2)
{
return num1*num2;
}
int div(int num1,int num2)
{
return num1/num2;
}
//编写一子函数,实现两个整数的相关运算
//参数1: 函数的指针 int (*)(int,int ) 函数的类型int (int ,int)
//参数2: int num1
//参数3: int num2
//返回值:运算的结果
int cal(int (*pfun)(int,int),int num1,int num2)
{
return pfun(num1,num2);
}
int main(void)
{
printf("%d ",cal(add,12,3)); //+
printf("%d ",cal(sub,12,3)); //-
printf("%d ",cal(mul,12,3)); //*
printf("%d \n",cal(div,12,3)); //(/)
return 0;
}
给函数指针取了别名
typedef struct student Stu; //struct student ------>Stu
#include <stdio.h>
int add(int num1,int num2)
{
return num1+num2;
}
int sub(int num1,int num2)
{
return num1-num2;
}
int mul(int num1,int num2)
{
return num1*num2;
}
int div(int num1,int num2)
{
return num1/num2;
}
//1.给函数指针取了别名
typedef int (*pFun)(int,int); //int (*) (int,int) --->pFun 类型名
//4.函数指针作为参数传参
//参数1:函数的指针
//参数2: int num1
//参数3: int num2
//返回值:int
int cal(pFun pf,int num1,int num2)
{
return pf(num1,num2);
}
int main(void)
{
//2.定义一个函数指针变量
pFun pf=add;
printf("%d\n",pf(12,3));
//3.定义一个函数指针数组
pFun pfunArr[4]={add,sub,mul,div};
int i=0;
for(i=0;i<4;i++)
{
printf("%d ",pfunArr[i](12,3));
}
printf("\n");
printf("%d ",cal(add,12,3));
printf("%d ",cal(sub,12,3));
printf("%d ",cal(mul,12,3));
printf("%d \n",cal(div,12,3));
return 0;
}
指针函数
定义:返回值是指针的函数
<存储类型> 数据类型 函数名(参数列表)
int* add()
int* add(int a, int b)
{
int *p = NULL;
return p;
}
调用:
int* res = add(a, b);
使用NULL时,必须引用stdio.h头文件
堆区的使用
定义在自定义函数中的变量会随着程序的结束而释放,如果我们想得到变量的值,必须使用静态的变量。
但是这样会导致内存无法及时释放,资源占用大。所以引出堆区空间的使用。
堆区:程序员自己申请自己释放的一片的空间。
申请空间
<1> 函数原型
#include <stdlib.h>
void* malloc(size_t size);
<2> 函数参数
size_t size
size_t————>unsigned int
ssize_t————>signed int
size————>申请空间大小(字节)
<3>函数返回值
void* 类型的指针————>万能指针
成功返回:申请到(开辟)空间的首地址
失败返回:NULL
<4>函数调用
int* malloc_func()
{
int* ptr = (int*)malloc(sizeof(int));
if(ptr == NULL)
{
printf("申请失败\n");
}
return ptr;
}
int main()
{
int* pr = malloc_func();
}
递归
存储类型
static extern auto register
auto 自动的
//类型名 变量名
// 存储类型 类型名 变量名
auto
register 寄存器 (CPU中的存储器)
register int i=10;
static 静态的
修饰全局变量 (隐藏)
修饰函数 (隐藏)
修饰局部变量