热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C语言中extern的简易编译方法及预编译、static和extern的综合应用解析

本文详细探讨了C语言中`extern`关键字的简易编译方法,并深入解析了预编译、`static`和`extern`的综合应用。通过具体的代码示例,介绍了如何在不同的文件之间共享变量和函数声明,以及这些关键字在编译过程中的作用和影响。文章还讨论了预编译过程中宏定义的使用,为开发者提供了实用的编程技巧和最佳实践。

//

// main.c

// c预编译

//

// Created by stevenchang on 9/6/15.

// Copyright (c) 2015 cz. All rights reserved.

//

#include

/**

宏定义:

1> 不带参数的宏

2> 带参数的宏

*/

//不带参数的宏定义

#define LENGTH 5 //这里定义一个宏,宏的值是不变的,不可以对其进行++

//带参数的宏定义

#define sum(a,b) ((a)+(b)) //带参数的宏,使用时要将参数都要用小括号括住,不然会出现问题

#define Max(a,b) ((a)>(b)?(a):(b)) //求两个参数的最大值

/**

对于文件包含,我们使用的是#include

<> 包含的是系统自带的文件

"" 包含的是自定义的文件

*/

/**

条件编译&#xff1a;

#ifndef &#xff1a;如果未定义

#ifdef &#xff1a;如果定义

#elif

#elif

#endif &#xff1a; 必须以它结尾&#xff0c;不然程序会出错

*/

/**

typedef定义别名

*/

typedef struct Student { //定义了一个类型为结构体的变量stu

int age ;

double weight;

char *name;

} STU;

/**

上面的方式也可以写成&#xff1a;

struct Student {

int age;

double weight;

char *name;

};

typedef struct Student STU;

*/

typedef char * String; //定义一个指针为String,用于指向字符串

#define String1 char *; //这样定义也是可以的&#xff0c;但是使用这种是定义的宏&#xff0c;再编译的时候只会将String1进行替换&#xff0c;因此如果String1 s3, s4; 这种情况下&#xff0c;s4不是指针类型。实际为&#xff1a;char * s3, s4;

/**

static 作用于函数&#xff1a; static function_name();用于声明和定义一个内部函数&#xff0c;作用范围在当前文件有效&#xff1b;

extern 作用于函数&#xff1a; 用于声明和定义一个外部函数&#xff1b;默认情况下都是外部函数&#xff0c;因此可以省略。

extern 作用于变量 &#xff1a; 用于声明一个外部变量&#xff0c;默认情况下都是外部变量&#xff0c;因此可以省略&#xff1b;

static 作用于变量 &#xff1a; 用于声明一个内部变量&#xff0c;作用范围是&#xff1a;从当前定义开始&#xff0c;知道文件结束。

我们使用static作用变量的时候&#xff0c;static只分配一次内存空间&#xff0c;以后不会再次分配。

*/

void initArray(int array[]); //声明一个初始化数组的函数

void test();

int main(int argc, const char * argv[]) {

// insert code here...

// printf("Hello, World!\n");

int a[LENGTH]; //定义一个数组变量

initArray(a);

printf("&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;\n");

int b &#61; 10;

int c &#61; 20;

int result &#61; sum(b, c);

printf("%d\n",result);

printf("&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;\n");

double d &#61; 34.5;

double e &#61; 35.4;

double res &#61; Max(d, e);

printf("%.2f\n",res);

printf("&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;\n");

STU stu &#61; {13,23.4,"adfafa"};

printf("age&#61;%d,weight&#61;%f,name&#61;%s\n",stu.age,stu.weight,stu.name);

printf("&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;\n");

String str &#61; "steven";

printf("%s\n",str);

printf("&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;\n");

test();

test();

//可以发现num 最终值为12&#xff0c;说明num的声明周期不是在方法结束的时候就释放的

return 0;

}

/**

初始化数组函数&#xff1a;int array[]&#xff1a;数组变量&#xff1b; LENGTH&#xff1a;数组长度

*/

void initArray(int array[]) {

for (int i &#61; 0; i

array[i] &#61; i &#43; 1;

}

}

void test() {

static int num &#61; 10;

num&#43;&#43;;

printf("%d\n",num);

}



