C/C++ 关键字

2021-06-05 15:02

阅读:692

标签:通过   读取数据   打破   属性   param   volatil   释放   取值   直接插入   

C语言关键字:

关键字就是已被C语言本身使用,不能作其它用途使用的字。例如关键字不能用作变量名、函数名等。由ANSI标准定义的C语言关键字共32个:

根据关键字的作用,可以将关键字分为数据类型关键字和流程控制关键字两大类。

  1. 数据类型关键字
    A. 基本数据类型(5个)
    void :声明函数无返回值或无参数,声明无类型指针,显式丢弃运算结果
    char :字符型类型数据,属于整型数据的一种
    int :整型数据,通常为编译器指定的机器字长
    float :单精度浮点型数据,属于浮点数据的一种
    double :双精度浮点型数据,属于浮点数据的一种

B. 类型修饰关键字(4个)

short :修饰int,短整型数据,可省略被修饰的int
long :修饰int,长整形数据,可省略被修饰的int
signed :修饰整型数据,有符号数据类型
unsigned :修饰整型数据,无符号数据类型
32位编译器:
char:1个字节 = 8个bit
char*(即指针变量):4个字节(32位的寻址空间是2^32, 即32个bit,也就是4个字节。同理64位编译器)
short:2个字节
int:4个字节
unsigned int:4个字节
float:4个字节
double:8个字节
long:4个字节
long long:8个字节
unsigned long:4个字节

64位编译器:
char:1个字节
char*(即指针变量):8个字节
short:2个字节
int:4个字节
unsigned int:4个字节
float:4个字节
double:8个字节
long:8个字节
long long:8个字节
unsigned long:8个字节

C. 复杂类型关键字(5个)

struct :结构体声明
union :共用体声明
enum :枚举声明
typedef :声明类型别名
给一个已经存在的数据类型(注意:是类型不是变量)取一个别名,而非定义一个新的数据类型。
typedef struct student
{
    //code
} Stu_st,*Stu_pst;
(1) struct student stu1;和Stu_st stu1;没有区别。
(2) struct student *stu2;和Stu_pst stu2;和Stu_st *stu2;没有区别。
typedef 通常被用于以下三种目的: 
为了隐藏特定类型的实现,强调使用类型的目的。 
简化复杂的类型定义,使其更易理解。 
允许一种类型用于多个目的,同时使得每次使用该类型的目的明确。
sizeof :得到特定类型或特定类型变量的大小

D. 存储级别关键字(6个)
auto :指定为自动变量,由编译器自动分配及释放。通常在栈上分配
编译器在默认缺省情况下,所有变量都是auto。
static :指定为静态变量,分配在静态变量区,修饰函数时,指定函数作用域为文件内部
(1) 修饰变量。变量又分为局部和全局变量,但它们都存在内存的静态区。
静态全局变量:作用域仅限于变量被定义的文件中,其他文件即使用extern 声明也没法使用他。准确地说作用域是从定义之处开始,到文件结尾处结束,在定义之处前面的那些代码行也不能使用它。
静态局部变量:在函数体里面定义的,就只能在这个函数里用了,同一个文档中的其他函数也用不了。由于被static 修饰的变量总是存在内存的静态区,所以即使这个函数运行结束,这个静态变量的值不会被销毁,函数下次使用时仍然能用到这个值。
(2) 修饰函数。函数前加static 使得函数成为静态函数。static对函数的作用域仅局限于本文件(所以又称内部函数)。使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名。
register :指定为寄存器变量,建议编译器将变量存储到寄存器中使用,也可以修饰函数形参,建议编译器通过寄存器而不是堆栈传递参数。
register变量必须是能被CPU 寄存器所接受的类型。意味着register 变量必须是一个单个的值,并且其长度应小于或等于整型的长度。而且register 变量可能不存放在内存中,所以不能用取址运算符“&”来获取register 变量的地址。
extern :指定对应变量为外部变量,即标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。
const :与volatile合称“cv特性”,指定变量不可被当前线程/进程改变(但有可能被系统或其他线程/进程改变)
编译器通常不为普通const 只读变量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的值,没有了存储与读内存的操作,使得它的效率也很高。例如:

define M 3 //宏常量

const int N=5; //此时并未将N 放入内存中
int i=N;    //此时为N 分配内存,以后不再分配!
int I=M;    //预处理期间进行宏替换,分配内存
int j=N;    //没有内存分配
int J=M;  //再进行宏替换,又一次分配内存!
const 定义的只读变量从汇编的角度来看,只是给出了对应的内存地址,而不是同#define一样给出的是立即数,所以,const 定义的只读变量在程序运行过程中只有一份拷贝(因为它是全局的只读变量,存放在静态区),而#define 定义的宏常量在内存中有若干个拷贝。

