首页 > 代码库 > Linux c基本知识整理

Linux c基本知识整理

1.指针和引用的区别

1.指针是一个变量,变量存储一个地址指向内存中一个存储单元,需要单独分配内存空间。引用相当于变量的别名,不需要单独分配空间

2.引用必须初始化,指针可以先不进行初始化

3.指针可以设置为const类型,引用不可以为const

4.作为形参时,引用在函数体内可直接修改原值,指针是原变量的一个拷贝

5.单目运算符++,作用在引用上int a=1;int b=&a; b++相当于a++;

作用在指针上int a =1; int *b=&a; b++只表示指针地址增加,a不曾变化

6.指针可以有多级,引用只有一级。

7.指针定义后可以修改为执行其他的存储单元,引用定义后不能修改。

8.sizeof运算符处理后,计算指针表示指针的大小:32为系统得到4;计算引用得到相应类型的大小:char型引用为1.

2.volatile作用(cpu缓存机制),实例有哪些?

在编译优化时,为了优化执行速度,有些变量在调用时使用保存在寄存器中的拷贝。使用volatile修饰的变量表示这个变量会被意外改变,每次使用都应小心的从内存读取原值

>现象举例:

  1.状态寄存器的内容

  2.中断服务程序中访问的非自动变量

  3.多线程程序的共享变量

3.static const用法说明(参数及变量)。

>const用法:

  1.在定义的时候必须进行初始化

  2.表示不会被程序修改的变量

  3.修饰形参表示形参在调用函数体内不能被修改

  4.修饰指针时的几种情况:

    const int *a 指针指向的为一个常整形数

    int *const a 指针是一个常指针

    const int *a const 一个执行常整形数据的常指针

static用法:

  1.static变量只会被定义一次,避免了多重定义的问题

  2.static变量默认初始化为0,存储在静态存储区BSS段。变量会被放在程序的全局存储区中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。

  3.变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。

  4.函数中必须要使用static变量情况:比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。

4.内联函数作用,与宏定义的区别。内联函数为什么定义在头文件中并且加static

宏的作用是基本的字符替换,在编译阶段进行。内联函数的使用时为了节省掉函数调用的时间,省去了call和ret并且具备函数功能

  1.内联函数在运行时可调试,而宏定义不可以;

  2.编译器会对内联函数的参数类型做安全检查或自动类型转换(同普通函数),而宏定义则不会;

  3.内联函数可以访问类的成员变量,宏定义则不能;

  4.在类中声明同时定义的成员函数,自动转化为内联函数。

>内联函数为什么定义在头文件中并且加static

  inline 关键字实际上仅是建议内联并不强制内联,gcc中O0优化时是不内联的,即使是O2以上,如果该函数被作为函数指针赋值,那么他也不会内联,也必须产生函数实体,以获得该函数地址。

  经测试c文件中的仅inline函数即使Os优化也不内联,因为没有static,编译认他是全局的,因此像普通函数一样编译了,本c文件也一样通过 bl inline_func 这样的方式调用,不像网上别人说的,本c会内联,其他c文件则通过bl inline_func 方式。加入static 后则内联了。(Os优化等级测试)

  所以在头文件中用inline时务必加入static,否则当inline不内联时就和普通函数在头文件中定义一样,当多个c文件包含时就会重定义。所以加入static代码健壮性高,如果都内联了实际效果上是一样的。(gcc下验证过O0级别includes.h中仅定义inline的函数,编译失败,Os编译成功)

  虽然知道了头文件中用inline函数时要加入static,但是为什么要在头文件中定义函数呢?

  一些简单的封装接口函数,如 open() { vfs_open() } 仅仅是为了封装一个接口,我们不希望耗费一次函数调用的时间,解决方法一是宏,但是作为接口,宏不够清晰。那选择inline,但是如果在c文件中写

main.c

inline void open(void)

{ vfs_open(); }

  头文件声明,外部要使用则不会内联的,因为编译器有个原则,以c文件为单位进行逐个编译obj,每个c文件的编译是独立的,该c文件用到的外部函数都在编译时预留一个符号,只有等到所有obj生成后链接时才给这些符号地址(链接脚本决定地址),所以其他c文件编译时只会看到这个函数的声明而无法知道她的实体,就会像普通函数一样通过bl 一个函数地址,等链接的时候再填入该地址了,他做不到内联展开。
  所以要内联则必须在每个用到它的c文件体现实体,那就只有在头文件了,所以把这类希望全局使用并且增加效率的函数实现在头文件中添加static inline。

5.静态内存分配和动态内存分配区别。

 

6。枚举与#define的区别

 

7.内存对齐规则。

 

8.动态分配对象与静态分配对象区别。

 

9.内存溢出有哪些因素。

 

10.new/delet与malloc/free区别。

 

11.模板怎么实现,模板的作用

 

12.多线程锁机制有哪些

 

13.自旋锁和互斥锁区别。

 

14.进程间通信和线程间通信方法

 

15.

Linux c基本知识整理