作用域和链接属性

简介: 作用域和链接属性

作用域和链接属性

 

作用域

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

 

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

一代码块作用域

一文件作用域

一原型作用域

一函数作用域

 

1)  代码块作用域(block scope

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

 

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

include<stdio.h>

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 <stdio.h>

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)

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

例如:

image.png

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

 

4)  函数作用域(function scope)

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

 

  • 定义和声明

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

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

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

 

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

 

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

 

  • 链接属性

image.png

external(外部的)

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

internal(内部的)

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

none(无)

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

 

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

 

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

 

#include <stdio.h>

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

相关文章
|
12天前
|
存储 缓存 JavaScript
哪些情况适合使用块级作用域,哪些情况适合使用函数作用域?
【10月更文挑战第29天】块级作用域和函数作用域在不同的场景下各有优势,合理地选择和运用这两种作用域可以使JavaScript代码更加清晰、高效和易于维护。在实际开发中,需要根据具体的业务需求、代码结构和编程模式来决定使用哪种作用域,或者在适当的情况下结合使用两者,以达到最佳的编程效果。
|
2月前
|
Java
作用域
作用域
19 2
|
2月前
C 作用域详解
在 C 语言中,作用域决定了变量和函数的可见性和生命周期,包括块作用域、函数作用域、文件作用域和全局作用域。块作用域内的变量仅在块内有效,函数作用域内的变量在整个函数内有效,文件作用域内的全局变量和函数在整个文件内有效,而全局作用域内的变量和函数在整个程序运行期间有效。作用域的优先级遵循局部变量优先的原则,局部变量会遮蔽同名的全局变量。变量的生命周期分为局部变量(函数调用时创建和销毁)、全局变量(程序开始时创建和结束时销毁)以及静态变量(整个程序期间有效)。理解作用域有助于避免命名冲突和错误,提高代码的可读性和可维护性。
|
6月前
|
JavaScript 前端开发 Python
函数与作用域
编程中的函数与作用域概念。函数是可重用的代码块,能提高代码的可读性、可维护性和复用性。基础用法包括定义、调用和返回值。高级用法涉及函数嵌套、匿名函数(lambda函数)和装饰器。装饰器能在不修改原函数代码的情况下添加功能。 作用域决定了变量的可见范围,从内到外是局部、嵌套、全局和内置作用域。闭包是能访问外部函数变量的内部函数,即使外部函数执行完毕,闭包仍能保留其状态。闭包常用于实现特殊功能,如记忆化和延迟执行。 立即执行函数表达式(IIFE)是JavaScript中的模式,用于创建私有作用域和防止变量污染全局。IIFE常用于封装变量、避免命名冲突以及实现模块化和函数作为参数传递。
|
Linux 网络架构
暂时性死区以及函数作用域
暂时性死区以及函数作用域
172 0
|
设计模式 自然语言处理 JavaScript
一篇文章帮你真正理解javascsript作用域闭包
一篇文章帮你真正理解javascsript作用域闭包
85 0
|
自然语言处理 JavaScript 前端开发
作用域是什么
作用域是什么
121 0
|
存储 缓存 JavaScript
深入理解作用域和闭包(下)
深入理解作用域和闭包(下)
深入理解作用域和闭包(下)
|
存储 JavaScript 前端开发
深入理解作用域和闭包(上)
深入理解作用域和闭包(上)
深入理解作用域和闭包(上)
|
自然语言处理 前端开发 JavaScript
作用域闭包
作用域闭包
88 0