IOS:static和extern的使用

先上代码:

static int var1 = 10;
void staticTest(void);
void countMethod(void);

int main() {
    @autoreleasepool {
        staticTest();
    }
}

void staticTest(void) {
    countMethod();
    countMethod();
    
    extern int var1;
    printf("%d\n",var1);
    printf("%p\n",&var1);
}

void countMethod(void) {
    static int var1 = 0;
    var1++;
    printf("%d\n",var1);
    printf("%p\n",&var1);
}

输出结果:

1
0x102dce3c0
2
0x102dce3c0
10
0x102dce190

一、extern的作用

extern:引入全局变量,本文件中没有就从整个项目中引入,如果整个程序中都不存在,编译阶段将会报错。
重点:引入的是全局变量,而不是全局区的变量。全局区包括全局变量和静态变量。
例子:
代码中注释掉本段:

//static int var1 = 10;

运行以上代码将会报错:


extern

原因:
extern引入的是全局变量,而不是全局区的局部静态变量。

二、static修饰局部变量

static修饰局部变量的几个功能:
1.改变局部变量的生命周期,将局部变量从栈中存储到全局区,生命周期从函数/代码块执行完成后销毁延长到了:程序的开始到结束;
2.不改变局部变量的作用域;
3.不改变数据类型,原来用var修饰,那么值仍然可以改变,原来用const修饰,那么值依然不可改变;

例子:
运行以上代码,前两次打印:

1
0x102dce3c0
2
0x102dce3c0

原因:
var1没有被销毁,存在整个程序的生命周期中。

三、static修饰全局变量

static修饰全局变量的几个功能:
1.不改变声明周期,全局变量的生命周期仍然是整个程序开始到结束;
2.改变了全局变量的作用域,由项目中任意文件都可以使用缩减成了只有在本文件中可以使用;
例子:
运行以上代码,最后一次打印:

10
0x102dce190

原因:
1.证明了两个var1虽然都是存储在全局区,但是却不是同一块内存,也就是说不是同一个变量;
2.extern引入的是全局变量,所以最后会打印10;

注意:static 和全局变量初始化时需要一个确定的值,如果不能,那就赋值为空,如下图,指针的地址需要在运行时才能确定,所以报错:


static初始化

正确做法:


static初始化

四、static修饰方法

被 static 修饰的方法称为静态方法,静态方法有几个特点:

  1. 只在该文件内部可见,无法被 extern;
  2. 存储在 Data 区?

优点

  1. 工程中避免了因函数重名导致的编译错误;
  2. 静态函数会被自动分配在一个一直使用的存储区,直到退出应用程序实例,避免了调用函数时压栈出栈,速度快很多;

关于优点二有待验证。函数不都是存储在 text 段的吗?研究 mahc-o 文件时注意验证下;

示例:
Test.c 中:

static void staticFunc(int a) {
    printf("%d\n",a);
}

main 中:

extern void staticFunc(int);

int main(int argc, const char * argv[]) {
    staticFunc(10);
    return 0;
}

编译直接报错:


Undefined symbol

你可能感兴趣的:(IOS:static和extern的使用)