C语言存储类型 auto,register,static,extern

news2024/12/22 22:28:53

目录

1. auto 存储类型

1.1 自动变量特性

1.2 举例

2. register 存储类型

2.1 寄存器变量特性

2.2 举例

 3. extern 存储类型

3.1 extern 存储类型特性

3.2 举例

3.2.1 extern全局变量

​编辑

3.2.2 extern函数

4. static 存储类型

4.1 static 存储类型特性

4.2 举例

4.2.1 静态局部变量

4.2.2 静态全局变量

4.2.3 静态函数


C语言存储类型关键字(storage-class specifier)有:

  • auto
  • register
  • static
  • extern

这些说明符放置在它们所修饰的类型之前。

1. auto 存储类型

        默认情况下,不加任何存储类型说明符修饰的所有在函数块内定义的变量或函数形参都是自动变量,但由 malloc,calloc 函数在堆中申请的内存除外,自动变量具有块作用域,生存期在定义它的块内。

1.1 自动变量特性

  • 所有自动变量在函数被调用时在栈中创建,并在函数返回时销毁。
  • 未初始化的自动变量存储的是一个垃圾值,除非显式初始化了它
  • 函数形参默认也是自动变量,程序会在调用该函数前在栈中创建形参,并在函数返回时销毁
  • 不能在所有函数外加 auto 关键字声明全局自动变量,编译器会报全局范围的声明不能用 auto 存储类型

1.2 举例

(1)试图在所有函数外加 auto 关键字声明全局自动变量,这时编译器报错

(2)函数形参加 auto 显式声明 和 函数体内加 auto 显式声明自动变量

#include <stdio.h>

int my_add(auto int a, int b) {
	return a + b;
}

int main() {
	int m = 1;
	printf("m = %d\n", m);
	for (auto int i = 1; i < 2; i++)
		printf("i = %d\n", i);

	printf("sum = %d\n", my_add(1, 2));

	return 0;
}
  • main 函数体内,m 是自动变量,具有块作用域,生存期在整个main函数体内
  • main 函数体内,i 是自动变量,具有块作用域,生存期在定义它的for循环体内
  • my_add 函数的形参 a 和形参 b 也是自动变量,具有函数作用域,生存期在 my_add 整个函数体内

注意:

        auto 关键字在 C++ 中的用法完全不同,为了更好的兼容C++程序,不建议在声明变量时用 auto 关键字声明。

2. register 存储类型

        所有在函数块内定义的在数据类型前用 register 修饰的变量或由 register 修饰的函数形参都是寄存器变量。

2.1 寄存器变量特性

  • 用 register 关键词修饰的变量,只是一个建议,具体会不会接受编译器的这个建议,需要看硬件是否支持
  • 寄存器变量在寄存器中,不在内存中,所以不能用 & 取地址,即使这个变量最终不一定在寄存器上
  • 寄存器变量的访问速度比普通变量快,只用于需要快速访问的变量,比如计数器,而且变量占用的最大字节数不能超过寄存器的最大字节数。

2.2 举例

#include <stdio.h>

int my_add(register int a, int b) {		// 寄存器形参 a
	return a + b;
}

int main() {
	register int sum = 0;	// 寄存器变量 sum
	sum = my_add(1, 2);

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

	return 0;
}

 3. extern 存储类型

3.1 extern 存储类型特性

        extern 关键字用于声明该全局变量或函数在其他文件中有定义,extern 修饰符通常用于当有两个或多个文件共享相同的全局变量或函数的时候。

3.2 举例

3.2.1 extern全局变量

global.c

const int SIZE = 1000;

main.c

#include <stdio.h>

extern const int SIZE;

int main() {
	printf("SIZE= %d\n", SIZE);

	return 0;
}
3.2.2 extern函数

global.c

int my_add(int a, int b) {
    return a+b;
}

main.c

#include <stdio.h>

extern int my_add(int a, int b);

