现在的位置:主页 > 综合新闻 >

C/C++编程笔记:C语言编程需要掌握的核心要点有(2)

来源:电脑编程技巧与维护 【在线投稿】 栏目:综合新闻 时间:2020-08-25

【作者】网站采编

【关键词】

【摘要】函数指针与回调(callback) c source code被编译链接后,函数被转换到可执行程序文件的text节,进程启动的时候,会把text节的内容装载到进程的代码段,代码

函数指针与回调(callback)

c source code被编译链接后,函数被转换到可执行程序文件的text节,进程启动的时候,会把text节的内容装载到进程的代码段,代码段是c进程内存空间的一部分,所以任何c函数都会占一块内存空间,函数指针就是指向函数在代码段的第一行汇编指令,函数调用就会跳转到函数的第一个指令处执行。

函数指针经常被用来作为回调(callback),c语言也会用包含函数指针成员的结构体模拟OOP,本质上是把C++编译器做的事情,转给程序员来做(C++为包含虚函数的类构建虚函数表,为包含虚函数的类对象附加虚函数表的指针)。

字符串

char*是一类特殊的指针,它被称为c风格字符串,因为它总是以‘\\0’作为结尾的标识,所以要标识一个字符串,有一个char*指针就够了,字符串的长度被0隐式指出,跟字符串相关的STD C API大多以str打头,比如strlen/strcpy/strcat/strcmp/strtok。

内存和内存管理

指针提供了c语言直接操作底层内存的能力,c程序区分栈内存和堆内存,栈内存是函数内的局部变量,它随程序执行而动态伸缩,所以不要返回临时变量的指针,栈内存容量有限(8/16M),所以我们要避免在函数内创建过大的局部变量,要警惕递归爆栈。

堆内存也叫动态内存,它由一个叫动态内存配置器的标准库组件管理,glibc的默认动态内存配置器叫ptmalloc,初始版本有性能问题,但后面用线程私有解决了竞争改善了性能。动态内存配置器是介于kernel与应用层的一个层次,从内核视角看ptmalloc是应用程序,从应用层来看ptmalloc又是系统库。malloc跟free必须配对,这是程序员的职责,动态分配的内存丢失引用就会导致内存泄漏,指向已释放的内存块俗称野(悬垂)指针。

预处理

从c source file到可执行程序需要经过预处理-编译-汇编-链接多个阶段,预处理阶段做替换、消除和扩充,预处理语句以#打头。

宏定义,#define,宏定义可以用\\做行连接,#用来产生字符串,##用来拼接,宏定义的时候要注意加()避免操作符优先级干扰,可以用do while(0)来把定义作为单独语句,#undef是define的反操作。

#if #ifdef #ifndef #else #elif #endif用来条件编译,为了避免头文件重复包含,经常用#ifndef #define #endif。

#include用来做头文件包含;#pragma用来做行为控制;#error用来在编译的时候输出错误信息。

__FILE__、__LINE__、_DATE_、_TIME_、_STDC_等标准预定义宏可以被用来做一些debug用途。

#typedef用来定义类型别名。比如typedef int money_t;money_t比int更有含义。

typedef也能用来为结构体取别名,有时候会这样写:

typedef struct{ int a; int b;} xyz_t;复制代码

这样在定义结构体变量的时候就可以少敲几下键盘。

typedef也可以用来重定义函数指针类型,比如 typedef void (*PF) (int a, int b); PF是函数指针类型,而非函数指针变量。

枚举

枚举能增加代码可读性和可维护性,枚举本质上是int,只是为了更有含义,将有限取值的几个int值放在一组,比如定义性别:enum sex { male = 1, female };

可以在定义的时候赋值,比如male=1,后面的值依次递增1,如果不赋值则从0开始。

联合体(union)

结构体和联合体(共用体)的区别在于:结构体的各个成员会占用不同的内存,互相之间没有影响;而共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。

其实本质上,联合体就是对一块内存的多种解释,大小按最大的来。

位域(bitfield)

节省空间,在面向底层的编码,或者编写处理网络等程序时候用的比较多,注意这个语法特征是跟机器架构相关的。

位操作

位于 &

位或 |

位取反 ~

位异或 ^

位移 << >>

static、extern、register、volatile、sizeof

(1)static修饰全局函数,表示模块内(编译单元)内可用,不需要导出全局符号。

(2)static修饰局部变量,意味超越函数调用的生命周期,不存储在栈上,只会被初始化1次。

(3)extern声明外部变量。

(4)register,寄存器变量,建议编译器将变量放在寄存器里。

(5)volatile,告诉编译器不要做优化,每次从内存读取,不做寄存器优化。

(6)sizeof求大小,可以作用于变量,类型,表达式

文章来源:《电脑编程技巧与维护》 网址: http://www.dnbcjqywh.cn/zonghexinwen/2020/0825/414.html

上一篇:和码编程又获千万美元级投资,高增长、正现金
下一篇:Python编程!模块化开发!艾利特CS系列颠覆式创新

电脑编程技巧与维护投稿 | 电脑编程技巧与维护编辑部| 电脑编程技巧与维护版面费 | 电脑编程技巧与维护论文发表 | 电脑编程技巧与维护最新目录
Copyright © 2018 《电脑编程技巧与维护》杂志社 版权所有
投稿电话: 投稿邮箱: