关键字的作用及区别汇总

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zm1_1zm/article/details/76919136

static关键字

static关键字具有隐藏式、记忆、延长生命周期的作用。

在C语言中,static既可以修饰变量,也可以修饰函数。

1)        修饰的变量保存在静态数据区,静态变量默认初始化为0,只初始化一次。

2)        修饰局部变量,延长变量的生命周期,直到程序运行结束,下一次运行依据是上一次的运行结果,体现其记忆功能。

3)        修饰全局变量,只在本文件可见,其他文件隐藏。

4)        修饰函数,只在本文件中调用,其他文件不可调用。

在C++中,static既可以修饰成员变量,也可以修饰成员函数。

1)        修饰的成员变量保存在全局数据区,被所有对象共享,在没有实例时就可以使用它,必须对它进行初始化且只能在类外进行初始化,只有整型静态常量才可以在类外进行初始化。static修饰的成员变量能被所有类方法访问,值可以改变;当被protected或者private修饰时,不能被类外访问。

2)        修饰的成员函数属于类,被所有对象共享,无this指针。只能访问静态成员,调用其他静态成员方法;不能访问非静态成员,调用非静态成员方法。

静态变量与全局变量的区别

1)        静态变量具有局部稳健域,全局变量具有全局作用域

2)        静态局部变量只对定义它的函数体可见,静态全局变量和全局变量对整个文件可见

3)        静态全局变量对本文件可见,对其他文件不可见,全局变量对所有文件可见

4)        静态局部变量之初始化一次,静态全局变量每次调用都会初始化。

全局变量与局部变量的区别

1)        局部变量存储在栈区,全局变量存储在静态全局区

2)        局部变量的生命期随局部函数的结束而结束,全局变量的生命期随主程序的结束而结束

3)        局部变量对定义它的函数内有效,静态局部变量对本文件有效;全局变量在整个工程文件夹内都有效,静态全局变量对本文件有效。

4)        局部变量的初始值为随机值,全局变量的默认初始值为0

5)        在C语言中,全局变量和静态变量是在编译阶段进行分配内存和初始化的,局部变量是在编译阶段进行分配内存,在运行时进行初始化的。

 

const关键字

const关键字在一定程度上可以提高程序的安全性和可靠性。

C语言中,const可以修饰普通变量,指针,函数形参,函数返回值。

1)        修饰普通变量时,该变量为只读变量,不能通过变量名修改变量的值,但可以通过地址修改;

2)        修饰指针时,const在*左边,用于修饰指针指向的变量,即指针指向的是常量,不能通过指针改变变量的值;const在*右边,用于修饰指针本身,即指针本身是常量,不能指向其他对象。

3)        修饰函数形参时,防止形参在函数执行过程中被修改,便于调试。

4)        修饰函数返回值时,和修饰普通变量和指针的作用相同。

C++中,const可以修饰成员变量、成员函数、类对象、引用、

1)        修饰成员变量时,必须在构造函数的参数列表中进行初始化,不能在构造函数体内初始化;

2)        修饰成员函数时,函数体内不能修改该类的所有成员变量,不能调用非const成员函数。

3)        修饰类对象,该类对象中的所有成员变量都不能修改,该类对象不能调用该对象的非const成员函数。

4)        修饰引用时,该引用所引用的对象不能改变。

5)        const可以作为函数重载的一个依据。

const与#define的区别:

1)        处理方式不同:const在编译运行阶段使用;define在预处理阶段展开。

2)        类型和安全检查不同:const定义的变量有类型,并且在编译时会进行类型安全检查;而define没有。

3)        存储方式不同:const存储在数据段,在堆栈分配内存;define存储在代码段,不分配内存。

4)        const一定程度上节省了内存空间,const定义的变量给出的是内存地址,在运行时只有一份拷贝;define定义的变量给出的是立即数,在内存中有若干个拷贝。

