2019-08-07 10:29:29 u013983033 阅读数 266

extern

在一个项目中必须保证函数、变量、枚举等在所有的源文件中保持一致,除非指定定义为局部的。一个全局变量在所有的模块当

中只能被声明一次,否则会出现链接错误。但是可以声明很多次,且声明必须保证类型一致。用 extern 声明时一个变量时,并

不是定义一个变量,也不会为变量分配内存空间。extern 是 c/c++ 语言中表明函数和全局变量作用范围(可见性)的关键字,该

关键字告诉编译器,其声明的函数或变量可以在本模块或者其他模块中使用。通常,在模块的头文件中对本模块提供给其他模块

使用的函数和全局变量以关键字 extern 声明。

例如:如果模块 B 想要引用模块 A 中定义的全局变量和函数时,只包含模块 A 的头文件即可。这样,模块 B 调用模块 A 的函数时,在编译阶段,模块 B 虽然找不到该函数,但是并不会报错,它会在链接阶段中从模块 A 编译生成的目标代码中找到此函数。
与 extern 对应的关键字是 static。被 static 修饰的全局变量或函数,只能在本模块中使用。因此,一个函数或变量只能在本模块中使用时,不能够使用 extern 修饰。

extern "C"

一个 C++ 程序中可能包含其他语言编写的部分代码,同样,C++ 编写的代码片段也可能被用在其他语言编写的代码中。

但是,不同语言编写的代码相互调用是困难的,更何况用同一种语言编写,使用不同编译器进行编译的情况。

因为,不同语言或者同种语言在不同编译器上编译时,在注册变量,传递参数和参数在栈上的布局上可能存在差异。为了使它们

遵守统一规则,可以使用 extern 指定一个编译和链接规约。extern “C” 指令中的 C,表示的是一种编译和链接规约,而不是一种

语言。C 表示符合 C 语言的编译和链接规约的任何语言。还要说明的是,extern “C” 指令指定的编译和链接规约,不会影响语

义,只是改变编译和链接的方式。如果很很多语句要加上 extern "C",可以将它们放到 extern "C" {} 中。

2018-07-04 11:28:21 zhaoqin3669 阅读数 0

最新项目上线,抽空写下博客,记录一些基础知识

1.const和宏 区别

    const:常量

    const:当有字符串常量的时候,苹果推荐我们使用const

    const与宏的区别

    1.编译时刻: 宏:预编译 const:编译时刻

    2.编译检查: 宏:不会检查错误 const:会检查错误

    3.宏的好处:可以定义代码

    4.宏的坏处:编译时间过长,因此常用的字符串通常使用const修饰

    注意:经常使用宏会造成内存不段增加,每次使用宏,都会分配一个内存

   // 全局变量(const)

    NSString *const XMGAccountKey = @"account";

   // #:预编译(宏)

     #define XMGUserDefaults [NSUserDefaults standardUserDefaults]

 2.const 修饰类型

     1.仅仅是用来修饰右边的变量(只能修饰变量:基本变量,指针变量,对象变量)

     2.const修饰的变量,表示只读

     const书写规范:一定要放在变量的左边

3.const使用地方

     // const放*前面约束参数,表示*a只读

    // 只能修改地址a,不能通过a修改访问的内存空间

    - (void)test:(const int * )a{

         // *a = 20;

     }

     // const放*后面约束参数,表示a只读

     // 不能修改a的地址,只能修改a访问的值

     - (void)test1:(int * const)a{  

          int b;  

          // 会报错  

          a = &b;  

          *a = 2;

      }

     - (void)viewDidLoad {  

         [super viewDidLoad];  

         // Do any additional setup after loading the view, typically from a nib.  

         int a = 10;  

         // 需求1:提供一个方法,这个方法的参数是地址,里面只能通过地址读取值,不能通过地址修改值。  

         // 这时候就需要使用const,约束方法的参数只读.  

         [self test:&a];  

         // 需求2:提供一个方法,这个方法的参数是地址,里面不能修改参数的地址。  

         [self test1:&a];

      }

4.static和extern 作用

 static作用:

    1.修饰局部变量

        * 延长这个局部变量的生命周期,只要程序运行,局部变量就会一直存在

        * 局部变量只会分配一次内存,为什么?用static修饰的代码,只会在程序一启动就会执行,以后就不会在执行

 

    2.修饰全局变量

        * 只会修改全局变量的作用域,表示只能是当前文件内使用

 

    extern作用:

    1.声明一个变量,不能定义变量

 

    注意:extern修饰的变量不能初始化

 

    使用场景,一般用于声明全局变量


   extern工作原理:

           先在当前文件查找有没有全局变量,没有找到,才会去其他文件查找。


    // 全局变量:只有一份内存,所有文件共享,与extern联合使用。

