关键字

extern关键字

extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。此外extern也可用来进行链接指定。

也就是说,extern有两个作用:

当它与"C"一起连用时,如:extern “C” void fun(int a, int b);,则告诉编译器在编译fun这个函数名时按着C的规则去翻译相应的函数名而不是C++的,C++的规则在翻译这个函数名时会把fun这个名字变得面目全非,可能是fun@aBc_int_int#%$也可能是别的,这要看编译器的"脾气"了(不同的编译器采用的方法不一样)。为什么这么做呢,因为C++支持函数的重载;

当extern不与"C"在一起修饰变量或函数时,如在头文件中:extern int g_Int; ,它的作用就是声明函数或全局变量的作用范围的关键字,其声明的函数和变量可以在本模块和其他模块中使用,记住它是一个声明不是定义!也就是说B模块要是引用模块A中定义的全局变量或函数时,它只要包含A模块的头文件即可,在编译阶段,模块B虽然找不到该函数或变量,但它不会报错,它会在连接时从模块A生成的目标代码中找到此函数。

在一个文件中定义的全局变量默认为外部的,即关键字extern可以省略,但如果在其他的文件中使用这个文件定义的全局变量,则必须在使用前用extern进行外部声明。

也就是说,用extern修饰只是表示声明变量,不表示定义变量。如果不用extern修饰的全局变量,就默认声明加定义了。

static关键字

static关键字的作用有:
static修饰局部变量:被修饰的变量成为静态变量,存储在静态区。存储在静态区的数据生命周期与程序相同,在main函数之前初始化,在程序退出时销毁。局部静态变量使得该变量在退出函数后,不会被销毁,因此再次调用该函数时,该变量的值与上次退出函数时值相同;
static修饰全局变量:全局变量本来就存储在静态区,因此static并不能改变其存储位置。但是,static限定该全局变量在本编译单元内,一个编译单元就是指一个cpp和它包含的头文件;
static修饰普通函数:限定该函数只能在本编译单元内被调用;
static修饰成员变量:所有的对象都只维持同一个实例,可以采用static可以实现不同对象之间数据共享;
static修饰成员函数:类中的static成员函数属于整个类所拥有,这个函数不接收this指针,所以只能访问类的static成员变量。
static与extern是一对“水火不容”的家伙,也就是说extern和static不能同时修饰一个变量;其次,static修饰的全局变量声明与定义同时进行,也就是说当你在头文件中使用static声明了全局变量后,它也同时被定义了;最后,static修饰全局变量的作用域 只能是本身的编译单元,也就是说它的“全局”只对本编译单元有效,其他编译单元则看不到它。
参考:https://blog.youkuaiyun.com/ginwafts/article/details/78884435

volatile关键字

一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:

存储器映射的硬件寄存器通常也要加voliate,因为每次对它的读写都可能有不同意义;
在中断函数中的交互变量,一定要加上volatile关键字修饰,这样每次读取非自动存储类型的值(全局变量,静态变量)都是在其内存地址中读取的,确保是我们想要的数据;
多任务环境下各任务间共享的标志应该加volatile。
一个参数既可以是const还可以是volatile吗?

可以的,例如只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。软件不能改变,并不意味着我硬件不能改变你的值,这就是单片机中的应用。

const关键字

简单地说,const意味着常数。

const定义的变量,它的值不能被改变,在整个作用域中都保持固定;
同宏定义一样,可以避免意义模糊的数字出现,同样可以很方便地进行参数的调整和修改;
可以保护被修饰的东西,防止意外的修改,增强程序的健壮性。const是通过编译器在编译的时候执行检查来确保实现的。
const与指针:修饰指针、修饰指针指向的对象;

const与函数

修饰函数形参,如果形参是一个指针,为了防止在函数内部修改指针指向的数据,就可以用 const 来限制;
修饰返回值,表明函数的返回值是一个常量;
修饰类成员函数(放在函数的参数表之后,函数体之前),表示该函数的this指针是一个常量,不能修改该对象的数据成员。

define和const

define和const的区别:

const 定义的常数是变量,也带类型, #define 定义的只是个常数,不带类型;
define是在编译的预处理阶段起作用,而const是在 编译、运行的时候起作用;
define只是简单的字符串替换,没有类型检查。而const有对应的数据类型,是要进行判断的,可以避免一些低级的错误;
const变量存放在内存的静态区域中,在程序运行过程中const变量只有一个拷贝,而#define 所定义的宏变量却有多个拷贝,所消耗的内存要比const变量的大得多;
用define可以定义一些简单的函数,const是不可以定义函数的;
define可以用来防止头文件重复引用,而const不能;
const不足的地方,是与生俱来的,const不能重定义,而#define可以通过#undef取消某个符号的定义,再重新定义;
在编译时, 编译器通常不为const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。

Malloc:

定义上:malloc memory allocation 动态内存分配 是c中的一个函数
使用方法:

extern void *malloc(unsigned int num_bytes)

num_bytes内存块字节长度。

内存块大小确定:malloc是通过我们计算然后得到一块新内存,然后指定数据类型并且内存值也是随机的。

使用时:需要引入头文件库函数 stdlib.h 或是 malloc.h(malloc.h与alloc.h一致)。

内存分配位置:堆中动态分配的内存。

具体分配过程:由程序向操作系统申请,操作系统遍历空闲结点链表,将第一个大于申请空间的堆结点分配给程序,然后将空闲结点链表中此节点删掉。

成功分配:返回值为指向被分配内存的指针。

失败分配:返回值为空NULL。

返回类型:void* (未确定类型的指针)。

void*类型可以通过强制类型转换转换为任意其他类型(因为用户存储数据类型未知,由用户决定数据类型)。

内存块释放:free()函数 将内存还给程序或操作系统。

注意:malloc与free都属于c/c++标准库函数,在使用时应该配对 申请之后不释放就会有可能发生内存泄漏。

使用free时需要检查指针是否为空。

New:

new 是c++中的运算符(其地位等同于“+”,“=”)。

在使用:new时不止分配内存,还会进行初始化,执行相应构造函数,初始化时需要指定数据类型。

内存分配位置:自由存储区为对象分配内存。

使用时:无需引入头文件,new是保留字。

new 和 delete 是配对使用的。

在使用delete时注意将指针置为0,否则会形成悬垂指针(指针所指内存已被释放,仍指向该内存),造成错误。

new 可以看做是malloc 加 构造函数的执行,就是new更高级一些。

new的几种用法:

int *p=new int; //在自由存储区开辟一个int变量 
int *p=new int[10];//在自由存储区开辟一个int数组,有10个元素
int *p=new int(10);//在自由存储区开辟一个int变量,并初始化为10

释放内存时无需检查是否为空。

如果p等于NULL,则delete p不作任何事情。由于之后可以得到测试,并且大多数的测试方法论都强制显式测试每个分支点,因此你不应该加上多余的 if 测试。

new与malloc

malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。
new可以认为是malloc加构造函数的执行。new出来的指针是直接带类型信息的。而malloc返回的都是void指针。

有了malloc/free为什么还要new/delete?
它们都可用于申请动态内存和释放内存。
malloc是库函数只能作用于内部数据类型,对于非内部数据动态对象而言,就不能完成对象的初始化与销毁,即执行构造函数与析构函数。
而new 与 delete此类运算符就能够在编译器的控制权限内完成,对象的初始化与销毁任务,即执行构造函数与析构函数。

为什么C++不把malloc/free淘汰出局呢
这是因为C++程序经常要调用C函数;而C程序只能用malloc/free管理动态内存。

我们不要企图用malloc/free来 完成动态对象的内存管理, 应该用new/delete。由于内部数据类型的“对象”没有构造与析构的过程,对它们而言malloc/free和new/delete是等价的。

注意: 如果用free释放“new创建的动态对象”,那么该对象因无法执行析构函数而可能导致程序出错。

如果用delete释放“malloc申请的动态内存”,结果也会导致程序出错,但是该程序的可读性很差。所以new/delete必须配对使用,malloc/free也一样。

malloc 与 new 对于内存泄漏问题
内存泄漏对于malloc或者new都可以检查出来的,区别在于new可以指明是那个文件的那一行,而malloc没有这些信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值