探讨register关键字在c语言和c++中的差异
在c++中:
(1)register 关键字无法在全局中定义变量,否则会被提示为不正确的存储类。
(2)register 关键字在局部作用域中声明时,可以用 & 操作符取地址,一旦使用了取地址操作符,被定义的变量会强制存放在内存中。
在c中:
(1)register 关键字可以在全局中定义变量,当对其变量使用 & 操作符时,只是警告“有坏的存储类”。
(2)register 关键字可以在局部作用域中声明,但这样就无法对其使用 & 操作符。否则编译不通过。
建议不要用register关键字定义全局变量,因为全局变量的生命周期是从执行程序开始,一直到程序结束才会终止,而register变量可能会存放在cpu的寄存器中,如果在程序的整个生命周期内都占用着寄存器的话,这是个相当不好的举措。
以下是从网上摘自别人的:
C和C++处理register关键字的一处差异
C++并不是完全兼容C语言的,上次提到的sizeof('a')等于几的问题就是一例。今天我在编码时又无意中发现了一处不同:
用register关键字修饰的变量,在c语言中是不可以用&操作符取地址的,这是我已有的经验。因为编译器如果接受了程序员的建议把变量存入寄存器,它是不存在虚拟地址的。但在C++中,用register修饰的变量可以用&操作符取地址,这是我在一段代码中发现的。如果程序中显式取了register变量的地址,编译器一定会将这个变量定义在内存中,而不会定义为寄存器变量。
我在C99(ISO/IEC 9899:1999)和ISO C++(ISO/IEC 14882:2003)标准中得到了确认,C和C++标准对register遇到&的处理确实有不同的明确定义。但为什么要这样定义?我只能从标准的字里行间猜测。K&R C1中如何描述register我尚未查证,K&R C2(ANSI C)中说明了“register variables are to be placed in machine registers ... but compilers are free to ignore the advice ”。但在C99和ISO C++中,措辞分别变成:“suggests that access to the object be as fast as possible”、“a hint to the implementation that the object so declared will be heavily used”,不再特别提及“machine registers”。可见历史上register关键字在强调尽可能地把变量保存到寄存器,而现在的register关键字不再强调具体手段,只是建议编译器通过各种可行的方式优化该变量的访问(不过很多编译器会忽略这一关键字,而采用自身的优化策略)。C99可能是为了保持对K&R C的兼容而不允许取地址操作;而C++也许是因为没有历史包袱才放宽了这个限制吧。猜测而已,希望知道内幕的朋友告诉我更精确的答案。
相关推荐
-
Lua教程(四):在Lua中调用C语言、C++的函数
本教程将介绍如何在Lua里面调用c/c++函数. 在Lua里面调用c/c++函数其实是比较简单,本文将通过两个示例演示具体的做法:一个是求平均数,另一个是打印lua函数的一些参数信息. 最后,本文会介绍如何把这两个函数定义成一个模块,这样lua代码里面就可以不再使用全局的名字空间了. 前言 当我们需要在Lua里面调用c/c++函数时,所有的函数都必须满足以下函数签名: 复制代码 代码如下: typedef int (*lua_CFunction) (lua_State *L); 换句话说,所有的
-
C语言、C++内存对齐问题详解
这也可以? 复制代码 代码如下: #include <iostream> using namespace std; struct Test_A { char a; char b; int c; }; struct Test_B { char a; int c; char b; }; struct Test_C { int c; char a; char b; }; int main() {
-
C语言、C++中的union用法总结
开始的话 已经好长时间没有更新了,对不起自己,更对不起我亲爱的读者,同时也对不起自己开办的这个博客平台.忙,太忙了,忙于找工作,找一份好工作,纠结于去大城市闯呢,还是回到本省的首府城市.大家都在纠结这个问题,也希望大家和我讨论讨论.别的先不说了,都工作这么长时间了,还回过头来总结union,确实有点过分,要是和大家说我一直从事于C++开发,还不懂union,大家可能还真的不信.我们每天都在总结那些看似高端的东西,什么设计模式(当然我也有总结了).重构(后期我也会说的了)了,却忽略了那些最基础,最
-
C语言/C++中如何产生随机数
C语言/C++怎样产生随机数:这里要用到的是rand()函数, srand()函数,和time()函数. 需要说明的是,iostream头文件中就有srand函数的定义,不需要再额外引入stdlib.h;而使用time()函数需要引入ctime头文件. 使用rand()函数获取一个随机数如果你只要产生随机数而不需要设定范围的话,你只要用rand()就可以了:rand()会返回一随机数值, 范围在0至RAND_MAX 间.RAND_MAX定义在stdlib.h, 其值为2147483647. 例子
-
c语言读取csv文件和c++读取csv文件示例分享
C读取csv文件 复制代码 代码如下: #include <stdio.h>#include <string.h> char *trim(char *str){ char *p = str; while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') p ++; str = p; p = str + strlen(str) - 1; while (*p == ' ' ||
-
马尔可夫链算法(markov算法)的awk、C++、C语言实现代码
1. 问题描述 马尔可夫链算法用于生成一段随机的英文,其思想非常简单.首先读入数据,然后将读入的数据分成前缀和后缀两部分,通过前缀来随机获取后缀,籍此产生一段可读的随机英文. 为了说明方便,假设我们有如下一段话: 复制代码 代码如下: Show your flowcharts and conceal your tables and I will be mystified. Show your tables and your flowcharts will be obvious. 假设前缀的长
-
在C语言中调用C++做的动态链接库
今天在做东西的时候遇到一个问题,就是如何在C语言中调用C++做的动态链接库so文件 如果你有一个c++做的动态链接库.so文件,而你只有一些相关类的声明, 那么你如何用c调用呢,别着急,本文通过一个小小的例子,让你能够很爽的搞定. 链接库头文件: head.h class A { public: A(); virtual ~A(); int gt(); int pt(); private: int s; }; firstso.cpp #include <iostream> #include &
-
Lua教程(三):C语言、C++中调用Lua的Table示例
从写上一篇Lua的文章到现在,已经过去半月有余了,是时候让自己的Lua状态refresh一下了.本教程将介绍Lua的栈及基本栈操作,同时还有如何在C/C++代码里面读取Lua的Table. 理解Lua栈 Lua通过一个"虚拟栈"与C/C++程序进行数据交互,所有的Lua C API都是通过操作这个栈来完成相应的数据通信. Lua的这个"虚拟栈"解决了C/C++程序与Lua程序通信的两大问题: 1.Lua使用垃圾回收,而C/C++需要手动管理内存. 2.Lua使用动态
-
C语言代码中调用C++代码的方法示例
由于历史原因,以及不同开发人员的技术偏好,C语言和C++语言都有一些独有的非常有价值的项目,因而两种语言的互操作,充分利用前人造的轮子是一件非常有价值的事情. C++代码调用C代码很简单,只要分别在包含的C头文件的开头和结尾加上如下的两个块: #ifdef __cplusplus extern "C" { #endif 和 #ifdef __cplusplus } #endif 即可. 然而为了支持类.重载等更加高级的特性,在编译C++代码时,C++符号会被修饰.我们dump Linu
-
探讨register关键字在c语言和c++中的差异
在c++中: (1)register 关键字无法在全局中定义变量,否则会被提示为不正确的存储类. (2)register 关键字在局部作用域中声明时,可以用 & 操作符取地址,一旦使用了取地址操作符,被定义的变量会强制存放在内存中. 在c中: (1)register 关键字可以在全局中定义变量,当对其变量使用 & 操作符时,只是警告"有坏的存储类". (2)register 关键字可以在局部作用域中声明,但这样就无法对其使用 & 操作符.否则编译不通过. 建议不
-
详解C语言和Python中的线程混用
问题 你有一个程序需要混合使用C.Python和线程, 有些线程是在C中创建的,超出了Python解释器的控制范围. 并且一些线程还使用了Python C API中的函数. 解决方案 如果你想将C.Python和线程混合在一起,你需要确保正确的初始化和管理Python的全局解释器锁(GIL). 要想这样做,可以将下列代码放到你的C代码中并确保它在任何线程被创建之前被调用. #include <Python.h> ... if (!PyEval_ThreadsInitialized()) { P
-
c语言和c++语言中const修饰的变量区别浅析
目录 c: 修饰全局变量: 修饰局部变量: c++: 修饰全局变量: 修饰局部变量: 总结: 在c语言中: 在c++语言中: 总结 c: 修饰全局变量: 用const修饰的全局变量是没有办法直接修改的,间接的修改也是不成功的(语法可以通过,但是编译运行的时候会报错.)(const只要是修饰全局变量,那么就会储存到常量区中,收到常量区的保护.) 修饰局部变量: 但是如果用const修饰局部变量,同样的也是没有办法直接修改的,但是是可以间接修改的. int main() { const int b
-
C语言和go语言之间的交互操作方法
一.go代码中使用C代码 go代码中使用C代码,在go语言的函数块中,以注释的方式写入C代码,然后紧跟import "C" 即可在go代码中使用C函数 代码示例: go代码:testC.go package main /* #include <stdio.h> #include <stdlib.h> void c_print(char *str) { printf("%s\n", str); } */ import "C"
-
C语言和C++的6点区别
C语言和C++的区别 (1)面向过程语言和面向对象语言 C语言是面向过程语言,即先分析出解决问题的步骤然后再将这些步骤一一实现 C++是面向对象语言,即把问题分成若干个对象,目的是为了描述某个事物在解决整个问题的步骤中的行为 (2)关键字不同 C语言中有32个关键字,而C++有63个关键字.另外在C语言中struct关键字定义的变量不能有函数,而在C++中可以有函数 (3)文件后缀名不同 C语言中源文件的后缀名是.c,C++源文件后缀名是.cpp (4)函数返回值不同 C语言中如果一个函数没有指
-
C++、C语言和JAVA开发的区别
1.面向对象没有java彻底. 由于C++要兼容C的内容,而C是面向过程的,所以C++不可避免地出现过程影子,并不算是完全的面向对象的程序设计语言.例如总得要有main或winmain之类的过程吧. 2.C++的移植能力没有java好. 由于C++的事实标准的存在,即各个编译器总存在差异,所以或多或少存 在不兼容.而且各个软件平台的C++启动代码和硬件指令不同,编译后的C++程序一般是不能跨平台的.而java从娘胎里出来就是为了跨平台执行的,不采 用二进制机器码作为最终代码,所以在移植方面较好.
-
实例说明js脚本语言和php脚本语言的区别
js脚本语言和php脚本语言的区别是什么? 一句话: js是客户端脚本, 由浏览器执行. php是服务端脚本, 由php服务执行, php脚本跟shell脚本(bash执行)颇为类似. 来看看js脚本, 写一个test.html文件, 其中内容为: <script> alert("this is js"); </script> 直接双击本地的test.html文件, 结果就有一个弹框了, 因为浏览器执行了上述js脚本. 再看看看php脚本, 写一个test.ph
-
C语言 auto和register关键字
目录 一.关键字分类 二.补充内容 1.变量的分类 2.变量的作用域与生命周期 三.最宽宏大量的关键字 -- auto 四.最快的关键字 -- register 1.存储分级 2.寄存器 3.register修饰变量 一.关键字分类 C语言一共多少个关键字呢?一般的书上,都是32个(包括本书),但是这个都是C90(C89)的标准.其实C99后又新增了5个关键字.不过,目前主流的编译器,对C99支持的并不好,我们后面默认情况,使用C90,即,认为32个 二.补充内容 在正式开始讲解关键字之前,我们
-
12种实现301网页重定向方法的代码实例(含Web编程语言和Web服务器)
为什么需要使用301重定向: 1. 保留搜索引擎的排名: 301 重定向是最有效的方法,不会影响到搜索引擎对页面的排名. 2. 保留访客和流量: 如果你将页面链接到大量方法可以访问过的地址,如果不是用重定向的话你就会失去这些用户(不解)原文:If you move your popular page to which a lot of visitors have already linked, you may lose them if you don't used redirect method
-
解析c语言中"函数调用中缺少哨兵"的情况分析
在写一个练习时候出现的.觉得奇怪,因为翻译说缺少哨兵??什么意思呢...===================================== 复制代码 代码如下: /*//练习如下,创建一个进程*/#include <unistd.h>#include <stdio.h>#include <stdlib.h> int main(void){ printf("Running ps with execlp\n"); execlp("
随机推荐
- FCKeditor 图片上传进度条不动的解决方法
- Ubuntu Server 16.04安装MySQL设置远程访问出现问题的完美解决方案(error:10061)
- java 简单的计算器程序实例代码
- 基于JavaScript获取鼠标位置的各种方法
- ASP.Net页面生成饼图实例
- Python作用域用法实例详解
- Android之ListView分页加载数据功能实现代码
- Android开发之动画实现方法
- 鼠标滚轴控制文本框值的JS代码
- Python实现单词拼写检查
- Python NumPy库安装使用笔记
- js控制再次点击按钮之间的间隔时间可防止重复提交
- JQuery+Ajax实现数据查询、排序和分页功能
- 关于SQL Server 2008 安装提示"重新启动计算机失败"的解决办法
- 中文Access2000速成教程--1.1 使用“向导”设计数据库
- Android onTouchEvent事件中onTouch方法返回值(介绍)
- java 值Document解析xml详细介绍
- C#华氏温度和摄氏温度相互转换的方法
- 基础网络知识IP地址常识
- js实现点击按钮复制文本功能