define 宏是在预处理阶段进行替换,而const 修饰的只读变量是在编译的时候确定其值。

define 宏没有类型,而const 修饰的只读变量具有特定的类型。

const int p; //const 修饰p,p 是指针,p 是指针指向的对象,不可变
int const p; //const修饰p,p 是指针,
p 是指针指向的对象,不可变
int *const p; //const修饰p,p 不可变,p 指向的对象可变
const int const p; //前一个const 修饰p,后一个const 修饰p,指针p 和p 指向的对象都不可变
void Fun(const int i);//告诉编译器i 在函数体中的不能改变,从而防止了使用者的一些无意的或错误的修改
const int Fun (void);//返回值不可被改变。
volatile :与const合称“cv特性”,指定变量的值有可能会被系统或其他进程/线程改变,强制编译器每次从内存中取得该变量的值
volatile 关键字是一种类型修饰符,遇到volatile声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。
int i=10;
int j = i; //(1)语句
int k = i; //(2)语句
这时候编译器对代码进行优化,因为在(1),(2)两条语句中,i 没有被用作左值。这时候编译器认为i 的值没有发生改变,所以在(1)语句时从内存中取出i 的值赋给j 之后,这个值并没有被丢掉,而是在(2)语句时继续用这个值给k 赋值。编译器不会生成出汇编代码重新从内存里取i 的值,这样提高了效率。但要注意:(1),(2)语句之间i 没有被用作左值才行。

volatile int i=10;
int j = i;//(3)语句
int k = i;//(4)语句
volatile 关键字告诉编译器i 是随时可能发生变化的,每次使用它的时候必须从内存中取出i的值,因而编译器生成的汇编代码会重新从i 的地址处读取数据放在k 中。这样看来,如果i 是一个寄存器变量或者表示一个端口数据或者是多个线程的共享数据,就容易出错,所以说volatile可以保证对特殊地址的稳定访问。

  1. 流程控制关键字
    A. 跳转结构(4个)
    return :用在函数体中,返回特定值(或者是void值,即不返回值)
    continue :结束当前循环,开始下一轮循环
    break :跳出当前循环或switch结构
    goto :无条件跳转语句
    禁用goto 语句。自从提倡结构化设计以来,goto 就成了有争议的语句。首先,由于goto 语句可以灵活跳转,如果不加限制,它的确会破坏结构化设计风格;其次,goto 语句经常带来错误或隐患。它可能跳过了变量的初始化、重要的计算等语句。

B. 分支结构(5个)
if :条件语句,后面不需要放分号
else :条件语句否定分支(与if连用)
switch :开关语句(多重分支语句)
case :开关语句中的分支标记
(1) 每个case 语句的结尾必须使用break,否则将导致多个分支重叠(除非有意使多个分支重叠),最后必须使用default 分支。即使程序真的不需要default 处理,也应该保留语句:
default :
break;
(2) case 后面只能是整型或字符型的常量或常量表达式

default :开关语句中的“其他”分支,可选。

C. 循环结构(3个)
for :for循环结构,for(1;2;3)4;的执行顺序为1->2->4->3->2...循环,其中2为循环条件。在整个for循环过程中,表达式1只计算一次,表达式2和表达式3则可能计算多次,也可能一次也不计算。循环体可能多次执行,也可能一次都不执行。
do :do循环结构,do 1 while(2); 的执行顺序是1->2->1...循环,2为循环条件
while :while循环结构,while(1) 2; 的执行顺序是1->2->1...循环,1为循环条件
以上循环语句,当循环条件表达式为真则继续循环,为假则跳出循环。

