作用域+链接属性+存储类型

2024-09-02 17:38

本文主要是介绍作用域+链接属性+存储类型,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.作用域

     当变量在程序的某一部分被声明时,只有在程序的一定区域才能被访问。这个区域由标示符的作用域(scope)决定。换句话说,标示符的作用域,就是该标示符在程序中能被使用的区域。
    编译器可以确认4种不同类型的作用域:文件作用域、函数、代码块、原型作用域。

代码块作用域:(block scope)用{。。。。。}括起来的部分
文件作用域:任何在代码块外部声明的标示符都具有文件作用域。
原型作用域:(prototype scope)只适用于在函数原型中声明的参数名
函数作用域:只适用于语句标签,语句标签用于goto语句。一个函数中的所有语句标签必须唯一

2.链接属性

    各个源文件被编译后,所有的目标文件+从函数库中引用的函数(一般是归档库文件,*.a类型)经过链接器链接,形成一定格式的可执行程序,如elf格式。
    如果相同的标示符出现在几个不同个源文件中,他们是否表示同一个实体。这由标示符的链接属(linkage)决定。标示符的作用域和链接属性相关,作用域是由链接属性决定的,但二者并不相同。
比如,内部属性的静态全局变量,在代码块内有同样名称的标示符,这时静态变量无效,起作用的是代码块内的局部变量。虽然静态全局变量具有内部链接属性,但当名字冲突时,起作用的是局部变量。

链接属性:外部(external),内部(internal),无(none)。
分别说明:
外部属性的标示符在整个程序内,不论出现于哪个文件,不论声明多少次,都指的同一个实体。
内部属性,只在同一个源文件的所有声明中指同一个实体。
无属性,该标示符的多个声明都被当做独立的个体。

这里有两个关键字:extern  和  static,用于在声明中修改标示符的链接属性。
如果某个声明默认情况下具有外部external属性,加上static后,可以将其链接属性变为internal、。
static可以将该标示符的作用域限定为本文件,防止被其他源文件使用。
注:static只对缺省链接属性为external的声明才有改变链接属性的效果。

extern关键字可以声明一个变量,告诉要使用它的文件或函数,这个变量在别的文件内声明,这里只是引用。所以,extern扩大了一个标示符的作用域。

3.存储类型

变量的存储类型(storage class)是指存储变量值的内存类型。变量的存储类型决定了变量何时创建,何时销毁以及它的值保持多久。
有三个地方可以用于存储变量:普通内存,运行时堆栈,硬件寄存器。

变量的存储类型取决与它的声明位置。

(1)在任何代码块之外声明的变量总是存储于静态内存(程序的数据段+bss段BSS(Block Started by Symbol)通常是指用来存放程序中未初始化的全局变量和静态变量的一块内存区域。 注意和数据段的区别,BSS存放的是未初始化的全局变量和静态变量,数据段存放的是初始化后的全局变量和静态变量),而不是堆栈中,这类变量是静态变量(或全局变量)。
静态变量在程序运行之前创建,在程序的整个执行过程中都存在。

(2)在代码块内声明的变量默认是自动变量(automatic),存储于堆栈中,这类变量叫做自动(auto)变量。在程序执行到该代码块时,内部的自动变量才被创建,当程序离开该代码块时,自动变量销毁。

在代码块内部的变量如果给它加上static关键字,可以使其变为静态变量。
注:1.修改变量的存储类型,不等于修改变量的作用域,它仍然只能在该代码块内部按名字访问。
    2.函数的形式参数不能声明为静态,因为函数的参数传递是通过堆栈进行的,用于支持递归。

(3)在变量前加上register关键字,可以告诉编译器该变量应该存储于机器的硬件寄存器,而不是内存。如果有很多register变量,编译器只会选几个实际存储于寄存器。


4.变量的初始化

静态变量总是默认初始化为0,除非显式的赋值。
自动变量没有初始值,或认为它的值是个垃圾,所以在声明一个自动变量时最好在使用前进行赋初值。。

PS:自动变量+非自动变量,非自动变量(静态变量+全局变量)
PS:volatile  易失变量(嵌入式编程经常要用到这个变量)
(1)表示变量是易失的,易变的. (2)强制访存操作,防止编译器去优化,告诉编译器每次必须去内存中取值,而不是从寄存器或者缓存.
 
 
《C和指针(中文版)》上一道题,P49:
假如想着同一个源文件里写两个函数x,y,需要满足以下条件:
名字        类型       存储类型        链接类型       作用域                                  初始值
a              int              static            external          x可以访问,y不能              1
b              char           static            none               x,y都可以访问                     2
c              int              automatic     none              x的局部变量                         3
d              float           static            none              x的局部变量                         4
 
