C语言 static extern 关键字详解

news2025/1/12 10:55:38

C语言 static 关键字详解

  • 1 全局变量
  • 2 static 修饰全局变量
  • 3 static 修饰局部变量
  • 4 static 修饰函数
  • 5 extern 关键字

 


 

在C语言中主要是用来修饰变量和函数

1 全局变量

全局变量的作用域十分的广,只要在一个源文件中定义后,应用中所有的所有源文件、对象以及函数都可以调用,生命周期更是贯穿整个程序

代码说明

文件 global_test.cpp

int g_num = 100;//定义全局变量

文件 main.cpp

extern int g_num;//声明全局变量 不需要包含头文件 也可以引用 使用extern关键字

int32 get_g_num();

int main()
{
    get_g_num();
    return 0;
}

int32 get_g_num()
{
    return g_num;
}

 


2 static 修饰全局变量

 

  1. static 修饰全局变量其作用域会被限制在当前文件中

文件 global_test.cpp

#include "global_test.h"
// 如果全局变量被static修饰
// 那这个外部链接属性就会被修改成内部链接属性,
// 此时这个全局变量就只能在自己的源文件中使用;
static int g_num = 100;//static 修饰全局变量 变量的作用域会被限制在当前文件中

文件 main.cpp

#include "keyword.h"
extern int g_num;//声明全局变量 不需要包含头文件 也可以引用 使用extern关键字
int main()
{
    printf("g_num = %d\n",g_num);
    return 0;
}

此时编译会发现没有定义变量 g_num 说明 g_num被限制在了 global_test.cpp

其本质是

全局变量本身是具有外部链接属性的,在A文件中定义的全局变量,在B文件中可以通过【链接】来使用;
但如果全局变量被static修饰,那这个外部链接属性就会被修改成内部链接属性,此时这个全局变量就只能在自己的源文件中使用

  1. 对static全局变量的修改对其他文件不可见

在另一个头文件中包含定义有静态全局变量头文件,此静态全局变量可以被引用

文件 global_test.h

static int g_num = 100;

文件 test.h

#ifndef KEYWORD_H
#define KEYWORD_H
#include "ctest.h"
#include "global_test.h" 
int32 print_g_num();
#endif // KEYWORD_H

文件 test.cpp

#include "keyword.h"

int32 print_g_num()
{
    // 在 global_test.h 头文件中定义的静态全局变量在文件被包含之后可以被正常访问
    printf("g_num = %d",g_num);
    return 0;
}

文件 main.c

#include <stdio.h>
#include "test.h"
int main()
{
    print_g_num();
    return 0;
}

静态全局变量被多次包含会出现重复定义错误么? 答案是不会 接下来验证

test_2.cpp中包含头文件 global_test.h

#include "global_test.h"
#include "stdio.h"
int print_g_num_1()
{
    printf("g_num = %d\n",g_num);
    return 0;
}

文件 main.c

#include <stdio.h>
#include "test.h"
extern int print_g_num_1();//函数声明
int main()
{
    print_g_num();// 正常访问 g_num
    print_g_num_1();// 正常访问 g_num
    return 0;
}

如果将 global_test.h 中的 static 关键字去掉,则上述代码编译之后会出现重复定义错误

在一个文件中对静态全局变量进行修改对其他文件不可见

global.h

#ifndef GLOBAL_TEST_H
#define GLOBAL_TEST_H
static int g_num = 100;//定义静态全局变量
int set_num_3(int num);
int print_num_3();
#endif // GLOBAL_TEST_H

global.c

#include "global_test.h"
int set_num_3(int num)
{
    printf("set_num_1 modi befor g_num = %d\n",g_num);
    g_num  = num;
}

int print_num_3()
{
    printf("g_num = %d\n",g_num);
    return 0;
}

test.c

int print_num_1()
{
    printf("g_num = %d\n",g_num);
    return 0;
}

int set_num_1(int num)
{
    printf("set_num_1 modi befor g_num = %d\n",g_num);
    g_num  = num;
}
#include "global_test.h"
#include "stdio.h"
int print_g_num_1()
{
    printf("g_num = %d\n",g_num);
    return 0;
}

int set_num_2(int num)
{
    printf("set_num_1 modi befor g_num = %d\n",g_num);
    g_num  = num;
}

int print_num_2()
{
    printf("g_num = %d\n",g_num);
    return 0;
}

main.c

#include <stdio.h>
#include "test.h"
#include "global_test.h"
//函数声明
extern int print_g_num_1();
extern int set_num_1(int);
extern int set_num_2(int);
extern int print_num_1();
extern int print_num_2();

int main()
{
     set_num_3(3);
     print_num_3();

     set_num_2(2);
     print_num_2();

     set_num_1(1);
     print_num_1();
}

输出结果