C++语言关键字:
asm
asm允许在代码中直接插入汇编语言指令,各种不同的编译器为这一个指令允许不一致形式, 比如:
asm {
      instruction-sequence
}
or
asm( instruction );
inline 
inline int functionA(int i) {
...
}
声明定义内联函数(模版),提示编译时内联,将所调用的代码嵌入到主调函数中。注意是否内联取决于实现,编译器有权不实际内联,如果它认为这是必要的或更符合预期的目标代码质量。但inline还改变了ODR(One Definition Rule,单一定义规则)的适用性。类似函数模版,在头文件直接定义inline函数不会视为重复定义违反ODR而编译出错。C++中,一个函数若声明inline,则每处声明都必须保证是inline,和C语言允许extern inline或static inline不同,尽管C++实现可以提供类似非标准的扩展。注意类成员函数若在类定义内给出定义则隐含inline。
C++11中,新增inline namespace,指示命名空间中的名称同时是外层命名空间直接包含的名称。这便于命名空间的版本管理,减少冲突。
bool true/false
bool即布尔类型,属于基本类型中的整数类型,取值为真和假。true和false是具有bool类型的字面量,是右值,分别表示真和假。
dynamic_cast
dynamic_cast (object);
关键字dynamic_cast强制将一个类型转化为另外一种类型,并且在执行运行时时检查它保证它的合法性。如果想在两个互相矛盾的类型之间转化时,cast的返回值将为NULL.
const_cast
const_cast (object);
关键字const_cast用于移除"const-ness"的数据,修改类型的const或volatile属性。除了const 或volatile修饰之外, type_id和expression的类型是一样的。
常量指针被转化成非常量的指针,并且仍然指向原来的对象。
常量引用被转换成非常量的引用,并且仍然指向原来的对象。
static_cast
static_cast (object);
关键字static_cast用来在两个不同类型之间进行强制转换,并且没有运行时间检查.
reinterpret_cast
reinterpret_cast (object);
reinterpret_cast 操作能把一种数据类型改变成另一种.它应当被用在两种不可调和的指针类型之间. 
typeid
获取表达式的类型,以std::type_info表示结果,可能抛出std::bad_typeid。当操作数非多态类(引用)类型在编译时即可确定结果,否则需要在运行时取得结果,即RTTI。
typename
告诉编译器一个嵌套的限定名(包含::)中的未知的标识符是一个类型。这只在模板中需要区分依赖名称时使用。
另一种用法是在模版声明参数列表中表示模版类型参数,可被class代替。
mutable 
用于类的非静态非const数据成员,表示不受到成员函数的const的限制,可以在const成员函数中使用。
try, catch, throw
C++ 处理异常的系统给程序一个比较可行的机制用于错误校正。try指定try块的起始,try块后的catch可以捕获异常。异常由throw抛出。throw在函数中还表示动态异常规范
try {
    statement list;
  }
catch( typeA arg ) {
    statement list;
  }
catch( typeB arg ) {
    statement list;
  }
  ...
  catch( typeN arg ) {
    statement list;
  }
explicit
这个关键字修饰构造函数声明,表示显式构造函数(模版),显式构造函数不参与特定的重载。
C++11从两个角度扩展了用法。其一是适用于转换函数(模版),类似构造函数,避免不需要的重载。其二是列表初始化,除非直接使用std::initializer_list,显式构造函数被列表初始化忽略(在C++98/03中,explicit仅对单一参数调用构造函数有意义,这里打破了这个限制)。
namespace
namespace name {
declaration-list;
}
表示命名空间,其中可以声明若干标识符,组成的名称与其它命名空间不冲突。

using 
class
关键字class允许你创建新的数据类型. class-name 就是你要创建的类的名字,并且 inheritance-list 是一个对你创建的新类可供选择的定义体的表单.类的默认为私有类型成员,除非这个表单标注在公有或保护类型之下. object-list 是一个或一组声明对象。
class class-name : inheritance-list {
private-members-list;    
protected:
protected-members-list;
public:
public-members-list;
} object-list;
operator
virtual
声明虚基类或虚函数。具有虚基类或虚函数的类是多态类(polymorphic class),需要运行时提供支持来判断成员函数调用分派到的具体类型。
public
在类中的公共数据可以被任何人访问,也能用来指定派生。
protected 
保护数据对于它们自己的类是私有的并且能被派生类继承,也能用于指定派生。所有的公共和保护成员的基类可以变成保护的派生类。
private
属于私有类的数据只能被它的内部成员访问,除了friend使用。也能用来继承一个私有的基类,所有的公共和保护成员的基类可以变成私有的派生类。
friend 
声明友元,使其不受访问权限控制的限制。允许类或函数访问一个类中的私有数据。
template
template return-type name( parameter-list ) {
statement-list;
}
this 
this是一种实体,仅在类的非静态成员中使用,是指向类的对象的指针右值。
wchar_t 
用来声明字符变量的宽度。
————————————————
版权声明:本文为CSDN博主「赵健乔」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/miaodichiyou/article/details/43954591

C/C++ 关键字

标签:通过   读取数据   打破   属性   param   volatil   释放   取值   直接插入   

原文地址:https://www.cnblogs.com/Nonrustknife/p/14624728.html


评论


亲,登录后才可以留言!