作用域和链接属性|学习笔记

简介: 当变量被定义在程序的不同位置时,它的作用范围是不一样的,这个作用范围就是我们所说的作用域。

开发者学堂课程【你的第一门 C 语言课作用域和链接属性】学习笔记,与课程紧密联系,让用户快速学习知识

课程地址:https://developer.aliyun.com/learning/course/444/detail/5480


作用域和链接属性


作用域

当变量被定义在程序的不同位置时,它的作用范围是不一样的,这作用范围就是我们所说的作用域。

C 语言编译器可以确认4种不同类型的作用域:

一代码块作用域

一文件作用域

一原型作用域

一函数作用域

1) 代码块作用域(block scope)

在代码块中定义的变量,具有代码块作用域。作用范围是从变量定义的位置开始,到标志该代码块结束的右大括号)处。

尽管函数的形式参数不在大括号内定义,但其同样具有代码块作用域,隶属于包含函数体的代码块。

include

int main(void)

{

int i = 100; //i1

{

int i = 110;//li

{

int i = 120;//i3

printf ( "i = %d\n", i);

}

//i =110

{

printf ( "i=%d\n", i);

int i = 130;

printf ( "i=%d\n", i);

}

printf ("i=%d \n", i);

}

printf("i= %d\n", i);

return 0;

}

2) 文件作用域(file scope)

任何在代码块之外声明的标识符都具有文件作用域,作用范围是从它们的声明位置开始,到文件的结尾处都是可以访问的。

另外,函数名也具有文件作用域,因为函数名本身也是在代码块之外。

#include

void func(void);

int main(void)

{

extern int count;

func();

count++;

printf( "In main, count = %d \n", count);

return 0;

}

int count;

void func(void)

{

count++;

printf( "In func, count = %d \n", count);

}

3) 原型作用域(prototype scope)

原型作用域只适用于那些在函数原型中声明的参数名。

例如:

图片95.png

函数在声明的时候可以不写参数的名字(但参数类型是必须要写上的),其实函数原型的参数名还可以随便写一个名字,不必与形式参数相匹配(当然,这样做没有任何意义!)。

4) 函数作用域(function scope)

函数作用域只适用于 goto 语句的标签,作用将 goto 语句的标签暖制在同一个函数内部,以及防止出现重名标签。

  • 定义和声明

当一个变量被定义的时候,编译器为变量申请内存空间并填充一些值。

当一个变量被声明的时候,编译器就知道该变量被定义在其他地方。

声明是通知编译器该变量名及相关的类型已存在,不需要再为此申请内存空间。

局部变量既是定义又是声明。

定义只能来一次,否则就叫做重复定义某个同名变量;而声明可以有很多次。

  • 链接属性

图片96.png

external(外部的)

一多个文件中声明的同名标识符表示同一个实体

internal(内部的)

一单个文件中声明的同名标识符表示同一个实体

none(无)

一声明的同名标识符被当作独立不同的实体

只有具备文件作用域的标识符才能拥有 externa l或 internal 的链接属性,其他作用域的标识符都是 none 属性。

默认情况下,具备文件作用域的标识符拥有 external 属性。也就是说该标识符允许跨文件访问。对于 external 属性的标识符,无论在不同文件中声明多少次,表示的都是同一个实体。

#include

void a(void) ;

void b(void);

void c(void);

int count;

int main(void)

{

a();

b();

c();

b();

printf("小郭今天一共被抱了%d次\n", count);

return 0;

}

  • 全局变量

extern int count;

void b (void)

{

count++;

}

使用 static 关键字可以使得原先拥有 external 属性的标识符变为 internal 属性。

这里有两点需要注意:

使用 static 关键字修改链接属性,只对具有文件

作用域的标识符生效(对于拥有其他作用域的标识符是另一种功能)

一链接属性只能修改一次,也就是说一旦将标识符的链接属性变为 internal,就无法变回 external 了

相关文章
|
23天前
|
自然语言处理 JavaScript 前端开发
词法作用域和静态作用域有什么区别
【10月更文挑战第12天】词法作用域和静态作用域有什么区别
|
2月前
|
Java
作用域
作用域
18 2
|
2月前
C 作用域详解
在 C 语言中,作用域决定了变量和函数的可见性和生命周期,包括块作用域、函数作用域、文件作用域和全局作用域。块作用域内的变量仅在块内有效,函数作用域内的变量在整个函数内有效,文件作用域内的全局变量和函数在整个文件内有效,而全局作用域内的变量和函数在整个程序运行期间有效。作用域的优先级遵循局部变量优先的原则,局部变量会遮蔽同名的全局变量。变量的生命周期分为局部变量(函数调用时创建和销毁)、全局变量(程序开始时创建和结束时销毁)以及静态变量(整个程序期间有效)。理解作用域有助于避免命名冲突和错误,提高代码的可读性和可维护性。
|
6月前
|
JavaScript 前端开发 Python
函数与作用域
编程中的函数与作用域概念。函数是可重用的代码块,能提高代码的可读性、可维护性和复用性。基础用法包括定义、调用和返回值。高级用法涉及函数嵌套、匿名函数(lambda函数)和装饰器。装饰器能在不修改原函数代码的情况下添加功能。 作用域决定了变量的可见范围,从内到外是局部、嵌套、全局和内置作用域。闭包是能访问外部函数变量的内部函数,即使外部函数执行完毕,闭包仍能保留其状态。闭包常用于实现特殊功能,如记忆化和延迟执行。 立即执行函数表达式(IIFE)是JavaScript中的模式,用于创建私有作用域和防止变量污染全局。IIFE常用于封装变量、避免命名冲突以及实现模块化和函数作为参数传递。
|
设计模式 自然语言处理 JavaScript
一篇文章帮你真正理解javascsript作用域闭包
一篇文章帮你真正理解javascsript作用域闭包
85 0
|
存储 缓存 JavaScript
深入理解作用域和闭包(下)
深入理解作用域和闭包(下)
深入理解作用域和闭包(下)
|
存储 JavaScript 前端开发
深入理解作用域和闭包(上)
深入理解作用域和闭包(上)
深入理解作用域和闭包(上)
|
自然语言处理 JavaScript 前端开发
作用域是什么
作用域是什么
121 0
|
自然语言处理 前端开发 JavaScript
作用域闭包
作用域闭包
86 0
|
PHP 开发者
超全局作用域|学习笔记
快速学习超全局作用域
超全局作用域|学习笔记