从输出结果可以得出结论 :
对静态全局变量的修改对其他文件是不可见的,相当于每个文件中都有一份初始的值,都一样,各自修改各自的,互不影响

 


3 static 修饰局部变量

 

coding
test.c

int  local_var_test()
{
    /**
       * 局部变量只是在第一次调用时会被初始化一次 数据是存储在全局区
       */
    static int index = 0;
    index ++;
    printf("index =  %d \n",index);
    return 0;
}

int  test()
{
    for (int i = 0;i < 10;++i){
         local_var_test();
    }
}

main.c

extern int  test();
int main()
{
    test();
}

output

index = 1
index = 2
index = 3
index = 4
index = 5
index = 6
index = 7
index = 8
index = 9
index = 10

 


4 static 修饰函数

 

在上面的代码中 我们只需要在 main.c中 声明 函数,即可完成对函数的调用

现在我们把函数声明为静态函数,即使用 static修饰,则此函数将会被限制在所在文件中,使用extern关键字也无法调用该函数

test.c

static int static_func_test()
{
    printf("static_func_test \n");
    return 0;
}
extern static_func_test();
int main()
{
    static_func_test();
}

此时编译报错,没有定义引用 static_func_test

函数本身也是有外部链接属性的;
被static修饰后,函数的外部链接属性被修改成内部链接属性,使得这个函数只能在自己的源文件内被使用,因此函数的作用域就变小了。

 


5 extern 关键字

 

extern 是一种外部声明的关键字,字面意思就是在此处声明某种变量或函数,在外部定义。

 
1 修饰变量

在其它文件中定义变量

int extern_val = 100;//定义变量 并进行初始化

在当前文件中引用变量

#include <stdio.h>
extern int extern_val;//声明变量 表示此处要进行引用
int main()
{
    printf("extern_val = %d\n",extern_val);
    return 0;
}

 

2 修饰函数
 

在其它头文件中定义函数
 

// 函数的定义
int printArr(int* pIntArr,int ilen){
    if (pIntArr == NULL || ilen == 0)
    {
        return 0;
    }
    for (int index = 0; index < ilen; index++){
        printf("%d ",pIntArr[index]);
    }
    return 0;
}

 

声明并引用函数
 

extern int printArr(int* pIntArr,int ilen);//函数的声明
int main()
{
    int intArr[] = {1,20,7,3,12};
    printArr(intArr,sizeof(intArr) / sizeof(int));
    return 0;
}

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

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

相关文章

发现国内优秀的团队协作软件,帮助提高工作效率

中国有许多优秀的团队协作软件&#xff0c;它们在企业和组织中发挥着重要作用。 以下是一些最受欢迎的团队协作软件&#xff1a; 1、钉钉&#xff08;DingTalk&#xff09;: 这是一款由阿里巴巴推出的企业级协作工具&#xff0c;旨在帮助企业和组织实现高效沟通和协作。钉钉提…

【VR】【Unity】如何调整Quest2的隐藏系统时间日期

【背景】 网络虽然OK&#xff0c;但是Oculus Quest要连上商店还必须调整好系统时间&#xff0c;不过在Quest系统中&#xff0c;时间对用户是不可见的&#xff0c;本篇介绍调整的方法。 【方法】 打开SideQuest&#xff0c;没有的话先去下载一个。打开后先登录&#xff0c;如…

Unity-3D模型展示

将3D模型放置到某个位置&#xff0c;然后通过鼠标左键进行旋转的操作 一种方法是添加另外的相机&#xff0c;采用RenderTexture来渲染该相机的内容 那么RenderTexture是做什么的呢&#xff1f; RenderTexture可以捕获从摄像机、光源和其他对象渲染的图像&#xff0c;并将结果…

基础课2——自然语言处理

1.概念 自然语言处理&#xff08;Natural Language Processing, NLP&#xff09;是计算机科学领域与人工智能领域中的一个重要方向&#xff0c;它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和方法。 自然语言处理的主要研究方向包括&#xff1a; 语言学研究&…

软考高项第四版教材整合管理(第8章)重点内容

序&#xff1a;距离2023下半年软考还有18天&#xff0c;来不及看书的小伙伴看过来啦&#xff0c;一起过一下重点&#xff0c;开始之前&#xff0c;建议大家将下面的过程组矩阵图熟记&#xff01;&#xff01;&#xff01; 第8章 项目整合管理 项目整合管理包括识别、定义、组…

水滴怕片效果实现

效果展示 CSS 知识点 border-radius 属性运用 FANCY-BORDER-RADIUS 工具 此工具主要是实现不规则的图形。 FANCY-BORDER-RADIUS 工具地址 页面整体布局实现 <div class"container"><div class"drop" style"--clr: #ff0f5b">&l…

手机有什么爬虫App工具?

