6.9学习内容

课程安排:
1、二级指针;
2、宏定义和自定义函数的区别;===》内联函数;
3、#define和typedef;
4、结构体、共用体、枚举和位运算;大小端!


明天:链表


二级指针:
一级指针是变量 ===》既然是变量,所以肯定有地址! ==》有没有其他的手段来保存一级指针
变量的地址?
==》引入了二级指针:用来保存一级指针的地址!
1、掌握二级指针变量的定义方法;
二级指针要掌握的东西:
1、各个指针变量里面保存的是什么值;
2、对各个指针变量进行取值操作的时候,里面是什么值;
3、*p1 *p2 **p2是什么意思;
4、随便给你a p1 p2 &a &p1 &p2 *p1 *p2 **p2要能够推出其他的东西;
也就是你要掌握我画的那张图;


int char float long:在内存里面,都是以0 1的形式保存的!只是解析的方式不一样;
int a  = 10;
%d  %c %f
0x12345678;


宏定义函数和自定义函数:
在预处理阶段要处理哪些东西?
1、头文件:#include ....   //#include <stdio.h>   #include "stdio.h"
2、宏定义:#define ...
3、注释;
4、条件编译:#if ...  #elif ... #endif
总结一下:带#都是在预处理阶段处理的!


宏定义怎么定义:
#define 宏定义变量名  宏定义本质上的内容   //注意的是:没有分号!
为什么需要宏定义;
1、修改方便,减少很多不必要的工作量;
2、防止出错!


宏定义函数和自定义函数的区别:
1、宏定义是在调用的地方原地展开;
  自定义函数是跳转到函数定义的地方调用,调用结束之后再返回到函数调用的地方;
  ===》带来的实质区别是:
  ===》宏定义函数没有调用开销,而自定义函数是需要有调用开销的(需要保存现场,有入栈
和出栈的操作)
  ===》宏定义函数不需要进行参数类型的检查,也没有返回值类型;但是自定义有参数类型的
  ===》检查和返回值类型的检查!这个检查是由编译器完成的,如果调用的时候传入的实参和
  ===》函数的形参不一样的话,要么报警告要么报错!【会提示你发生了错误】


什么时候用宏定义函数,什么时候用自定义函数?
1、函数体比较简单的时候,不需要进行参数类型检查的时候,可以用宏定义函数!
2、函数体比较复杂,需要进行参数类型检查和返回值类型判断的时候,用自定义函数!


有没有一种手段可以兼具宏定义函数和自定义函数的优点?
  ==》既可以进行参数类型和返回值类型的检查,又可以进行原地展开!
  ==》内联函数!
  ==》在函数定义的时候,在前面加上inline关键字;不是在函数声明的时候添加;
  ==》请求编译器在编译的时候,将这个函数当成是“内联函数”来编译!
  ==》既然是请求的话,编译器一般都会拒绝!因为如果当成是“内联函数”来编译的话,放到
  ==》“符号表”里面,会浪费内存!
  ==》在C语言里面其实是没有“内联函数”的! ===》C++的时候是有内联函数!


//自带的内联函数:两个_ _组成的!
printf("%d\n",__LINE__); //打印当前行数;
printf("%s\n",__func__); //打印当前所在的函数;
printf("%s\n",__TIME__);
printf("%s\n",__DATE__); 


#define和typedef;
共同点:都可以对其他内容进行重命名;
#define dint int
typedef int tint;


#define dint int*
typedef int* tint;
区别:
1、dint c,d; //int* c,d; c是int *;d是int;
   tint e,f; //e和f都是int *;


2、 unsigned dint g; //unsigned int * g;   OK
// unsigned tint h; //unsigned int * h;   error;
define的类型可以和unsigned之类的其他类型进行组合;
typedef就不可以!
3、本质上是define只是进行单纯的替换;
define是在预处理阶段处理;
typedef是在编译阶段进行处理;

#define STR "HELLO"


char *p = STR; //char *p = "HELLO";
printf("%s\n",STR);


/*********************/
输入:从终端输入一个整型数据;
输出:将输入的整型数转化为字符串输出;
例如:
输入:123   //整型
输出:123 //字符串

int2str():
1 + '0' = '1';

'5' - '0' = 5;

补充了:goto语句  少用,会破坏程序的结构!

结构体:
什么是结构体?为什么需要结构体?没有结构体行不行?有了结构体之后有什么好处?
对于结构体有哪些操作?

数组的特点是什么?或者是数组有哪些缺点?
char num[4] = {0}; //printf("%s\n",num);
1、数组里面的元素类型必须是一样的; //结构体来解决!
2、数组的大小一旦定义的话,后面没办法改变了; //链表来解决;

现在想保存张远的一些个人信息:姓名,学号,性别;
char name[10] = {0};
int xuehao = 0;
int sex = 0; //1表示男生,0表示女生;

将一些紧密联系的信息保存在一个结构里;===》结构体:

结构体类型所占字节大小:


对于结构体中的字节对齐:
下面仅限于32位系统:对齐参数!
1、变量的自身对齐参数:
   在32位系统中,CPU字长是4个字节;
   变量的自身对齐参数 = CPU字长和变量本身的字节长度中的较小的一个!
   ===》变量的自身对齐参数 <= 4个字节
   
2、编译器默认的对齐参数:#pragma pack(n) n可以取 1 2 4 但是在32位中n默认取4
32位系统中默认是4;
   
两条原则:
1、结构体变量所占空间的大小是"对齐参数"的整数倍!
   ==》对齐参数 = 结构体中所有变量的对齐参数的最大值和系统默认参数中较小的一个;
   
2、每个变量相对于结构体的首地址的偏移量必须是对齐参数的整数倍!
   ==》对齐参数 = 每个变量自身对齐参数和系统默认对齐参数中较小的一个;


   
计算结构体所占字节大小的方法:
1、确定分配单位:
2、确定字节大小所占空间是谁的倍数!
   
梳理一下:
我们现在所做的事情,就是“想知道结构体类型所占字节大小是多少?”
==》分配单位:
==》1.如果结构体里面的数据类型,最大的那一个大于等于4,那么我们的分配单位就是4;
==》2.如果结构体里面的数据类型,最大的小于4,那么我们的分配单位就是那个最大的;
==》填充问题;


   
   
C语言中结构体中不允许含有静态数据成员;是单独存放在静态数据区的,sizeof的时候没有将
静态变量所占的空间计算进来!
发布了23 篇原创文章 · 获赞 20 · 访问量 1万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览