-
register
2017-12-19 11:31:02(2)register 当声明对象有自动生存周期时,可以使用register修饰符。因此,register也只能用在函数内的声明中。 此关键字告诉编译器:此对象的存取应该尽量快,最好存储在CPU的寄存器中。然而,编译器不见得会...(2)register
当声明对象有自动生存周期时,可以使用register修饰符。因此,register也只能用在函数内的声明中。
此关键字告诉编译器:此对象的存取应该尽量快,最好存储在CPU的寄存器中。然而,编译器不见得会这么做。
另外要注意的是,当一个对象声明为register,就不可使用地址运算符&了,因为它有可能被放到寄存器中。1、先说register吧
在c++中:
(1)register 关键字无法在全局中定义变量,否则会被提示为不正确的存储类。
(2)register 关键字在局部作用域中声明时,可以用 & 操作符取地址,一旦使用了取地址操作符,被定义的变量会强制存放在内存中。
在c中:
(1)register 关键字可以在全局中定义变量,当对其变量使用 & 操作符时,只是警告“有坏的存储类”。
(2)register 关键字可以在局部作用域中声明,但这样就无法对其使用 & 操作符。否则编译不通过。
3333333333333333333333333333333333333333
变量作用域和生存周期
SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
C++中变量的生存周期
在C++中变量有以下两种生存周期:
#变量由编译程序在编译时给其分配存储空间(称为静态存储分配),并在程序执行过程中始终存在。这类变量的生存周期与程序的运行周期相同,当程序运行时,该变量的生存周期随即存在,程序运行结束,变量的生存周期随即终止。
#变量由程序在运行时自动给其分配存储空间(称为自动存储分配),这类变量为函数(或块)中定义的自动变量。它们在程序执行到该函数(或块)时被创建,在函数(或块)执行结束时释放所占用的空间。
注:在C++中,当标识符的作用域发生重叠时,在一个函数(或块)中声明的标识符可以屏蔽函数(或块)外声明的标识符或全局标识符。
>变量作用域示例
- #include<iostream>
- using namespace std;
- int i=0; //line 0
- int main(){
- int i=1; //line 1
- cout<<"i="<<i; //line 2
- { //line 3
- int i=2; //line 4
- cout<<"i="<<i; //line 5
- { //line 6
- i+=1; //line 7
- cout<<"i="<<i; //line 8
- } //line 9
- cout<<"i="<<i; //line 10
- } //line 11
- cout<<"i="<<i<<endl; //line 12
- system("pause");
- return 0; //line 13
- }
>程序的运行结果是:
>分析:
在函数外面定义的全局变量i(0行),它的作用域应为整个程序。在main函数开头处定义的局部变量i(1行),它的作用域为整个函数,即从1行到13行,根据上面标识符作用域冲突规定,在2行的输出语句将输出定义在1行的变量i的值,即为1。在4行定义的局部变量i,其作用域为所在块,即从4到10行,同样根据标识符作用域冲突规定,在5行的输出语句将输出定义在4行的变量i的值,即为2;同时由于7行所操作的变量i正处于定义在4行的变量i的作用范围内,因此将其值加1,得i=3,所以8行的输出语句输出变量i的值为3。同理,由于10行所输出的变量i正处于定义在4行变量i的作用域范围内,因此输出结果为3(其值在7行修改)。而在12行的输出语句所输出的变量i处于定义在1行变量i的左右范围内,因此输出结果为1(其值未被修改过)。
由于作用域的屏蔽效应,如果函数中有同名变量,则不能访问外部变量。为了能在函数内部访问函数外部定义的变量,可以使用C++中的作用域运算符“ :: ”。通过作用域运算符,即使该函数(或块)中已有与之同名的变量,也可以在函数(块)中使用定义在函数(块)外的全局变量。此外作用域运算符还可以用来指定类成员变量或成员函数所属的类。
当程序较大时,利用名字屏蔽机制是非常必要的。但是,这也会导致程序的可读性变差,好的程序设计风格应尽量避免名字屏蔽。
SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
1、局部变量
(1)作用域函数内部,从变量定义完成到达函数结束
(2)生命周期变量定义完成 到 函数调用结束
(3)初始化值随机值
(4)内存区域栈(后进先出,TOP指针,高地址向低地址生长,连续)
2、全局变量
(1)作用域整个程序(本文件,和同工程其他文件都可访问)
(2)生命周期进程建立,main调用之前 到 进程结束(特别长)
(3)初始化值0
(4)内存区域全局变量区(数据段 .date)
static,可将全局变量可见性,限定在本文件内
可将函数可见性,限定在本文件内
extern,将外部的文件中的全局变量、函数引入到本文件中,本文件
可使用外部的全局变量
3、复合语句块变量
(1)作用域复合语句块内部,从变量定义完成到达语句块结束
(2)生命周期 变量定义完成 到 函数调用结束
(3)初始化值随机值
(4)内存区域栈
4、静态变量
静态局部变量:
(1)作用域局部变量相同,函数内部,从变量定义完成到达函数结束
(2)生命周期本文件内进程建立,main调用之前 到 进程结束
(3)初始化值0
(4)内存区域全局变量区/静态变量区/数据段/.data
静态全局变量:
(1)作用域从变量定义完成时开始,整个文件可访问。但是:只能在本文件内访
问,其他文件无法访问
(2)生命周期进程建立到结束(特别长)
(3)初始化值0
(4)内存区域全局变量区/静态变量区/数据段/.data
5、外部全局变量
(1)作用域整个程序,本文件,同工程的其他文件可用
(2)生命周期进程建立到结束(特别长)
(3)初始化值0
(4)内存区域全局变量区
6、形式参数变量
(1)作用域函数内部,函数调用时可见,到达函数结束
(2)生命周期函数调用 到 函数调用结束
(3)初始化值来在于调用函数传递的实参值
(4)内存区域栈
7、堆空间(char *p = (char *)malloc(4);new)
(1)作用域动态空间
(2)生命周期start:主动调用malloc,calloc,realloc(new),申请成功时建立
end:主动调用free,堆空间释放
end:进程结束,操作系统进行内存空间回收
(3)初始化值malloc为随机值;calloc为0
(4)内存区域堆(heap,从低向高,物理上不连续)
8、寄存器变量
(1)作用域
(2)生命周期该寄存器值被其他值替换
(3)初始化值
(4)内存区域放在寄存器当中,不在内存中出现
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
44444444444444444444444444444444444444444444444444444
- int func1(void); //func1具有外部链接;
- int a = 10; //a具有外部链接,静态生存周期;
- extern int b = 1; //b具有外部链接,静态生存周期。但编译会有警告extern变量不应初始化,同时也要注意是否会重复定义;
- static int c; //c具有内部链接,静态生存周期;
- static int e; //e具有内部链接,静态生存周期;
- static void func2(int d){ //func2具有内部链接;参数d具有无链接,自动生存周期;
- extern int a; //a与上面的a一样(同一变量),具有外部链接,静态生存周期。注意这里的不会被默认初始为0,它只是个声明;
- int b = 2; //b具有无链接,自动生存同期。并且将上面声明的b隐藏起来;
- extern int c; //c与上面的c一样,维持内部链接,静态生存周期。注意这里的不会被默认初始为0,它只是个声明;
- //如果去掉了extern修饰符,就跟b类似了,无链接,自动生存周期,把上面声明的c隐藏起来;
- static int e; //e具有无链接,静态生存周期。并且将上面声明的e隐藏起来;初始化值为0;
- static int f; //f具有无链接,静态生存周期;
- }
#ifdef NOSTRUCTASSIGN
memcpy (d, s, l)
{
register char *d;
register char *s;
register int i;
while (i--)
*d++ = *s++;
}
#endif
666666666666666666666666666使用register修饰符的注意点
但是使用register修饰符有几点限制。
首先,register变量必须是能被CPU所接受的类型。这通常意味着register变量必须是一个单个的值,并且长度应该小于或者等于整型的长度。不过,有些机器的寄存器也能存放浮点数。
其次,因为register变量可能不存放在内存中,所以不能用“&”来获取register变量的地址。
由于寄存器的数量有限,而且某些寄存器只能接受特定类型的数据(如指针和浮点数),因此真正起作用的register修饰符的数目和类型都依赖于运行程序的机器,而任何多余的register修饰符都将被编译程序所忽略。
在某些情况下,把变量保存在寄存器中反而会降低程序的运行速度。因为被占用的寄存器不能再用于其它目的;或者变量被使用的次数不够多,不足以装入和存储变量所带来的额外开销。
早期的C编译程序不会把变量保存在寄存器中,除非你命令它这样做,这时register修饰符是C语言的一种很有价值的补充。然而,随着编译程序设计技术的进步,在决定那些变量应该被存到寄存器中时,现在的C编译环境能比程序员做出更好的决定。实际上,许多编译程序都会忽略register修饰符,因为尽管它完全合法,但它仅仅是暗示而不是命令。
下面是volatile变量的几个例子
1)并行设备的硬件寄存器(如:状态寄存器)
2) 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3)多线程应用中被几个任务共享的变量
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
1)一个参数既可以是const还可以是volatile吗?解释为什么。
2); 一个指针可以是volatile 吗?解释为什么。
3); 下面的函数有什么错误:
int square(volatile int *ptr)
{
return *ptr * *ptr;
}下面是答案:
1)是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。
2); 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。
3)这段代码有点变态。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
b = *ptr;
return a * b;
}
由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:
long square(volatile int *ptr)
{
int a;
a = *ptr;
return a * a;
}
位操作(Bit manipulation)TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
-
模块xxx已加载,但找不到入口点DllRegisterServer
2014-02-01 21:01:47各位友友,新年快乐! 请问下,C#创建的类库,在system32下注册 如regsvr32 xxx.dll就会出现上面的提示,如下图 [img=https://img-bbs.csdn.net/upload/201402/01/1391259638_312738.png][/img] ...多谢了 -
register变量
2020-02-24 17:46:15Register修饰符暗示编译程序相应的变量将将被频繁使用,如果可能的话,应将其保存在CPU的寄存器中,以指加快其存取速度。但是,使用register修饰符有几点限制。 首先,register变量必须是能被CPU寄存器所接受的类型...Register修饰符暗示编译程序相应的变量将将被频繁使用,如果可能的话,应将其保存在CPU的寄存器中,以指加快其存取速度。但是,使用register修饰符有几点限制。
首先,register变量必须是能被CPU寄存器所接受的类型,这通常意味着register变量必须是一个单个的值,并且其长度应小於或等於整型的长度。但是,有些机器的寄存器也能存放浮点数。
其次,因为register变量可能不存放在内存中,所以不能用取址符运算符“ & ”来获取取址符运算符“ &” register变量的地址。如果你试图这样做,编译程序就会报告这是一个错误。
register变量修饰符的用处有多大还受其它一些规则的影响。因为寄存器的数量是有限的,而且某些寄存器只能接受特定类型的数据(如指针和浮点数),因此,真正能起作用的register修饰符的数目和类型都依赖於运行程序的机器,而任何多余的register修饰符都将被编译程序所忽略。
那麽,甚麽时候使用register变量修饰符呢?回答是,对现有的大多数编译程序来说,永远不要使用register变量修饰符。早期的C编译程序不会把变量保存在寄存器中,除非你命令它这样做,这时register变量修饰符是C语言的一种很有价值的补充。然而,随着编译程序设计技术的进步,在决定哪些变量应该被存到寄存器中时,现在的C编译程序能必程序员作出更好的决定。实际上,许多C编译程序会忽略register修饰符,因为尽管它完全合法,但它仅仅是暗示而不是命令。 -
register关键字
2020-02-11 12:07:15在C语言中,register关键字用于请求编译器将变量直接定义在寄存器中(编译器可能会根据实际情况忽略这个请求)。然而,这个功能在C++中是一个鸡肋,因此大多数C++不会针对register关键字进行特殊优化。 int main(int...在C语言中,
register
关键字用于请求编译器将变量直接定义在寄存器中(编译器可能会根据实际情况忽略这个请求)。然而,这个功能在C++中是一个鸡肋,因此大多数C++不会针对register
关键字进行特殊优化。int main(int argc, char *argv[]) { register int a = 0; int *pa = &a; // C语言不允许这样做,但C++可以。 return 0; }
三、不允许定义多个同名的全局变量
对于老式的C语言编译器(比如BCC编译器),允许定义同名的全局变量,并且将它们链接到同一块内存上。虽然一些现代化的C编译器(例如gcc, VC)同样不允许这样做,但是这仍然是C的一个黑暗地带。因此,C++完全禁止了这样的做法。现在,C++中的同名的全局变量一定会引发编译错误。
int g_v = 1; double g_v = 2; // 编译错误: 定义同名的全局变量。 int main(int argc, char *argv[]) { return 0; }
四、struct关键字现在可以用来定义一个全新的类型
在C语言中,
struct
关键字仅仅用于将多个其他数据类型组合在一起,采取一定的对齐方式占用一块连续的内存空间。然而,它定义的只是一个标识符,无法直接使用这个标识符来定义变量,而必须要使用类型别名的方式来为这个标识符定义类型名称。C++针对struct
做了重要的扩充。现在,struct
被用来定义类类型,不仅直接定义一个新类型,还支持类相关的写法(更多的被用于定义POD
(Plain Old Data)类型)。struct my_struct { int a; float b; double c; }; int main(int argc, char *argv[]) { // C风格的变量定义。 struct my_struct a; // C++风格的对象定义。 my_struct c; return 0; }
五、函数声明中的参数列表为空则表示void
在C中,函数声明中的参数列表如果为空,则意味着该函数可以接受任意多的实参;而在C++中,这种写法与void等价:
int func() { //... return 0; } int main(int argc, char *argv[]) { func(1, 2, 3, 4/*....*/); // C语言允许这样做,这些变量在函数调用时被压栈。 // C++语言不允许这样做,因为参数列表被推断为void。 return 0; }
-
解决:Unknown custom element: <myData> - did you register the component correctly? For recursive ...
2019-01-03 09:23:31- did you register the component correctly? For recursive components, make sure to provide the "name" option. 2. 原因是注册方式写重了: 3. 更正写法后,这个报错消失。...前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。
1. 引用一个组件报错:
Unknown custom element: <myData> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
2. 原因是注册方式写重了:
3. 更正写法后,这个报错消失。
-
Page Register
2018-09-27 09:08:30对于flash中的每个plane,都有一个page register(或者叫cache register, data register),用于存放将要写入到物理存储单元中去的或者刚从存储单元中读取出来的数据。也就是说,nand flash的数据流向如下图所示: ..... -
hlsl register
2017-01-06 16:02:57register Optional keyword for assigning a shader variable to a particular register, which uses the following syntax: : register ( [shader_profile], Type#[subcomponent] ) -
Vue报错—— Unknown custom element: [v-table] - did you register the component correctly......
2019-04-25 15:32:08今天怂怂就为大家分享一篇如何解决自定义了一个组件vTable,在nationsjgx-detailInfo.vue中页面中使用vTable组件提示: ... - did you register the component correctly? For recursive components, make sure to p... -
FLAGS register
2016-04-02 12:12:30FLAGS register From Wikipedia, the free encyclopedia The FLAGS register is the status register in Intel x86 microprocessors that contains the current state of the processor. This reg -
xilinx shift register and Altera shift register
2018-12-13 10:25:03Xilinx shift register 一、器件手册 二、产生IP核 此为一行数据,若要多行,直接实例化即可。 Altera shift register 一、原理 二、应用 产生IP核步骤如下图所示: ... -
成功解决 from ._conv import register_converters as _register_converters
2018-09-29 08:38:19成功解决 from ._conv import register_converters as _register_converters 目录 解决问题 解决思路 解决方法 解决问题 F:\Program Files\Python\Python36\Lib\site-packages\h5py\__init__.py:34... -
register解析
2012-12-20 15:24:39register:这个关键字请求编译器尽可能的将变量存在CPU内部寄存器中,而不是通过内存寻址访问,以提高效率。注意是尽可能,不是绝对。你想想,一个CPU 的寄存器也就那么几个或几十个,你要是定义了很多很多register ... -
关于DllRegisterServer的调用失败的问题解决办法
2019-03-06 13:02:21今天在注册ActiveX控件时出错了, 错误提示是XXX.ocx已加载,但是DllRegisterServer调用失败,其实在日常的工作中,用regsvr32 命令注册dll、ocx等时,这种模块已加载,但DllRegisterServer的调用失败的问题很常见,... -
cpu之register
2017-12-19 10:15:58cpu之register -
C++ register关键字作用
2019-09-09 17:11:10register 关键字作用 register用来声明变量,然后声明出来的变量是直接放在cpu的寄存器当中,而非就是通过内存寻址访问,这样效率更高。 示例代码: #include "stdafx.h" using namespace std; int _tmain... -
mem的RegisterFile和Sram类型讨论(RegisterFile和register搭建的mem不是一回事)
2019-05-27 18:50:13what's the difference betw. SRAM & register file 请问register file和ram有啥不同? -
Caller-saved register and Callee-saved register
2019-11-19 14:55:32Caller-saved register(又名易失性寄存器AKA volatile registers, or call-clobbered)用于保存不需要在各个调用之间保留的临时数量。 因此,如果要在过程调用后恢复该值,则调用方有责任将这些寄存器压入堆栈或将... -
STM32 Timer : Auto-reload register register
2015-08-26 23:10:00Auto-reload register (TIMx_ARR) The auto-reload register is preloaded. Writing to or reading from the auto-reload register accesses the preload register. The content of the preload register are ... -
register寄存器变量
2018-03-19 14:05:57对register寄存器变量的总结如下: 1.寄存器变量可以用来优化加速c语言程序 2.声名只需在类型前多加register 即可,eg register int quick; (quick 就是一个整形的寄存器变量) 3.register只是一个建议型关键字... -
register int 的作用
2019-12-01 15:53:32使用register int申请的变量是存储在CPU中央寄存器中的(寄存器是中央处理器内的组成部分。寄存器是有限存贮容量的高速存贮部件),而使用int申请的变量是存储在内存中。 使用register修饰的变量可以提高它的读写... -
RegisterServlet的实现
2019-03-21 12:56:30主要是表单提交的日期是String类型,User需要的类型是Date类型 ConvertUtils.register注册转换器 /** * Servlet implementation class RegisterServlet ...public class RegisterServlet extends HttpServ... -
Unknown custom element did you register the component correctly
2018-10-11 16:41:291、错误描述 vue.esm.js?efeb:591 [Vue warn]: Unknown custom element: &... - did you register the component correctly? For recursive components, make sure to provide the "name" option. f...