int a = 20;

// static修饰全局变量

static int age = 20;

- (void)test{  

// static修饰局部变量  

static int age = 0; age++;  

NSLog(@"%d",age);

}


- (void)viewDidLoad {  

[super viewDidLoad];  

// Do any additional setup after loading the view, typically from a nib.  

[self test];  

[self test];  

extern int age;  

NSLog(@"%d",age);

}


  
2016-02-01 13:41:34 victor_barnett 阅读数 2688
<span style="font-size:18px;">#ifdef __cplusplus
#define UIKIT_EXTERN		extern "C" __attribute__((visibility ("default")))
#else
#define UIKIT_EXTERN	        extern __attribute__((visibility ("default")))
#endif

#define UIKIT_STATIC_INLINE	static inline</span>

其中__cplusplus 是cpp中的自定义宏,那么定义了这个宏的话表示这是一段cpp的代码,也就是说,上面的代码的含义是:如果这是一段cpp的代码,那么加入extern"C"和其中的代码。


extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。


extern "C"呢?C++之父在设计C++之时,考虑到当时已经存在了大量的C代码,为了支持原来的C代码和已经写好C库,需要在C++中尽可能的支持C,而 extern "C"就是其中的一个策略。


__attribute__是GNU C的一种机制,用法为_attribute__ ((attribute-list))。当项目需要作为一个库被外包引用的时候通常在编译时可以用参数-fvisibility指定所有符号的可见性。在编译命令中加入 -fvisibility=hidden参数,会将所有默认的public的属性变为hidden。此时,如果对函数设置__attribute__((visibility ("default")))参数,使特定的函数仍然按默认的public属性处理,则-fvisibility=hidden参数不会对该函数起作用。所以,设置了-fvisibility=hidden参数之后,只有设置了__attribute__((visibility ("default")))的函数才是对外可见的。


总结:如果需要让类或方法可以让库外被引用,就需要使用以上代码确保代码的可见性。



2016-02-19 12:10:35 weo555 阅读数 4164

之前,在在objc项目中使用常量中,使用c的预处理#define来设置常量。比如,可以做个头文件,然后在需要的类文件中import,使用常量。

但这不是最佳实践。这样做可能是最好的方式,首先在比如叫Constants.h的头文件中:

#import

extern NSString * const kInitURL;

@interface Constants : NSObject {

}

@end

这里使用到extern c关键字,表示这个变量已经声明,只是引用。const关键字表示变量是常量,不可修改。

在objc的约定里,常量也是大小写混排的驼峰命名规则,首字母小写,另外,第一个字母是k。

然后,在Constants.m文件中:

#import "Constants.h"

NSString * const kInitURL = @"http://marshal.easymorse.com";

@implementation Constants

@end

 

在这里给常量kInitURL赋值。

如何使用常量?只需在所需的m文件引入Constants头文件,下面是使用示例:

#import "BasicDemosViewController.h" 
#import "Constants.h"

@implementation BasicDemosViewController

// Implement loadView to create a view hierarchy programmatically, without using a nib. 
- (void)loadView { 
    NSLog(@"load view: %@",kInitURL); 
}

使用这种方式,比通过宏预定义的优点是,可以对常量进行指针比较操作,这是#define做不到的。即:

[myURL isEqualToString:kInitURL];



转自:http://blog.sina.com.cn/s/blog_a843a8850101jr7d.html




2014-07-23 14:04:03 qq342261733 阅读数 0

使用extern关键字法:

        1 、新建Constants.h文件(文件名根据需要自己取),用于存放全局变量;

        2、 在Constants.h中写入你需要的全局变量名,但是在定义时不能对其进行初始化,否则就出错例如:

                  NSString *url;//指针类型
                 int count;//非指针类型

        3  、在需要用到全局变量的文件中引入此文件:

                   #import "Constants.h"  

        4、给全局变量初始化或者赋值:

  1.  extern NSString *url;     
  2.   
  3. url = [[NSString alloc] initWithFormat:@"http://www.hbcfg.net"];//指针类型;需要alloc   
  4.   
  5. extern int count;   
  6.   
  7. count = 0;//非指针类型  

       在使用全局变量的时候就和使用普通变量一样使用了。

当然还有其他的方法:可以在AppDelegate中声明并初始化全局变量,使用单例访问全局变量等

iOS之extern关键字

阅读数 1338