int main() {
	printf("sum = %d\n", my_add(1, 2));

	return 0;
}

4. static 存储类型

4.1 static 存储类型特性

  • 用 static 声明的局部变量,改变了这个局部变量的生存期为静态生存期,即整个程序运行期间都存在。不改变局部变量的作用域。
  • 用 static 关键字修饰的全局变量,改变了这个全局变量的作用域为文件作用域,即限制该全局变量只在定义它的源文件可见。不改变全局变量的生存期
  • 用 static 声明的函数,改变了这个函数的作用域为文件作用域,即限制该函数只在定义它的源文件可见。
类型作用域生存期
static 局部变量局部作用域整个程序运行期间都存在
static 全局变量文件作用域整个程序运行期间都存在
static 函数文件作用域整个程序运行期间都存在

 注意:

        变量的作用域和变量的生存期是两个不同的概率,不能搞混了。

  • 变量的作用域是描述程序可以访问变量的区域,比如块作用域,函数作用域,文件作用域,全局作用域。
  • 变量的生存期是描述变量在程序运行期间的生存期,比如函数形参在调用函数前在栈中创建,函数返回时销毁;局部变量在函数调用时在栈中创建,函数返回时销毁;用 malloc或calloc 在变量在堆创建,不用的时候需要程序员用 free 销毁;全局变量在静态存储区,程序在启动的时候进行创建并初始化,在整个程序运行期间都存在。
  • 用 static 关键字修饰的局部变量,改变了这个局部变量的生存期为静态生存期,即整个程序运行期间都存在。
  • 用 static 关键字修饰的全局变量,改变了这个全局变量的作用域为文件作用域,即限制该全局变量只在定义它的源文件可见。

4.2 举例

4.2.1 静态局部变量
#include <stdio.h>

typedef enum {
	ADD,
	SUB,
	GET
}ENUM_TYEP;

int counter(ENUM_TYEP t, int n) {
	static int c = 0;	// 静态局部变量,存储在静态区,,生存期在程序运行期间都有存在,具有局部作用域。
	if (t == ADD)
		c += n;
	else if (t == SUB)
		c -= n;

	return c;
}

int main() {
	printf("counter = %d\n", counter(GET, 0));    // counter = 0
	printf("counter = %d\n", counter(ADD, 10));   // counter = 10
	printf("counter = %d\n", counter(SUB, 1));    // counter = 9

	return 0;
}

静态局部变量,存储在静态区,,生存期在程序运行期间都有存在,具有局部作用域。

4.2.2 静态全局变量

global.c

static const int SIZE = 1000;

main.c

#include <stdio.h>

extern const int SIZE;

int main() {
    printf("SIZE = %d\n", SIZE);

    return 0;
}

        在该程序中,global.c 源文件中的 static 全局常量 SIZE 具有文件作用域,只在定义它的源文件中可见,在 main.c 源文件不可见,所以编译报错。

4.2.3 静态函数

global.c

// 静态函数,只在定义它的源文件中可见
static int my_add(int a, int b) {
    return a+b;
}

main.c

#include <stdio.h>

extern int my_add(int a, int b);

int main() {
	printf("sum = %d\n", my_add(1, 2));

	return 0;
}

        

        在该程序中,global.c 源文件中的static函数具有文件作用域,只在定义它的源文件中可见,在 main.c 源文件不可见,所以编译报错。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2130958.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

克雷格·费德里吉谈Apple Intelligence保密技术背后的挑战

苹果必须实现克雷格-费德里吉所说的突破&#xff0c;这样 Apple Intelligence公司才能在云中使用大型语言模型&#xff0c;同时还能保护用户隐私&#xff0c;苹果是这样做的。在"It’s Glowtime"活动中&#xff0c;苹果公司谈到了私有云计算作为保护用户隐私的方式。…

Java发邮件:如何配置SMTP服务器实现发信?

