C语言中static和extern

static关键字与extern关键字

C中的关键字extern是用来做变量声明的, 声明extern关键字的全局变量和全局函数可以使得它们的作用域得到扩展, 全局变量和全局函数默认是extern所以声明时我们一般不写 

C中的关键字static主要用于修饰普通变量和函数(C++中则主要修饰类的成员变量和函数)
不管在C还是C++中static静态变量都存储在静态区(全局区)


extern关键字

一. extern修饰全局变量(大多数时候被省略的关键字)

  • extern在一个文件内扩展全局变量的作用域(这种情况要发挥其作用的话不能被省略)

在C中, 如果全局变量不在文件开头定义, 其有效作用范围(作用域)只限于全局变量定义处到文件结束, 在定义处之前不能使用该变量 ,如需在定义处之前想用该全局变量的话, 需要在用之前用extern对该变量进行外部变量声明, 表示将此变量的作用域扩展到此位置, 这样就合法了

来看代码
main.c

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int Max();
int main() {
	printf("请输入a和b的值\n");
	scanf("%d %d", &a, &b);
	printf("最大值为:%d\n", Max());
	system("pause");
	return 0;
}
int a, b;
int Max() {
	return a > b ? a : b;
}

 我们看到, 编译未通过

我们加上extern之后再看

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int Max();
int main() {
	printf("请输入a和b的值\n");
	extern a, b;
	scanf("%d %d", &a, &b);
	printf("最大值为:%d\n", Max());
	system("pause");
	return 0;
}
int a, b;
int Max() {
	return a > b ? a : b;
}


这就可以了

  • 将全局变量的作用域扩展到其他文件(可以省略, 一般不写)

一个C程序可以由一个或多个源文件组成, 如果由多个组成, 那么在想在一个文件用另一个文件中定义的全局变量怎么办呢?
如果在两个文件中都定义名字相同的变量, 会在连接时出现重复定义的错误, 正确的做法是, 在任意一个文件中在全局变量前加上extern修饰, 这样实际只定义了一个全局变量, 只是将其作用域扩展到了其他文件

来看代码:

int b = 2;//全局成员默认是extern,所以可以省略
extern int c = 3;

main.c

#include<stdio.h>
#include<stdlib.h>
extern b;//
int c;
int main() {
	printf("b= %d\n", b);
	printf("c= %d\n", c);
	system("pause");
	return 0;
}

将test.c和main.c放在同一个工程下 . 

二. extern修饰函数(可以省略,一般不写)

在声明函数时, 在函数最左端加关键字extern, 此函数就成为了外部函数, 可供其他文件调用
(与之对应的是内部函数, 用staic修饰, 文章下面再来看)

来看看具体怎么用, 看代码 :
test1.c

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
void input_a(int* pa) {
	printf("请输入a的值\n");
	scanf("%d", pa);
}

test2.c

#include<stdio.h>
extern void output_a(const int* pa) {
	printf("a=%d\n", *pa);
}

main.c

#include<stdio.h>
#include<stdlib.h>
int main() {
	int a;
	int* pa = &a;
	extern void input_a(int* pa);
	void output_a(int* pa);
	input_a(pa);
	output_a(pa);
	system("pause");
	return 0;
}



static关键字

一 .static修饰变量

注意: 在用static声明变量时, 只能在声明变量的基础上加static修饰, 而不能单独使用, 例如 下面用法不对
int a;
static a;
在C中和static类似不能这样用的关键字还有auto ,register

  • 修饰全局变量, 将全局变量的作用域限制在本文件

static修饰全局变量改变的是全局变量的作用域, 使全局变量只能在本文件中使用,

来看下面代码
test.c

static int a = 1;

main.c

#include<stdio.h>
#include<stdlib.h>
extern a;
int main() {
	printf("a= %d\n", a);
	system("pause");
	return 0;
}

运行结果出错, 可以看到static确实把a的作用域限定到了test.c中

  • 修饰局部变量, 改变局部变量的生命周期(将局部变量存储在静态区)

static修饰局部变量, 会将局部变量存储在静态区(全局区)(普通局部变量存储在栈区), 改变局部变量的生命周期, 使其伴随整个程序, 程序运行结束时才会被释放

注意 : 虽然static修饰的局部变量改变了生命周期, 使其伴随整个程序, 程序结束前为其分配的空间一直都在, 但作用域并未改变

来看代码

#include<stdio.h>
#include<stdlib.h>
void test() {
	static int m = 1;
	printf("m = %d\n", m);
	++m;
}
int main() {
	test();
	test();
	test();
	system("pause");
	return 0;
}


二. static修饰函数

在声明函数时在其最左边加static修饰, 这个函数就成了内部函数, 内部函数又称为静态函数, 会使函数作用域只限定于本文件., 这样在不同文件中就算有相同名字的函数也不会相互干扰

通常一个大的程序往往由多人分工来编写不同的文件模块, 在不同人编写代码时,很可能会出现相同名字的函数, 此时, 在自己写的函数前加static修饰, 就不会出现函数重名的问题了, 这就保证了程序的可靠性.

来看例子
 

static void test(int *pa) {
	*pa++;
}
#include<stdio.h>
#include<stdlib.h>
void test(int *pa);
int main() {
	int a = 0;
	int* pa = &a;
	test(pa);
	printf("a= %d\n", a);
	system("pause");
	return 0;
}

我们看到, 在mian.c中确实访问不到test.c中的static函数了

在IT领域,尤其是地理信息系统(GIS)中,坐标转换是一项关键技术。本文将深入探讨百度坐标系、火星坐标系和WGS84坐标系之间的相互转换,并介绍如何使用相关工具进行批量转换。 首先,我们需要了解这三种坐标系的基本概念。WGS84坐标系,即“World Geodetic System 1984”,是一种全球通用的地球坐标系统,广泛应用于GPS定位和地图服务。它以地球椭球模型为基础,以地球质心为原点,是国际航空和航海的主要参考坐标系。百度坐标系(BD-09)是百度地图使用的坐标系。为了保护隐私和安全,百度对WGS84坐标进行了偏移处理,导致其与WGS84坐标存在差异。火星坐标系(GCJ-02)是中国国家测绘局采用的坐标系,同样对WGS84坐标进行了加密处理,以防止未经授权的精确位置获取。 坐标转换的目的是确保不同坐标系下的地理位置数据能够准确对应。在GIS应用中,通常通过特定的算法实现转换,如双线性内插法或四参数转换法。一些“坐标转换小工具”可以批量转换百度坐标、火星坐标与WGS84坐标。这些工具可能包含样本文件(如org_xy_格式参考.csv),用于提供原始坐标数据,其中包含需要转换的经纬度信息。此外,工具通常会附带使用指南(如重要说明用前必读.txt和readme.txt),说明输入数据格式、转换步骤及可能的精度问题等。x86和x64目录则可能包含适用于32位和64位操作系统的软件或库文件。 在使用这些工具时,用户需要注意以下几点:确保输入的坐标数据准确无误,包括经纬度顺序和浮点数精度;按照工具要求正确组织数据,遵循读写规则;注意转换精度,不同的转换方法可能会产生微小误差;在批量转换时,检查每个坐标是否成功转换,避免个别错误数据影响整体结果。 坐标转换是GIS领域的基础操作,对于地图服务、导航系统和地理数据分析等至关重要。理解不同坐标系的特点和转换方法,有助于我们更好地处
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值