C++关键字总结【新手必学】
const 关键字——常量
const 与define
define是预编译器的编译指令,它从C语言兼容下来,工作方式与文本编辑器中的全局搜索和替换相似。define定义的常量的意义在它开始的地方持续到文件结束,在预编译阶段,预编译器已经将所有define删除,并展开所有的宏定义。它单纯只做文本替换,没有类型安全检查,define命令会很容易引入错误,并且这种错误很难发觉,因此C++中用const取代define预编译指令。另外很多人在学习Python的过程中,往往因为没有好的教程或者没人指导从而导致自己容易放弃,为此我建了个C++交流.裙 :九起久伞吧起伞留伞(数字的谐音)转换下可以找到了,里面有最新C++教程项目可拿,不懂的问题多跟里面的人交流,都会解决哦!
#define SIGMOID(x) (1/(1+exp(-x)))
result = SIGMOID(a+b);//没有正确添加括号,会导致错误结果
result = SIGMOID((a+b));//正确
头文件里的const
const默认是内部链接,如果它被放在头文件中,目的是为了让所有包含它的编译单元能使用这个值,而且是仅让包含头文件的编译单元可见。定义一个const时,必须初始化,除非用extern做出了外部引用。通常,C++编译器不会为const变量分配空间,但extern关键字会强制编译器为const变量分配存储空间。因为extern为外部链接,为了其他的编译单元都能引用到const变量。变量必须要有存储空间。
注:由于编译器不能避免为const分配内存,所以const定义必须默认内部链接。在C++中,const常量是否被分配空间依赖于它如何被使用:对于基本数据类型的常量,编译器会把它放到目标文件的符号表中而不分配存储空间,而自定义的const对象则需要分配存储空间(大对象)。还有一些情况下也需要分配存储空间,例如强制声明为extern或取一个const的地址等操作。
const关键字与多线程安全
可重入是并发安全的保障,一个可重入的函数(函数没有执行完成,由于外部因素或内部调用,又一次进入函数执行)在多线程的环境下可以放心使用。而为了保证一个函数是可重入的,它必须使用任何(局部)静态或非const全局变量。同时,不能返回任何(局部)静态或非const全局变量的指针。
类中的const
在类中定义的非静态const变量,这个类的不同的对象可以含有一个不同的值。const的初始化在类的构造函数的初始化列表中。
static const——编译期间类里的专属常量
static意味着“不管类的对象被创建多少次,都只有一个实例”。必须在static const定义的地方对它初始化。C++用它来代替enum(枚举型),来指示对象的共同属性。它是为整个类服务,而不是某个对象,所以它不能使用this指针(this指针是对成员函数调用时用来指示调用对象的),也不能在复制构造函数中被复制。如果你取某个类的专属常量的地址或编译器坚持要看到一个定义式,则用域名解析符定义一下
//GamePlayer.h中
class GamePlayer{
private:
static const int NumTurns = 5;
int scores[NumTurns];
};
//GamePlayer.cpp中
const int GamePlayer::NumTurns;//NumTurns在class声明中已经初始化,因此这里不再设初值
const对象和成员函数
不修改数据成员的任何函数都应该声明为const,这样它可以和const对象一起使用。
按位const:对象中的每个字节都不能变。
按逻辑const:可以以成员为单位改变。
两种实现按逻辑const的方法
一种是取this指针,并把它强制转换成指向当前类型对象的指针,具体来说就是讲将this强制转换成普通指针。
另一种是使用关键字mutable,以指定一个特定的数据成员可以在一个const对象中被改变。
static关键字——静态区、内部链接
static关键字有两个作用,一个让变量存在静态区,另一个是让错误限制在一个源文件内。让局部变量声明成static使局部变量存储在静态区,从而在程序的整个生命期都存在。同时,当static作用于全局变量时,该全局变量变为内部链接,它的意思是“在文件的外部不可以使用这个名字”,从而使错误局部化。
static全局变量与全局变量的区别是静态变量只初始化一次,防止在其他文件中被引用;static局部变量与普通局部变量的区别除了值在启动程序时初始化一次外,就是它的值在程序的整个周期内都存在,两次函数调用期间,它的值保持不变;局部静态变量在函数调用之间的值保持不变,根据这个特性,可以用于记录函数调用或类创建的一些信息。
static函数与普通函数的区别是static函数在内存中只有一份,而普通函数在每次被调用都维持一份拷贝。
extern关键字——外部变量
extern关键字用来声明另一个文件中的全局变量。所以extern和static是矛盾的,不能同时使用。
extern “C”关键字
C++编译器将extern “C”中的代码单做C语言代码处理。extern C大括号所包围的范围中,C++的名称修饰机制不起作用,对于Visual C++,直接在变量名和函数名前加”_”。但对于Linux下的GCC,extern “C”后面的符号都是修饰后符号。
注:在C语言中不支持使用extern关键字
这里列举我平时编程时遇到的问题及处理方案
在我用vs2012调用C语言写的库时,出现“error LNK2019: 无法解析的外部符号 clGetPlatformIDs“的错误。
原因通常是没有包含相应的lib,也就是说链接器没搜索到相应lib中的clGetPlatformIDs目标模块,基于这种情况,我思考会不会是这个函数在头文件中是C语言函数的声明与定义,但是我又在C++代码中包含该头文件,导致其采用C++的名称修饰机制而无法与C语言库中符号链接。所以对于C++调用C库,需要添加extern “C”关键字声明。
通常的做法是定义宏
#ifdef __cplusplus
extern C" {
#endif
cl_int clGetPlatformIDs(...);
#ifdef _cplusplus
}
#endif
但是如果这个C源码已经编译成库,但是模块的头文件中没有包含extern “C”,则在C++文件中,需要添加
extern "C"{
#include "cl.h"
这相当于在cl.h头文件中所有的声明都添加了extern。
链接与const、static、extern——内存分配与读写
无链接性:在代码块中的局部变量(包括static局部变量)
外部链接:函数之外定义的所有变量(除了const变量)和函数默认为外部链接性。在定义时使用extern关键字显式指定标识符具有外部链接。也就是说在多个文件程序中,可以在文件并且只能在一个文件中定义全局变量,其他文件要使用该变量,要在变量前添加extern关键字。当有extern时,只是告知编译器存在这个变量,编译器并不为该变量分配存储空间,即真正的声明;若没有extern,则在声明的同时,编译器也为该变量分配存储空间。
内部链接:全局static变量和const变量为内部链接,为了使const具有外部链接以便让另外一个文件可以对它引用,必须在当前文件里明确把它定义为extern并初始化。
应使用链接性为外部的多文件程序的不同文件中共享数据,而使用链接性为内部的静态变量在同一文件中的多个函数间共享数据
volatile关键字
告诉编译器“该变量不知道何时回改变“,防止编译器依据变量的稳定性(短期内值不变)作任何优化。
volatile关键字与多度优化
在多线程环境下,即使合理地使用了锁,也不一定能保证线程安全。
x=y=0
Thread1 Thread2
x=1 y=1
r1=y r2=x
由于CPU的动态调度或编译器的优化,执行程序时,有可能交换两条毫不相干的相邻指令的顺序,导致r1=r2=0的情况的发生。而volatile关键字可以试图阻止优化。
(1)阻止编译器为了提高速度将一个变量缓存到寄存器而不写回。也就是说防止编译器根据变量的稳定性作任何优化,假设要读一个硬件中的寄存器,将使用这个关键字。无论何时需要volatile变量的值,编译器都要硬着头皮头读,即使该行之前刚刚读过。
(2)阻止编译器调整volatile变量的指令顺序。(这一步其实只能阻止编译器的优化换序,并不能 阻止CPU动态调度换序)
注:阻止CPU乱序执行的唯一办法是调用CPU提供barrier指令;
关键字restrict
关键字restrict只用于限定指针;该关键字用于告知编译器,所有修改该指针所指向内容的操作全部都是基于(base on)该指针的,即不存在其它进行修改操作的途径;这样的后果是帮助编译器进行更好的代码优化,生成更有效率的汇编代码。
最后注意一点,restrict是C99中定义的关键字,C++目前并未引入;在GCC可通过使用参数” -std=c99”
来开启对C99的支持
enum枚举类型
本质上,enum是一个int型,但C++不允许enum到int的隐式转换。枚举的类型名也是可选的。enum{ a,b,c}choice;可以立即定义一个enum实例。一个类中的枚举在编译期间分配值,不占用对象的内存空间。但通常优先选择static const而尽量不是用enum。枚举常量的缺点是:它的隐含数据类型是整数,其最大值有限,且不能表示浮点数
register变量
关键字register只是告诉编译器“尽可能快地访问该变量”dawn并不能保证将变量放置在寄存器中。同时,register有许多限制,比如不能获取register变量的地址,不能将其声明为全局或静态变量,因为register变量没有内存地址。因此,最好避免使用。
————————————————
另外很多人在学习Python的过程中,往往因为没有好的教程或者没人指导从而导致自己容易放弃,为此我建了个C++交流.裙 :九起久伞吧起伞留伞(数字的谐音)转换下可以找到了,里面有最新C++教程项目可拿,不懂的问题多跟里面的人交流,都会解决哦!
以上,有些内容转自网络,如有侵权,请联系博主改正。
C++关键字总结【新手必学】的更多相关文章
- Python基础语法总结【新手必学】
前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:weixin_45189038直接上知识点: 1. 注释 单行注释: ...
- Python 如何定义只读属性?【新手必学】
前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:Daniel2333如果还没学到属性问题,看不懂不怪你,可以先去小编的P ...
- 浅谈HTML之模仿人人网登陆界面(新手必学)
为方便大家对web相关知识的了解,现谈谈新手如何从HTML css Javascript到以后后台的发展.首先,让大家看看HTML仿人人登陆界面: <!doctype html> < ...
- PHP新手必学之刚进公司装环境
由于今天去一家公司做项目,又重新的装了一遍所熟悉的PHP环境,所以记录下来,总结下. PHP环境主要: PHPstudy(apache+mysql+php)+phpstorm+navicate 解释: ...
- Python爬虫之cookie的获取、保存和使用【新手必学】
前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:huhanghao Cookie,指某些网站为了辨别用户身份.进行ses ...
- 一款简单的C++猜数字游戏(新手必学)
前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:1只小弛 废话不多说,直接上代码! #include<bits/s ...
- Python学习笔记—自动化部署【新手必学】
前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:唯恋殊雨 目录 pexpect fabric pexpect P ...
- 【新手必学】Python爬虫之多线程实战
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:清风化煞_ 正文 新手注意:如果你学习遇到问题找不到人解答,可以点 ...
- Python自动输入【新手必学】
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:哈喽哈嘿哈 这篇文章是我的第一篇文章,写的不好的地方,请大家多多指教哈 ...
随机推荐
- 记一次使用正则表达式+foreach控制器调试
使用forEach控制器时,变量为上一个请求返回的参数(通过正则表达式提取),设置好控制器的起始值后发现每次都是只执行一个,然后开始怀疑人生,百度了各种材料,最后还是决心好好的观察自己每一步是不是错了 ...
- 1.1Jmeter学习网站
在网上找到一些关于Jmeter学习的博客等,在此标记 一. chinaunix的一篇博客,讲的蛮详细的 http://blog.chinaunix.net/uid/26884465/cid-16819 ...
- 快递查询API
https://market.aliyun.com/products/56928004/cmapi014394.html#sku=yuncode839400000
- Linux - curl 基本使用
1. 概述 我接触过的很多服务端调试, 接口测试, 最终都落到了这个地方 简答介绍 curl 的使用 尽量循序渐进, 因为我也不太熟悉 大概会提到的命令 curl curl -v curl -s cu ...
- CSS学习(1)简介
什么是 CSS? CSS 指层叠样式表 (Cascading Style Sheets) 样式定义如何显示 HTML 元素 样式通常存储在样式表中 把样式添加到 HTML 4.0 中,是为了解决内容与 ...
- LOJ#6713. 「EC Final 2019」狄利克雷 k 次根 加强版
题目描述 定义两个函数 \(f, g: \{1, 2, \dots, n\} \rightarrow \mathbb Z\) 的狄利克雷卷积 \(f * g\) 为: \[ (f * g)(n) = ...
- uni-app 去除顶部导航栏
自学uni-app第一天,因为有一点点的小程序和vue的基础所以感觉对uni-app有一点点的亲切感,从今天呢开始着手从登录页学习uni-app,记录一些用到的知识点,欢迎大家一起学习. 启动页隐藏顶 ...
- (办公)记事本_linux网络命令
参考谷粒学院的linux视频教程:http://www.gulixueyuan.com/course/300/task/7091/show 阿里云ECS云服务器更换公网IP的方法:https://yq ...
- SQL注入--sqli-labs(1-4关)
Less_1 查库:select schema_name from information_schema.schemata 查表:select table_name from information_ ...
- BUUCTF-Web-Warm Up(CVE-2018-12613)
题目(虽然是Warm up,但一点也不简单): 打开只有图片,源码里面提示了source.php 查看source.php: php代码里又提到了hint,去查看一下: 提示flag在如上图文件名里面 ...