C语言基础系列【9】常见存储类型介绍

devtools/2025/2/12 7:35:32/

博主介绍:程序喵大人

  • 35- 资深C/C++/Rust/Android/iOS客户端开发
  • 10年大厂工作经验
  • 嵌入式/人工智能/自动驾驶/音视频/游戏开发入门级选手
  • 《C++20高级编程》《C++23高级编程》等多本书籍著译者
  • 更多原创精品文章,首发gzh,见文末
  • 👇👇记得订阅专栏,以防走丢👇👇
    😃C++基础系列专栏
    😃C语言基础系列

在C语言中,存储类型定义了变量或函数在内存中的存储位置、生命周期和作用域。下面将详细介绍C语言中主要的存储类型,主要有几个关键字:registerstaticextern

register

register用于提示编译器将变量存储在CPU寄存器中,而不是RAM中。

寄存器的访问速度比RAM快得多,因此对于需要频繁访问的变量,使用register可以提高程序的运行速度。

需要注意的是,register是一个建议而非强制要求,编译器可能会忽略这个建议。

此外,由于寄存器大小有限,register变量的大小不能超过寄存器的大小。

示例代码

#include <stdio.h>void myFunction() {register int count = 0;for (count = 0; count < 1000000; count++) {// 频繁访问count变量}printf("Count reached 1000000\n");
}int main() {myFunction();return 0;
}

static

static在C语言中有两种主要用途:一是修饰局部变量,使其在函数调用之间保持值不变;二是修饰全局变量,限制其作用域仅限于声明它的文件内。

  • 修饰局部变量: 当static修饰局部变量时,该变量在程序的生命周期内只被初始化一次,并且在函数调用之间保持其值不会改变。

示例代码

#include <stdio.h>void myFunction() {static int count = 0; // 静态局部变量,只在程序开始时初始化一次count++;printf("Count = %d\n", count);
}int main() {for (int i = 0; i < 5; i++) {myFunction();}return 0;
}

输出:

Count = 1Count = 2
Count = 3Count = 4
Count = 5
  • 修饰全局变量: 当static修饰全局变量时,变量的作用域被限制在声明它的文件内。这对于模块化编程非常有用,可以避免命名冲突。

示例代码(两个文件)

// file1.c
#include <stdio.h>static int globalVar = 100; // 静态全局变量,只在file1.c中可见void printGlobalVar() {printf("GlobalVar in file1.c = %d\n", globalVar);
}
// file2.c
#include <stdio.h>// extern int globalVar; // 如果去掉static,则需要在file2.c中声明
void anotherFunction() {// printf("GlobalVar in file2.c = %d\n", globalVar); // 错误:globalVar在file2.c中不可见
}int main() {printGlobalVar();anotherFunction();return 0;
}

编译和运行:

clang file1.c file2.c -o myProgram./myProgram

输出:

GlobalVar in file1.c = 100

extern

extern用于声明在其他文件中定义的全局变量或函数。

当在多个文件中使用全局变量或函数时,可以在一个文件中定义它们,并在其他文件中使用extern关键字来声明它们。这样,所有文件都可以访问同一个全局变量或函数,实现跨文件的数据共享。

示例代码(两个文件)

// file1.c
#include <stdio.h>int globalVar = 100; // 全局变量,在file1.c中定义void printGlobalVar() {printf("GlobalVar in file1.c = %d\n", globalVar);
}
// file2.c
#include <stdio.h>extern int globalVar; // 声明在file1.c中定义的全局变量void anotherFunction() {printf("GlobalVar in file2.c = %d\n", globalVar);
}int main() {printGlobalVar();anotherFunction();return 0;
}

编译和运行:

clang file1.c file2.c -o myProgram./myProgram

输出:

GlobalVar in file1.c = 100GlobalVar in file2.c = 100

建议,对于频繁访问的变量,可以考虑使用register来提高访问速度;对于需要在函数调用之间保持值的变量,可以使用static;对于需要在多个文件中共享的全局变量,可以使用extern进行声明。

码字不易,欢迎大家点赞关注评论,谢谢!


C++训练营

专为校招、社招3年工作经验的同学打造的1V1 C++训练营,量身定制学习计划、每日代码review,简历优化,面试辅导,已帮助多名学员获得offer!训练营介绍


http://www.ppmy.cn/devtools/158148.html

相关文章

嵌入式工程师面试经验分享与案例解析

嵌入式工程师岗位受到众多求职者的关注。面试流程严格&#xff0c;技术要求全面&#xff0c;涵盖C/C编程、数据结构与算法、操作系统、嵌入式系统开发、硬件驱动等多个方向。本文将结合真实案例&#xff0c;深入剖析嵌入式工程师的面试流程、常见问题及应对策略&#xff0c;帮助…

Spring中常见的设计模式

Spring框架是一个庞大的生态系统&#xff0c;设计模式的应用广泛分布在其各个模块中。以下是针对你提到的设计模式&#xff0c;在Spring源码中的具体应用位置&#xff1a; 单例模式&#xff08;Singleton Pattern&#xff09;&#xff1a; 在org.springframework.beans.factory…

什么是动态路由和嵌套路由?

动态路由和嵌套路由是 Vue Router 中的两个重要概念,它们可以帮助构建复杂的单页应用程序(SPA)。以下是对这两个概念的详细解释: 一、动态路由 定义 动态路由是指根据特定条件或参数动态生成的路由。它允许你在运行时根据 URL 中的参数或其他条件加载不同的组件。 使用…

Office hour 1

涉及Python环境配置、深度学习框架安装、常用数据处理和分析库、以及Python IDE的选择等内容。 1. Anaconda 安装与配置 • Anaconda Individual Edition&#xff1a;Anaconda 是一个开源平台&#xff0c;旨在简化数据科学的工作流程&#xff0c;提供了 Python 和超过 150 个科…

oracle11g搭建主从集群

安装oracle11g参考&#xff1a;centos安装oracle11g数据库-CSDN博客 一、主库操作 sqlplus / as sysdba 1、开启归档模式和强制日志模式 shutdown immediate startup mount #开启归档模式和强制日志模式 alter database archivelog; alter database force logging; #开启补…

VertexList(顶点列表)里的 normal(法线)

含义 在三维空间里&#xff0c;每个顶点的法线是一个单位向量&#xff08;长度为 1&#xff09;&#xff0c;它垂直于该顶点所在的表面。对于平面来说&#xff0c;平面上所有顶点的法线方向是相同的&#xff1b;而对于曲面&#xff0c;每个顶点的法线方向通常会根据曲面的局部…

代码随想录算法【Day40】

Day40 121. 买卖股票的最佳时机 class Solution { public:int maxProfit(vector<int>& prices) {int len prices.size();if (len 0) return 0;vector<vector<int>> dp(len, vector<int>(2));dp[0][0] - prices[0];dp[0][1] 0;for(int i 1; i…

Vue 3 中的 reactive 和 ref 有什么区别?

在 Vue 3 中,reactive 和 ref 是用于创建响应式状态的两个 API。虽然它们的目标都是使数据响应式,但它们的使用场景和实现方式有所不同。以下是它们之间的主要区别: 目录 何时使用 reactive 和 ref基本用法响应式对象的类型总结何时使用 reactive 和 ref reactive:适用于创…