Java发邮件功能实现的教程&#xff1f;Java发邮件的方式有哪些&#xff1f; 无论是用于用户注册确认、密码重置&#xff0c;还是系统通知&#xff0c;Java发邮件都是不可或缺的一部分。AokSend将详细介绍如何配置SMTP服务器&#xff0c;以便在Java发邮件时能够顺利发送邮件。 …

【Kubernetes】linux centos安装部署Kubernetes集群

【Kubernetes】centos安装Kubernetes集群 1、环境准备 系统centos7 配置yum源参考文章 Centos系统换yum源 步骤1-3是所有主机都要配置&#xff0c;主机名和hosts配置完后可以使用工具命令同步 1.1 主机 一主二从 主机名ipk8smaster192.168.59.148k8snode1192.168.59.149…

App结合3D形象的技术实现选择

在为App添加3D人物交互效果时&#xff0c;可以采用多种技术&#xff0c;具体选择取决于你的目标平台&#xff08;iOS、Android、跨平台&#xff09;以及项目的复杂性和需求。 以下是几种常用技术及其特点&#xff1a; 游戏引擎技术 游戏引擎提供了强大的3D图形渲染和交互功能&…

05 输出三角形面积和周长

题目&#xff1a; 代码&#xff1a; #include<iostream> using namespace std;#include<stdio.h> #include<stdlib.h>#include<math.h>int main() {int a,b,c;cin>>a>>b>>c;if(ab>c&&ac>b&&bc>a){;}else{…

打包yolov8目标检测模型为exe的教程(pyinstaller 打包pyQt5 界面为exe)

要将YOLOv8模型的应用程序打包成EXE可执行文件&#xff0c;您可以遵循以下步骤&#xff0c;这里使用的是PyInstaller作为打包工具。请注意&#xff0c;这个过程可能会因为您的环境和依赖关系的不同而有所变化。以下是一个基本的指南&#xff1a; 步骤 1: 安装必要的库 确保您…

RabbitMQ 07 另两种集群方式 warren(主备模式),shovel(远程模式)

01.之前的集群有一个缺点&#xff0c;就是故障恢复的时候&#xff0c;停留在队列中的消息怎么办&#xff1f; 02.镜像集群模式&#xff0c;同步所有消息&#xff0c;当当前主节点不可用的时候&#xff0c;可以选举一个从节点来作为主节点。这样可以避免因为主节点不可用的情况…

JVM面试真题总结(八)

文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ G1收集器如何划分堆内存? G1收集器将整个堆划分成约 2048 个大小…

查看TCP/UDP网络连接通信情况

绪论​ “宿命论是那些缺乏意志力的弱者的借口。 ——罗曼&#xff0e;罗兰” 话不多说安全带系好&#xff0c;发车啦&#xff08;建议电脑观看&#xff09;。 主要使用&#xff1a; nestat -nltp n 拒绝显示别名&#xff0c;能显示数字的全部转化成数字l 仅列出有在 Listen (…

开放式蓝牙耳机推荐性价比高的有哪些?权威推荐全网热销前五名

​到了2024年&#xff0c;开放式耳机无疑成为了耳机市场的宠儿。它们的优势在于&#xff0c;不仅佩戴舒适&#xff0c;还能在保护听力的同时&#xff0c;让你保持对周围环境的警觉&#xff0c;这对于爱好户外探险的朋友来说&#xff0c;无疑是一个巨大的安全加分项。作为一名资…

无人机PX4飞控ROS应用层开发:MAVROS 功能包介绍与飞控消息汇总(一)

概述 这个软件包提供了针对各种自动驾驶仪(如PX4,Ardupilot)使用 MAVLink 通信协议的通信驱动程序。 此外&#xff0c;它还提供了用于地面控制站&#xff08;例如 QGroundControl&#xff09;的 UDP MAVLink 桥接功能。 通常与PX4的offboard模式联合使用 Offboard控制背后的想…