推荐阅读
  • 在稀疏直接法视觉里程计中,通过优化特征点并采用基于光度误差最小化的灰度图像线性插值技术,提高了定位精度。该方法通过对空间点的非齐次和齐次表示进行处理,利用RGB-D传感器获取的3D坐标信息,在两帧图像之间实现精确匹配,有效减少了光度误差,提升了系统的鲁棒性和稳定性。 ... [详细]
  • 深入解析 C 语言与 C++ 之间的差异及关联
    深入解析 C 语言与 C++ 之间的差异及关联 ... [详细]
  • 本研究基于状态空间方法,通过动态可视化技术实现了汉诺塔问题的求解过程,即将n个盘子从A柱移动到C柱。本文提供了一个使用C语言在控制台进行动画绘制的示例,并详细注释了程序逻辑,以帮助读者更好地理解和学习该算法。 ... [详细]
  • NOI题库(noi.openjudge.cn):1.7 编程基础之字符串 T31 至 T35 详解与解析
    T31至T35题目详细解析了字符串处理的基础编程技巧。其中,T31涉及P型编码,要求将一个仅包含数字字符的字符串转换为特定格式的编码串。例如,输入字符串“111223”应输出相应的P型编码结果。其他题目则涵盖了字符串的多种操作和变换方法,包括但不限于子串提取、字符替换和模式匹配等,旨在提升编程者对字符串处理的综合能力。 ... [详细]
  • 深入解析:使用C++实现Python字节数组(struct)的高效处理方法 ... [详细]
  • Java 9 中 SafeVarargs 注释的使用与示例解析 ... [详细]
  • 本文探讨了在Linux 2.6内核中实现进程隐藏的技术方法与实践。通过分析系统调用 `sys_getdents` 的工作原理,提出了一种有效的方法来隐藏指定的进程。该方法通过对内核模块进行修改,拦截并过滤掉目标进程的相关信息,从而在常用的进程查看命令(如 `ps` 和 `top`)中无法显示这些隐藏的进程。实验结果表明,该方法在实际应用中具有较高的隐蔽性和稳定性。 ... [详细]
  • 在幼儿园中,有 \( n \) 个小朋友需要通过投票来决定是否午睡。尽管这个问题对每个孩子来说并不是特别重要,但他们仍然希望通过谦让的方式达成一致。每个人都有自己的偏好,但为了集体和谐,他们决定采用一种最小割的方法来解决这一问题。这种方法不仅能够确保每个人的意愿得到尽可能多的尊重,还能找到一个最优的解决方案,使整体满意度最大化。 ... [详细]
  • 题目旨在解决树上的路径最优化问题,具体为在给定的树中寻找一条长度介于L到R之间的路径,使该路径上的边权平均值最大化。通过点分治策略,可以有效地处理此类问题。若无长度限制,可采用01分数规划模型,将所有边权减去一个常数m,从而简化计算过程。此外,利用单调队列优化动态规划过程,进一步提高算法效率。 ... [详细]
  • 本文深入探讨了NDK与JNI技术在实际项目中的应用及其学习路径。通过分析工程目录结构和关键代码示例,详细介绍了如何在Android开发中高效利用NDK和JNI,实现高性能计算和跨平台功能。同时,文章还提供了从基础概念到高级实践的系统学习指南,帮助开发者快速掌握这些关键技术。 ... [详细]
  • Qt 34:深入探讨缓冲区管理、目录操作及文件系统监控技术——QBuffer、QDir与QFileSystemWatcher的应用分析
    本文深入探讨了Qt框架中QBuffer、QDir和QFileSystemWatcher三个核心类的应用。QBuffer作为缓冲区管理工具,提供了高效的数据读写功能;QDir则专注于目录操作,支持路径遍历和文件检索等任务;而QFileSystemWatcher则用于实时监控文件系统的变化,便于应用程序及时响应文件或目录的增删改操作。通过实例分析,详细解析了这三个类在实际开发中的应用场景和实现细节。 ... [详细]
  • 使用Boost.Asio进行异步数据处理的应用程序主要依赖于两个核心概念:I/O服务和I/O对象。I/O服务抽象了操作系统接口,使得异步操作能够高效地执行。I/O对象则代表了具体的网络资源,如套接字和文件描述符,通过这些对象可以实现数据的读写操作。本文详细介绍了这两个概念在Boost.Asio中的应用及其在网络编程中的重要性。 ... [详细]
  • 深入解析Spring框架中的双亲委派机制突破方法
    在探讨Spring框架中突破双亲委派机制的方法之前,首先需要了解类加载器的基本概念。类加载器负责将类的全限定名转换为对应的二进制字节流。每个类在被特定的类加载器加载后,其唯一性得到保证。然而,这种机制在某些场景下可能会限制灵活性,因此Spring框架提供了一些策略来突破这一限制,以实现更加动态和灵活的类加载。这些策略不仅能够提升系统的可扩展性,还能在复杂的运行环境中确保类的正确加载和管理。 ... [详细]
  • 深入解析Gradle中的Project核心组件
    在Gradle构建系统中,`Project` 是一个核心组件,扮演着至关重要的角色。通过使用 `./gradlew projects` 命令,可以清晰地列出当前项目结构中包含的所有子项目,这有助于开发者更好地理解和管理复杂的多模块项目。此外,`Project` 对象还提供了丰富的配置选项和生命周期管理功能,使得构建过程更加灵活高效。 ... [详细]
  • Java 8 引入了 Stream API,这一新特性极大地增强了集合数据的处理能力。通过 Stream API,开发者可以更加高效、简洁地进行集合数据的遍历、过滤和转换操作。本文将详细解析 Stream API 的核心概念和常见用法,帮助读者更好地理解和应用这一强大的工具。 ... [详细]
author-avatar
你我她啊
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有