a链接属性external,应该位于所有代码块外面,但由于x可以访问,y不能,所以要出现在y函数后面,x函数前面;
b链接类型为none,则应该位于代码块内,具有代码块作用域。但是由于x,y都能访问到,所以x需要调用y,或反之。。(笔者以为,b的链接类型应该是internal,且位于文件起始处)
c,d明显要处于x的代码块内,且一个为static变量,一个automatic变量。
 
形式如下:
    static int b = 2;void y(){...}int a =1;void x(){int c = 3;static d = 4;....}


zuo

这篇关于作用域+链接属性+存储类型的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1130627

相关文章

异构存储(冷热数据分离)

异构存储主要解决不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。 异构存储Shell操作 (1)查看当前有哪些存储策略可以用 [lytfly@hadoop102 hadoop-3.1.4]$ hdfs storagepolicies -listPolicies (2)为指定路径(数据存储目录)设置指定的存储策略 hdfs storagepolicies -setStoragePo

HDFS—存储优化(纠删码)

纠删码原理 HDFS 默认情况下,一个文件有3个副本,这样提高了数据的可靠性,但也带来了2倍的冗余开销。 Hadoop3.x 引入了纠删码,采用计算的方式,可以节省约50%左右的存储空间。 此种方式节约了空间,但是会增加 cpu 的计算。 纠删码策略是给具体一个路径设置。所有往此路径下存储的文件,都会执行此策略。 默认只开启对 RS-6-3-1024k

安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析: url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理  如下: guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {return} 后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

滚雪球学Java(87):Java事务处理:JDBC的ACID属性与实战技巧!真有两下子!

咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE啦,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~ 🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎大家关注&&收藏!持续更新中,up!up!up!! 环境说明:Windows 10

自定义类型:结构体(续)

目录 一. 结构体的内存对齐 1.1 为什么存在内存对齐? 1.2 修改默认对齐数 二. 结构体传参 三. 结构体实现位段 一. 结构体的内存对齐 在前面的文章里我们已经讲过一部分的内存对齐的知识,并举出了两个例子,我们再举出两个例子继续说明: struct S3{double a;int b;char c;};int mian(){printf("%zd\n",s

【编程底层思考】垃圾收集机制,GC算法,垃圾收集器类型概述

Java的垃圾收集(Garbage Collection,GC)机制是Java语言的一大特色,它负责自动管理内存的回收,释放不再使用的对象所占用的内存。以下是对Java垃圾收集机制的详细介绍: 一、垃圾收集机制概述: 对象存活判断:垃圾收集器定期检查堆内存中的对象,判断哪些对象是“垃圾”,即不再被任何引用链直接或间接引用的对象。内存回收:将判断为垃圾的对象占用的内存进行回收,以便重新使用。

flume系列之:查看flume系统日志、查看统计flume日志类型、查看flume日志

遍历指定目录下多个文件查找指定内容 服务器系统日志会记录flume相关日志 cat /var/log/messages |grep -i oom 查找系统日志中关于flume的指定日志 import osdef search_string_in_files(directory, search_string):count = 0

两个月冲刺软考——访问位与修改位的题型(淘汰哪一页);内聚的类型;关于码制的知识点;地址映射的相关内容

1.访问位与修改位的题型(淘汰哪一页) 访问位:为1时表示在内存期间被访问过,为0时表示未被访问;修改位:为1时表示该页面自从被装入内存后被修改过,为0时表示未修改过。 置换页面时,最先置换访问位和修改位为00的,其次是01(没被访问但被修改过)的,之后是10(被访问了但没被修改过),最后是11。 2.内聚的类型 功能内聚:完成一个单一功能,各个部分协同工作,缺一不可。 顺序内聚:

Mysql BLOB类型介绍

BLOB类型的字段用于存储二进制数据 在MySQL中,BLOB类型,包括:TinyBlob、Blob、MediumBlob、LongBlob,这几个类型之间的唯一区别是在存储的大小不同。 TinyBlob 最大 255 Blob 最大 65K MediumBlob 最大 16M LongBlob 最大 4G