const-static-extern-volatile的释义和用法

博文一 博文二   1、const 这个单词翻译成中文是“常量”的意思。在程序中我们知道“常量”的值是不能变的,固定的。所以const关键字的作用就呼之欲出了: (1) const用来修饰右边的基本变量或指针变量 (2) 被修饰的变量只读,不能被修改 const修饰位置不同,代表什么? 1.const NSString *HSCoder = @"汉斯哈哈哈"; 2.NSString const *HSCoder = @"汉斯哈哈哈"; 3.NSString * const HSCoder = @"汉斯哈哈哈";   1.const NSString *HSCoder = @"汉斯哈哈哈"; "*HSCoder"不能被修改, "HSCoder"能被修改 2.NSString const *HSCoder = @"汉斯哈哈哈"; "*HSCoder"不能被修改, "HSCoder"能被修改 3.NSString * const HSCoder = @"汉斯哈哈哈"; "HSCoder"不能被修改,"*HSCoder"能被修改   注意:1和2其实没什么区别 结论:const右边的总不能被修改   所以一般我们定义一个常量又不想被修改应该这样: NSString * const HSCoder = @"汉斯哈哈哈"; 一般项目中,定义全局常量,会写在独立文件里  const-static-extern-volatile的释义和用法

2.static

论iOS中的全局变量和static全局变量的定义和区别 1.全局变量与全局静态变量的区别:  (a)若程序由一个源文件构成时,全局变量与全局静态变量没有区别。  (b)若程序由多个源文件构成时,全局变量与全局静态变量不同:全局静态变量使得该变量成为定义该变量的源文件所独享,即:全局静态变量对组成该程序的其它源文件是无效的。  (c)具有外部链接的静态;可以在所有源文件里调用;除了本文件,其他文件可以通过extern的方式引用; 2.静态全局变量的作用:  (a)不必担心其它源文件使用相同变量名,彼此相互独立。  (b)在某源文件中定义的静态全局变量不能被其他源文件使用或修改。  (c) 只能在本文件中使用!具有内部链接的静态;不允许在其他文件里调用; 接下来,Xcode创建一个工程,并且创建一个继承于UIView的MyView(为了验证在两个不同的 .m 文件中全局变量和静态全局变量的使用): 1--->两个.m文件中同样的全局变量: #import "MyView.h" //声明一个全局变量 NSInteger CellHeight; @implementation MyView @end ---------- #import "ViewController.h" @interface ViewController () @end //声明同的全局变量 NSInteger CellHeight; @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; //打印变量 NSLog(@"%ld",CellHeight); } @end 好了,我们同时在同一个工程的两个不同 .m 文件中声明了一模一样的全局变量,这样会发生什么情况呢?程序编译报错!!! const-static-extern-volatile的释义和用法

 

 

我的理解是:同一个工程中,两个不同 .m 文件中同样的全局变量不能同时存在,因为这样在编译或运行的时候,编译器分不清是哪个全局变量,所以我们千万不能同时在同一个工程中定义同样的全局变量! 2--->一个.m文件使用另一个.m文件中的全局变量  问题来了,如果我就是想用另一个 .m 文件中的全局变量,那怎么处理呢?很简单,使用关键字 extern 修饰使用的全局变量就好了,也即是在 import “ViewController.h”中: //加上关键字extern,表示这里要使用到MyView中的全局变量  extern NSInteger CellHeight; 打印结果:0。因为当没有初始化的时候系统默认:零。  注:如果在MyView中初始化了数据,比如NSInteger CellHeight = 100;则打印结果就为100,但是在ViewController中就不能再次初始化!!!否则编译报错同上!!! 3 静态全局变量 

const-static-extern-volatile的释义和用法

 

 

显然,依旧报错!这是因为在MyView中是一个静态全局变量,尽管在ViewController使用了关键字extern想使用它,但还是不行的,静态全局变量只能在本文件中使用,不允许其他文件的调用!换句话说我们可以在两个不同的 .m 文件中定义同样的静态全局变量,而互不干涉、互不影响。   3.extern 使用extern可以创建外部文件可以访问的全局变量。这样我们可以让多个类操控同一变量。通过它可以实现全局可变字符串。 在源文件A里定义的变量,在其它源文件里是看不见的(即不能访问)。为了在源文件B里能调用这个函数,应该在B的头部加上一个外部声明:extern 变量;    这样,在源文件B里也可以调用那个变量了。     注意这里的用词区别:在A里是定义,在B里是声明。一个函数只能(也必须)在一个源文件里被定义,但是可以在其它多个源文件里被声明。定义引起存储分配,是真正产生那个实体。而声明并不引起存储分配。打一个粗俗的比方:在源文件B里声明后,好比在B里开了一扇窗,让它可以看到A里的那个变量。