随着智能手机的普及和应用的繁盛&#xff0c;越来越多的人开始对手机App进行数据爬取和分析。那么&#xff0c;在进行手机App爬虫的过程中&#xff0c;我们可以借助哪些工具呢&#xff1f;让我们一起来了解一下吧&#xff01; 1、Fiddler Fiddler是一款功能强大的网络调试工具…

Angular安全专辑之五 —— 防止URL中敏感信息泄露

URL 中的敏感数据是指在网址上的机密或者个人信息&#xff0c;包括 UserId, usernames, passwords, session, token 等其他认证信息。 由于URL 可能会被第三方拦截和查看&#xff08;比如互联网服务商、代理或者其他监视网络流量的攻击者&#xff09;&#xff0c;所以URL中的敏…

Qt (QFileDialogQColorDialogQFontDialog) 对话框实战

目录 一、QFileDialog 类 (文件对话框) 二、QColorDialog 类(颜色对话框) 三、QFontDialog 类(字体对话框类) 一、QFileDialog 类 (文件对话框) QFileDialog 是 Qt 框架中的一个类&#xff0c;用于在应用程序中提供文件对话框。它允许用户选择文件或目录&#xff0c;并且可…

ssh 连接:Permission denied (publickey,gssapi-keyex,gssapi-with-mic).

报错原因&#xff1a; ssh配置文件中有些配置文件没有开启 问题解决&#xff1a; PasswordAuthentication yes // 开启密码登录 PermitRootLogin yes // 开启root登录 PubkeyAuthenticaion yes // 开启公钥登录 配置项解释&#xff1a; 1.PasswordAuthenticati…

AI算法检测对无人军用车辆的MitM攻击

南澳大利亚大学和查尔斯特大学的教授开发了一种算法来检测和拦截对无人军事机器人的中间人&#xff08;MitM&#xff09;攻击。 MitM 攻击是一种网络攻击&#xff0c;其中两方&#xff08;在本例中为机器人及其合法控制器&#xff09;之间的数据流量被拦截&#xff0c;以窃听或…

诊断DLL——周立功模板生成dll文件

文章目录 前言一、周立功sa_demosa.cppdll.h二、自定义安全访问算法三、配置工程属性四、生成dll库五、ZCANPRO加载dll文件六、总结前言 在实际诊断工程应用中,如UDS刷写——27服务,经常会遇到一些Seed2Key的算法问题,为了安全保密,这个算法的源码不便公开,我们可以将其打…

UGUI交互组件InputField

一.InputField的结构 对象说明InputField挂有TextMeshPro-InputField组件的主体对象Text Area文本显示区Placeholder未输入时占位文本Enter text...Text输入的显示文本 二.InputField的属性 属性说明Text ViewportText Area子对象的引用Text ComponentText子对象的引用Text输入…

解密JavaScript的异步机制:打破单线程限制,提升性能与用户体验

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 一、JavaScript的异步编步机制 二、事件循环…

面试总结之并发编程

一、ThreadLocal 1、什么是ThreadLocal ThreadLocal是一种多线程隔离机制&#xff0c;提供了多线程环境下对共享变量访问的安全性 在多线程访问共享变量的场景中&#xff08;如上图&#xff09;&#xff0c;一般的解决方案是对共享变量加锁&#xff0c;从而保证同一时刻只有一…

“权限之舞:Linux安全之道”

W...Y的主页&#x1f60a; 代码仓库分享&#x1f495; &#x1f354;前言&#xff1a; 在之前的Linux博客中&#xff0c;我们学习了基础的Linux指令&#xff0c;具体可以订阅一下博主的Linux专栏学习。当我们想进行递归删除文件时等等许多操作中&#xff0c;只有在root账号中…

IPV6 ND协议--源码解析【根源分析】

ND协议介绍 ND介绍请阅读上一篇文章&#xff1a;IPv6知识 - ND协议【一文通透】11.NDP协议分析与实践_router solicitation报文中不携带source link-layer address-CSDN博客 ND协议定义了5种ICMPv6报文类型&#xff0c;如下表所示&#xff1a; NS/NA报文主要用于地址解析RS/…

使用PyTorch解决多分类问题:构建、训练和评估深度学习模型

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

【学习笔记】RabbitMQ02:交换机,以及结合springboot快速开始

参考资料 RabbitMQ官方网站RabbitMQ官方文档噼咔噼咔-动力节点教程 文章目录 四、RabbitMQ &#xff1a;Exchange 交换机4.1 交换机类型4.2 扇形交换机 Fanout Exchange4.2.1 概念4.2.1 实例&#xff1a;生产者4.2.1.1 添加起步依赖4.2.1.2 配置文件4.2.1.3 JavaBean进行配置4.…

NGF ; -R : Trk NTRK

NTRK基因融合的机制与靶向治疗 - 知乎 【NTRK基因】共识已发布&#xff0c;24款获证&#xff0c;2款NGS产品已布局