函数
1、如何理解库函数
库是已经写好的、成熟的、可复用的代码。每个程序都需要依赖很多底层库,不可能每个人的代码从零开始编写代码,因此库的存在具有非常重要的意义。在我们的开发的应用中经常有一些公共代码是需要反复使用的,就把这些代码编译为库文件。库可以简单看成一组目标文件的集合,将这些目标文件经过压缩打包之后形成的一个文件。像在Windows这样的平台上,最常用的c语言库是由集成按开发环境所附带的运行库,这些库一般由编译厂商提供
2、如何理解指针作为函数参数的输入和输出特性
输入特性:主调函数分配空间 背调函数使用该空间
输出特性:被调用分配空间 主调函数使用该空间
3、函数名的意义
在c语言中 函数名代表的是函数的入口地址
4、函数的形参和实参的区别
C++
int data1=0;
int data2=0;
int my_add(int x, int y)
{
return x+y;
}
int main()
{
my_add(data1,data2);
}
形参:在函数定义时候定义形参(例如:x,y),一般由形参类型和形参名组成。在定义函数是不会为形参开辟空间,只有在函数调用时系统才会为形参开辟空间
实参:在函数调用时传递给函数的实际参数(例如:data1,data2),他在函数调用前就存在的
5、函数的作用
将为同一功能服务的代码,封装在一起,通过函数名直接调用,提高代码的重用
6、函数的定义与函数的声明的区别
函数定义:是指对函数功能的确立,包括指定函数名、函数类型、形参及其类型、函数体等,它是一个完整的、独立的函数单位。
函数的声明:是把函数的名字、函数类型以及形参的个数、类型和顺序(注意,不包括函数体)通知编译系统,以便在对包含函数调用的语句进行编译时,据此对其进行对照检查(例如函数名是否正确,实参与形参的类型和个数是否一致)
7、从定义的角度为函数分类
库函数(c语言库)、自定义函数、系统调用(内核提供给用户的函数接口)
8、从有无参数的角度对函数分类
无参的函数:不能将函数外部的数据 传递 给函数内部
有参的函数:通过参数 将函数外部的数据 传递到函数内部
(参数:函数外部数据 到 函数内部的 桥梁)
9、普通变量作为函数的参数特点
函数内部可以借助函数的参数使用外部变量的值,但是函数内部不能通过形参间接修改外部变量的值(单向传递中的值传递)
10、一维数组作为函数的参数的特点
数组作为函数的参数,会被优化成数组元素指针变量,在调用函数的时候实参只需要传递数组的首元素地址就可以操作数组的所有元素
11、在32位平台Void func(int arr[5]){}则sizeof(arr)的结果
4字节
12、二维数组作为函数的特点
二维数组作为函数的参数会被优化成数组指针,函数内部可以借助该数组指针操作二维数组的所有元素。在操作数组元素上该数组指针等价于函数外部的二维数组名
字符串
宏函数以及作用
在项目中,经常把一些短小而又频繁使用的函数写成宏函数,这是由于宏函数没有普通函数参数压栈、跳转、返回等的开销,可以调高程序的效率。宏通过使用参数,可以创建外形和作用都与函数类似地类函数宏(function-like macro). 宏的参数也用圆括号括起来,来保证宏函数的完整性。
strlen和sizeof的区别
strlen是测量字符串长度(不包含'\0'),sizeof是测量类型大小(包含‘\0’)
字符串的结束标记
一般将'\0'作为字符串的结束标记,以str开头的字符串操作函数默认遇到'\0'结束调用
字符串的常用操作
字符串拷贝(strcpy),比较(strcmp)、拼接(strcat)、查找(strchr,strstr)、 长度(strlen)、获取子串(strtok)
在使用realloc给已分配的堆区空间追加空间时需要注意啥
realloc给定的空间大小必须是新空间+旧空间的大小
记得用指针变量保存realloc的返回值
宏函数和普通函数的区别
普通函数只有一份,在调用的时候为函数内部数据分配空间,每次调用函数是独立的。函数在调用的时候存在出入栈的开销。函数的形参有类型 能保证参数的整型
宏函数:本质是宏 而不是函数,他是在预处理阶段展开,多次调用,展开多次,没有函数调用时的"出入栈"开销。宏函数的参数没有参数不能保证参数的完整性
条件编译的作用
条件编译的作用:在编译阶段有选择的编译我们的源码,达到同一个源码裁剪出不同的功能
以str开头的字符串操作函数的特点
字符串的操作函数基本都是传递字符串首元素地址
字符串的操作函数基本都是遇到'\0'结束操作
结构体共用体枚举
描述结构体对齐规则
1. 数组成员对齐规则。第一个数组成员应该放在offset为0的地方,以后每个数组成员应该放在offset为min(当前成员的大小,#pargama pack(n))整数倍的地方开始(比如int在32位机器为4字节,#pargama pack(2),那么从2的倍数地方开始存储)。
2. 结构体总的大小,也就是sizeof的结果,必须是min(结构体内部最大成员,#pargama pack(n))的整数倍,不足要补齐。
3. 结构体做为成员的对齐规则。如果一个结构体B里嵌套另一个结构体A,还是以最大成员类型的大小对齐,但是结构体A的起点为A内部最大成员的整数倍的地方。(struct B里存有struct A,A里有char,int,double等成员,那A应该从8的整数倍开始存储。),结构体A中的成员的对齐规则仍满足原则1、原则2。
如何理解结构体的浅拷贝与深拷贝
当结构体中有指针成员的时候容易出现浅拷贝与深拷贝的问题。
浅拷贝就是,两个结构体变量的指针成员指向同一块堆区空间,在各个结构体变量释放的时候会出现多次释放同一段堆区空间
深拷贝就是,让两个结构体变量的指针成员分别指向不同的堆区空间,只是空间内容拷贝一份,这样在各个结构体变量释放的时候就不会出现多次释放同一段堆区空间的问题
描述枚举
关键字enum,将枚举变量将要赋值的值 一一用符号常量(枚举值)列举出来。枚举变量尽量赋值为给定的符号常量(枚举值)
描述共有体
以关键字union修饰,共有体又叫联合体,共有体中的成员共享同一块内存空间。
内存空间总大小由共用体中最大的成员类型决定,每个成员能够操作的空间大小是由成员自身类型大小决定
描述结构体
以关键字struct修饰,结构体中的成员拥有各自独立的空间,按照(结构体对齐规则)存储在内存中
结构体中的成员类型可以不同
结构体与共用体的区别
结构体中的成员拥有独立的空间,共用体的成员共享同一块空间,但是每个共用体成员能访问共用区的空间大小是由成员自身的类型决定
结构体变量初始化时需要注意啥
结构体变量的初始化 必须遵循结构体成员的顺序以及成员的自身类型
谈谈你对结构体数组的理解
结构体数组:本质是数组,数组的每个元素为结构体变量。
谈谈你对结构体位域的理解
在结构体中,以位为单位的成员,咱们称之为位段(位域)
不能对位域取地址
对位域赋值 不要超过 位域本身位的宽度
谈谈你对链表的理解
链表是由一个个节点组成,节点没有名字,每个节点从堆区动态申请,节点间物理上是非连续的,但是每个节点通过指针域 保存下一个节点的位置 达到逻辑上连续
谈谈数组和链表的不同点
数组通过下标能够快速遍历数组的每个元素(访问效率高),但是当数组插入或删除数据时需要移动大量的数据(插入删除效率低)
链表通过指针域逐个节点的访问数据(访问效率低),但是当链表插入或删除节点不需要移动节点(插入删除效率高)
文件操作
文件缓冲区刷新方式有几种
行刷新、满刷新、强制刷新、关闭刷新
文件的分类
文件分为二进制和文本文件
二进制文件基于值编码,需要根据具体的应用才能知道某个值具体的含义
文本文件基于字符编码,一个字节一个意思,可以通过记事本打开
二进制文件和文本文件的区别
文本文件:
基于字符编码,常见编码有 ASCII、UNICODE 等 ,一般可以使用文本编辑器直接打开 例如:数 5678 的以 ASCII 存储形式为: ASCII 码:00110101 00110110 00110111 00111000
二进制文件:
基于值编码,把内存中的数据原样输出到磁盘上,一般需要自己判断或使用特定软件分析数据格式例如:数 5678 的存储形式为: 二进制码:00010110 00101110
c语言中fopen打开文件的模式(mode)有哪些
文件的打开方式mode:r w a + t b
r:只读的方式打开 w:只写的方式打开 a:追加的方式打开 +:可读可写方式打开
t:以文本文件方式打开 (默认是省略)
b:以二进制方式打开(必须显示说明)
对FILE*文件指针读写的API
Fgetc 和fputc 一次读写一个字符
fgets和fputs 一次读写一个字符串
fread和fwrite按快读写文件
fscanf和sprintf格式化读写文件
文件的随机读写API有哪些
rewind复位文件流指针
ftell返回文件流指针 距离文件首部的 字节数
fseek文件流指针定位