const-static-extern-volatile的释义和用法

 

 

4.volatile 一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。就像大家更熟悉的const一样,volatile是一个类型修饰符。它是被设计用来修饰被不同线程访问和修改的变量。如果不加入volatile,基本上会导致这样的结果:要么无法编写多线程程序,要么编译器失去大量优化的机会。   Volatile变量具有 synchronized 的可见性特性,但是不具备原子特性。这就是说线程能够自动发现 volatile变量的最新值。Volatile变量可用于提供线程安全,但是只能应用于非常有限的一组用例:多个变量之间或者某个变量的当前值与修改后值之间没有约束。因此,单独使用 volatile 还不足以实现计数器、互斥锁或任何具有与多个变量相关的不变式(Invariants)的类(例如 “start <=end”)。   出于简易性或可伸缩性的考虑,您可能倾向于使用 volatile变量而不是锁。当使用 volatile变量而非锁时,某些习惯用法更加易于编码和阅读。此外,volatile变量不会像锁那样造成线程阻塞,因此也很少造成可伸缩性问题。在某些情况下,如果读操作远远大于写操作,volatile变量还可以提供优于锁的性能优势。   代码示例   volatile int i=10; int j = i; ... int k = i;   volatile 告诉编译器i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,因而编译器生成的可执行码会重新从i的地址读取数据放在k中。编译器在产生release版可执行码时会进行编译优化,加volatile关键字的变量有关的运算,将不进行编译优化。而优化做法是,由于编译器发现两次从i读数据的代码之间的代码没有对i进行过操作,它会自动把上次读的数据放在k中。而不是重新从i里面读。这样以来,如果i是一个寄存器变量或者表示一个端口数据就容易出错,所以说volatile可以保证对特殊地址的稳定访问,不会出错。   int square(volatile int *ptr) { return *ptr * *ptr; }   这段代码的目的是用来返指针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; }   下面是volatile变量的几个使用: • 并行设备的硬件寄存器(如:状态寄存器) • 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables) • 多线程应用中被几个任务共享的变量   那么问题来了: 一个参数既可以是const还可以是volatile吗?答案是是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。 一个指针可以是volatile 吗?答案是是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。   在编写多线程程序中使用volatile的关键点: 1.将所有的共享对象声明为volatile; 2.不要将volatile直接作用于基本类型; 3.当定义了共享类的时候,用volatile成员函数来保证线程安全; 在多线程中,我们可以利用锁的机制来保护好资源临界区。在临界区的外面操作共享变量则需要volatile,在临界区的里面则non-volatile了。             31.关键字const有什么含意?修饰类呢?static的作用,用于类呢?还有extern c的作用 答:const 意味着"只读",下面的声明都是什么意思? const int a; int const a; const int*a; int* const a; int const* a const;   前两个的作用是一样,a是一个常整型数。   第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以)。   第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)。   最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。   结论:   关键字const的作用是为给读你代码的人传达非常有用的信息,实际上,声明一个参数为常量是为了告诉了用户这个参数的应用目的。   如果你曾花很多时间清理其它人留下的垃圾,你就会很快学会感谢这点多余的信息。(当然,懂得用const的程序员很少会留下的垃圾让别人来清理的) 通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。简而言之,这样可以减少bug的出现。   1).欲阻止一个变量被改变,可以使用 const 关键字。在定义该 const 变量时,通常需要对它进行初   始化,因为以后就没有机会再去改变它了;   2).对指针来说,可以指定指针本身为 const,也可以指定指针所指的数据为 const,或二者同时指   定为 const;   3).在一个函数声明中,const 可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;   4).对于类的成员函数,若指定其为 const 类型,则表明其是一个常函数,不能修改类的成员变量;   5).对于类的成员函数,有时候必须指定其返回值为 const 类型,以使得其返回值不为“左值”。   73. 关键字volatile有什么含意?并给出三个不同的例子。   答:一个定义为 volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。   下面是volatile变量的几个例子:   并行设备的硬件寄存器(如:状态寄存器)   一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)   多线程应用中被几个任务共享的变量   74. 一个参数既可以是const还可以是volatile吗? 一个指针可以是volatile 吗?解释为什么。   答:1).是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。   2).是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。   75 . static 关键字的作用:   答:   1).函数体内 static 变量的作用范围为该函数体,不同于 auto 变量,该变量的内存只被分配一次,   因此其值在下次调用时仍维持上次的值;   2).在模块内的 static 全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;   3).在模块内的 static 函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明   它的模块内;   4).在类中的 static 成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;   5).在类中的 static 成员函数属于整个类所拥有,这个函数不接收 this 指针,因而只能访问类的static 成员变量。

 

上一篇:python调用c++


下一篇:win32.dll中包含的方法说明(摘抄)