const修饰的常量可以排除程序间的不安全性因素,保证程序中的常量不被修改,并且会进行类型的安全检查,提高了程序的健壮性,最好用const来定义常量,而不是define。

宏定义的优缺点:

优点:

1)        提高了程序的阅读性,方便进行修改;

2)        提高了程序的运行效率,带参的宏定义既能实现函数的功能,又避免函数出栈入栈操作,减小系统开销;

3)        宏定义可以实现很多编译器无法实现的功能,如##连接符

缺点:

1)        无法进行类型检查

2)        无法单步操作

3)        由于优先级的问题,使用宏定义可能存在副作用;

4)        会导致代码膨胀

5)        无法操作类的私有数据成员

6)        宏定义很容易产生二义性。

枚举与宏定义的区别

1)        枚举常量是实体中的一种,而宏定义不是实体

2)        枚举常量属于常量,而宏定义不属于

3)        枚举常量有具体的类型,而宏定义没有

4)        枚举常量有与普通变量相同的作用域、值等性质,而宏定义没有

5)        枚举常量在编译期间确定值,而宏定义在预编译期间进行替换

6)        枚举常量可以一次定义很多常量,宏定义一次只能定义一个。

typedef与define的区别

1)        格式不同:typedef语句需要加分号;define不是语句,不需要加分号

2)        原理不同:typedef是在编译期处理的,具有类型检查功能;define是在预编译阶段进行替换,没有任何类型检查。

3)        功能不同:typedef是给一个已经具有的类型起一个别名,可以是基本类型,也可以是自定义类型struct;宏定义不仅可以给类型取别名,还可以定义变量、常量、编译开关等。

4)        作用域不同:typedef有作用域,宏定义没有作用域。

5)        对指针操作不同:

#define int* INTPTR1

typedef INTPTR2 int*;

INTPTR1 a,b;//int *a, b;

INTPTR2 c,d;//int *c, *d;

宏函数与函数有什么区别?

1)        处理方式不同:函数是先求出实参表达式的值,带入形参;宏函数只是简单的符号替换。

2)        处理时间不同:函数是在运行时处理的,需分配内存空间;宏函数是在预编译阶段处理的,展开时不分配内存空间。

3)        参数类型:函数的形参和实参有具体类型,且类型要一致;宏函数没有具体类型

4)        返回值个数:函数的返回值只有一个;宏函数的返回值可以设法获得多个

5)        运行时间:函数调用占用运行时间;宏函数的替换不占用运行时间

6)        代码空间:函数调用不会使源程序变长;宏函数的替换会使源程序变长

7)        参数求值:函数调用前实参只求值一次;参数每次用于宏定义时,都要重新求值,可能会产生不可预料的结果。

宏函数与内联函数的区别

1)        处理时间不同:宏函数是在预处理阶段进行替换,内联函数是在编译阶段插入代码

2)        类型检查:宏函数没有类型检查,宏函数有类型检查。

3)        内联函数可以访问类的成员变量,宏函数不可以

4)        在类中声明同时定义的函数自动转为内联函数。

内联函数与普通函数的区别

1)        内联函数的参数传递机制与普通函数相同,但是编译器在每处调用内联函数的地方将内联函数的内容展开,避免函数调用的开销,也没有宏机制的缺陷。

2)        普通函数实现时首先跳跃到函数的入口地址,执行函数体,执行完返回调用的地方,函数始终只有一个拷贝;内联函数没有寻址的过程,在每次调用处都会展开,会有若干个拷贝

 
 

volatile关键字的含义

volatile修饰的变量,每次使用它时都会去内存读取,而不是寄存器中的备份。编译器不会对该类变量进行优化。

volatile一般修饰多线程中多个任务共享的变量、中断子程序中会访问到的非自动变量和并行设备硬件寄存器。

一个变量用const修饰的同时还可以用volatile修饰,原因是const表明这个对象体现常量语义,程序不应该试图修改它,但同时可能会被当前对象所在程序上下文意外的情况修改,此时可加上volatile。

 

explicit关键字的作用

explicit用于修饰含有一个参数的构造函数,表明该构造函数是显式的,禁止编译器进行非预期的类型转换。effective C++中建议使用该关键字修饰构造函数。

 
 

struct和union的区别

1)        存放位置:struct所有成员占用空间是累加的,不同成员放在不同地址;union所有成员共用一块内存地址,只存放一个被选中的成员;

2)        内存空间大小:struct的大小等于所有成员长度之和;union的大小等于最长成员的长度

3)        赋值操作:对struct的不同成员赋值互不影响;对union的不同成员赋值,会对其他成员重写,原先的成员的值就不存在了。

 
 

C语言中的struct与C++中的struct的区别

1)        C语言中的struct是用户自定义数据类型,没有设置权限;C++中的struct是抽象数据类型,有访问权限

2)        C语言中不能有成员函数,C++中可以有

3)        C语言中的struct没有继承关系,C++中有。

C++中struct与class的区别

1)        struct的成员默认权限是public,class的成员默认权限是private

2)        struct的继承默认为public,class的继承默认为private

3)        class可以定义模板参数,但struct不可以。

 

new/delete和malloc/free的区别

1)        new/delete是C++运算符,malloc/free是C/C++标准库函数。

2)        new/delete不需要头文件支持,malloc/free需要stdlib.h头文件支持。

3)        new可自动计算需要分配的内存大小,malloc需要手动计算。

4)        new返回具体类型的指针,malloc返回void类型的指针。

5)        new是类型安全的,而malloc不是。

6)        new分为new操作和构造,malloc相当于new操作。

7)        new执行构造函数,而malloc不能;delete执行析构函数,而free不能。

有new/malloc,就要有delete/free,否则会造成内存泄漏。free/delete结束后,并不是将内存直接返回给操作系统,而是告诉操作系统,这段内存可用作其他用途,但是没有重新对这块内存进行写操作,以前的数据没有变化,造成野指针,需要将其置为NULL。

 
 

sizeof和strlen的区别

sizeof是关键字,strlen是函数

sizeof的结果是创建的最大对象的字节大小,strlen返回的是字符串的长度,不包括‘\0’

sizeof可以用类型做参数,strlen只能用char*做参数,并且必须以’\0’结尾。

用数组名做参数时,sizeof不退化,strlen退化为指针。

sizeof在编译的时候计算,strlen在运行的时候计算。

sizeof返回值类型以及静态分配的对象、结构或数组所占的大小、返回值与对象、结构、数组所存储的内容没有关系;strlen只关心存储的数据内容,不关心空间的大小和类型。

struct的sizeof是所有成员对齐后的长度相加,union的sizeof是最大的成员长度。

 

exit与return的区别

1)        return返回函数值,是关键字;exit是函数。

2)        return是与言级别的,调用堆栈的返回;exit是系统调用级别的,应用程序的退出。

3)        return是C语言提供的,exit是操作系统提供的。

4)        return用于结束一个函数的执行,将返回值返回调用它的其他函数;exit用于结束应用程序,将返回一个状态给操作系统。

5)        在非主函数中调用return和exit的效果很明显,但是在主函数中两者效果类似。

 

ASEERT()和assert()

ASEERT()称为断言,是调试程序时用的宏,检查非法错误,只存在Debug版本中,Release版本中则被忽略。

ASSERT()是宏,而assert()是函数,用法和ASEERT()类似,但是可以出现在Realease版本中,需要注意的是:

1)        assert()频繁使用会影响程序的性能,增加额外地开销,可以在包含assert.h头文件之前加入#define NDEBUG来禁用assert的调用。

2)        assert在函数开始时使用

3)        一个assert一般只能检验一个条件

4)        不能使用改变环境的语句

5)        并非所有的assert都能代替过滤条件

6)        一般assert后加空行形成逻辑和视觉上的一致性。

 

猜你喜欢

转载自blog.csdn.net/zm1_1zm/article/details/76919136