代码随想录训练营 Day59打卡 图论part09 Bellman_ford算法

代码随想录训练营 Day59打卡 图论part09 Bellman_ford 算法 例题&#xff1a;卡码94. 城市间货物运输 I 题目描述 某国为促进城市间经济交流&#xff0c;决定对货物运输提供补贴。共有 n 个编号为 1 到 n 的城市&#xff0c;通过道路网络连接&#xff0c;网络中的道路仅允许从…

FP7195:大功率钓鱼灯应用方案,覆盖低压大功率40W,60W,80W的应用市场

前言; 目前夜钓正在逐渐变得时尚起来&#xff0c;随着夜钓群体的年轻化&#xff0c;人们对于夜钓灯的审美要求也越来越高。夜钓灯作为夜间钓鱼的重点装备&#xff0c;不仅仅需要高质量的光源照亮水面浮漂&#xff0c;同时还需要融合一些其他功能&#xff0c;尽可能让夜钓者轻装…

深入理解CASAtomic原子操作类详解

1.CAS介绍 什么是 CAS CAS&#xff08;Compare And Swap&#xff0c;比较与交换&#xff09;&#xff0c;是非阻塞同步的实现原理&#xff0c;它是CPU硬件层面的一种指令&#xff0c;从CPU层面能保证"比较与交换"两个操作的原子性。CAS指令操作包括三个参数&#x…

【LLM text2sql】浅看大模型用于text2sql的综述

前言 之前笔者分享了text2sql & LLM & KG的有机结合实现KBQA的问答&#xff0c; 《【LLM & RAG & text2sql】大模型在知识图谱问答上的核心算法详细思路及实践》、 《【开源分享】KBQA核心技术及结合大模型SPARQL查询生成问答实践》。 我们再来看看大模型在te…

智慧农业——InsectMamba利用状态空间模型对害虫进行分类

介绍 论文地址&#xff1a;https://arxiv.org/abs/2404.03611 害虫分类是农业中的一个重要问题。准确识别有害害虫可减少对作物的损害&#xff0c;确保粮食安全和环境的可持续发展。然而&#xff0c;害虫及其自然环境的高度拟态性和物种多样性使得视觉特征的提取极具挑战性。…

桌面应用框架:tauri是后起之秀,赶上electron路还很长。

一、tauri介绍 Tauri 是一个开源的工具和框架&#xff0c;用于构建现代化的跨平台桌面应用程序。它允许开发者使用 Web 技术&#xff08;如 HTML、CSS 和 JavaScript&#xff09;来构建桌面应用&#xff0c;并将其打包为原生应用程序&#xff0c;以在不同的操作系统上运行。Ta…

深度剖析iOS渲染

iOS App 图形图像渲染的基本流程&#xff1a; 1.CPU&#xff1a;完成对象的创建和销毁、对象属性的调整、布局计算、文本的计算和排版、图片的格式转换和解码、图像的绘制。 2.GPU&#xff1a;GPU拿到CPU计算好的显示内容&#xff0c;完成纹理的渲染&#xff0c; 渲染完成后将渲…

安全政策与安全意识(下)

等保测评介绍及解决方案 目录 一, 等保介绍 1.1 分三个等级 1.2 等级保护发展历程 1.2.1 等保1.0 1.2.2 等保2.0 1.2.3 等保等级对比 1.3 等级保护依据的法律,法规 1.4 等级保护2.0的法规、标准体系 1.5 等级保护等级划分 1.6 等级保护政策内容 二, 等保必要性 三…

Zookeeper工作机制、特点、数据结构、应用场景、配置参数解读

ZK工作机制 从涉及模式角度来理解&#xff1a;是一个基于观察者模式设计的分布式服务管理框架&#xff0c;负责存储和管理大家都关心的数据&#xff0c;然后接受观察者的注册&#xff0c;一旦这些数据的状态发生变化&#xff0c;zk就负责通知已在zk上注册的那些观察者做出相应…