全局变量和宏

先说全局变量:

全局变量是定义在函数外部的变量,与任何函数没有任何关系。在所有的函数都可以访问全局变量,它的作用于是整个程序。这里需要注意一个区别:本地变量在未初始化的时候它的值是随机的,但是全局变量会得到一个0值,指针的话会得到一个NULL。同时全局变量在被赋值的时候不可以被赋一个变量,哪怕是之前的全局变量。比如:

include <stdio.h>
int n=12;
int m=n;                             //系统就会报错
int main()
{
.....

但是如果我们把这个变量声明为const呢?就会发现可以通过了。但注意,必须是按照如下的顺序:

include <stdio.h>
const int n=12;
int m=n;                                   //right
int main()
{
.......

include <stdio.h>
int m=n;                                 //wrong
const int n=12;
int main()
{
......

其实在C语言中还有一种和全局变量很类似的东西叫做静态局部变量:关键字static。

它的特性是在函数结束后会继续存在并保留其值,也就是生命周期和全局变量相同,它的初始化只能在最开始第一次进入函数的过程中进行。但是静态局部变量有一个地方和全局变量不同就是它只能在局部函数的作用域内访问,不能在其它函数访问。

综上在一个函数中我们返回的如果是一个全局变量或者静态局部变量的地址是安全的。但是在多线程条件使用全局变量和静态局部变量是很不安全的。

接下来再来看看宏:

#define N 某些值

C语言中其实是把源代码中N这个符号文本替换为数值(注意只是文本替换,所以不会进行编译检查)。这里的值不只是数值可以是表达式甚至是注释,更有甚者可以是多行的宏。

#define  PI 3.14   \
              E   2.79

C语言中还有一些预定义的宏比如:_LINE_(代表源代码行号),_FILE_(代表文件名)等等。

当然宏还可以定义为函数的形式,也就是宏可以被定义为带参数。

#include <stdio.h>
#define cube(x) ((x)*(x)*(x))
int main()
{
    printf("%d",cube(5));
    return 0;
}

然后我们就可以得到125.但是我们需要小心的是这种带参数的宏一定都要加括号。整个值要加括号,各个参数也要加括号,因为宏替换只是一种文本替换。所以为了避免错误,一定要在各个参数加括号。

再来一个例子(带多个参数的宏):

#define MAX(a,b) ((a)>(b)?(a):(b))        //选出最大值

当然宏还可以是嵌套的。

宏的使用主要是因为可以节省时间的开销,省去了调用函数的时间。但是因为它不会进行类型检查所以C以及C++语言中后来会用inline函数来代替部分宏。

最后可以看下这个例子:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TOUPPER(c) (‘a‘<=(c)&&(c)<=‘z‘?(c)-‘a‘+‘A‘:(c))
int main()
{
    char s[100];
    strcpy(s, "abcd");
    int i = 0;
    putchar(TOUPPER(s[++i]));
}

输出的是:D.

时间: 2024-12-29 11:15:28

全局变量和宏的相关文章

初识zabbix需了解的二三事

简介 zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案: zabbix能监视各种网络参数,保证服务器系统的安全运营:并提供灵活的通知机制以让系统管理员快速定位/解决存在的各种问题: 监控平台的组成 数据采集 --> 数据存储 --> 数据展示和分析 --> 报警 常见监控实现方案对比 cacti 优点:利用rrdtool绘图,图形美观: 缺点:报警功能薄弱,不适合大规模监控场景: nagios 优点:报警功能强大: 缺点:只关心正常与否的状态,数

算法的优化(C语言描述)

算法的优化 算法的优化分为全局优化和局部优化两个层次.全局优化也称为结构优化,主要是从基本控制结构优化.算法.数据结构的选择上考虑:局部优化即为代码优化,包括使用尽量小的数据类型.优化表达式.优化赋值语句.优化函数参数.全局变量及宏的使用等内容. 一.全局优化 1.优化算法设计 例如,在排序中用快速排序或者堆排序代替插入排序或冒泡排序:用较快的折半查找代替顺序查找法等,都可以极大地提高程序的执行效率. 2.优化数据结构 例如在一堆随机存放的数中使用了大量的插入和删除指令,那么使用链表要快得多.数

Makefile中头文件在依赖关系中作用

摘于:http://bbs.csdn.net/topics/120024677 (1)在makefile的依赖关系中用不用体现.h头文件?(2)如果在依赖关系中要体现.h头文件,应该体现到什么层次?==============================(1)在makefile的依赖关系中用不用体现.h头文件?============================== 下面是我的一些认识: 头文件中定义的是接口(函数接口,文件外全局变量和宏定义),它的作用是向调用文件封装函数的实现过程.在

Java通过JNI调用C

Java调用C有多种方式,本文介绍笔者最近的学习过程,避免今后再犯类似的错误. 首先,Java肯定是调用C的动态链接库,即通过编译器编译后的dll/so文件. 下面介绍gcc编译dll的方法. 一般情况把主函数,子函数定义,子函数声明(全局变量,宏等)分别放在不同的文件中. 我们主要对子函数编译生成可用的dll,供主函数调用. 有一个工程,里面有三个文件,分别是 #include <stdio.h> #include "test.h" int main(int argc,

PHP 源码学习之线程安全

从作用域上来说,C语言可以定义4种不同的变量:全局变量,静态全局变量,局部变量,静态局部变量. 下面仅从函数作用域的角度分析一下不同的变量,假设所有变量声明不重名. 全局变量,在函数外声明,例如,int gVar;.全局变量,所有函数共享,在任何地方出现这个变量名都是指这个变量 静态全局变量(static sgVar),其实也是所有函数共享,但是这个会有编译器的限制,算是编译器提供的一种功能 局部变量(函数/块内的int var;),不共享,函数的多次执行中涉及的这个变量都是相互独立的,他们只是

LXNetwork – 基于AF3.0封装的iOS网络请求库

本框架实现思路与YTKNetwork和RTNetworking类似,相当于一个简单版,把每一个网络请求封装成对象.使用LXNetwork,你的每一个请求都需要继承LXBaseRequest类,通过覆盖父类的一些方法或者实现相关协议方法来构造指定的网络请求.这个网络库可直接在项目中使用,但是有些功能完成度不是很完美,待完善. GitHud地址:https://github.com/CoderLXWang/LXNetwork 一.为什么要这样做? 实现思路的图在下面,可以对比着图看下面内容. 直接封

vim配置(vimplus)

vim配置(vimplus) vimplus vimplus是vim的超级配置安装程序 github地址:https://github.com/chxuan/vimplus.git,欢迎star和fork. 接触vim到现在也有几年了,但是之前用vim都是在网上找别人配置好了的vim,但是别人配置的始终都不能够满足自己的需求(自己需要有强大的C/C++代码提示补全功能.头文件/源文件切换.静态代码分析等功能),所以最近自己有时间,自己归纳了一些vim的插件,然后做成一键安装程序,供有相同需求的v

PHP 扩展开发小结

1.变量操作 设置变量 ZVAL_*系列函数; 例: zval t; ZVAL_STRING(t,"10",2); 获取变量 Z_* 系列函数 获取变量指针 Z_*_P 系列函数 获取变量指针的指针 Z_*_PP 系列函数 例: Z_STRVAL(t); Z_STRLEN(t); 变量类型转换 convert_to_* 系列函数 例: convert_to_long_ex(t); 获取变量类型 Z_TYPE Z_TYPE_P Z_TYPE_PP 可以同 IS_* 系列常量对比 例: i

C语法中的内存分配

关于c中的内存分配问题,这个问题怎么说好呢,我感觉还是和内存四区挂上了钩,在主调函数中栈区上分配的内存空间是可以在被调函数使用的: 例: #include <stdio.h> #include <string.h> #include <stdlib.h> char *distribution(char *a) { char b[64];//被调函数中在栈区上分配一个64字节的一维数组 printf("%s\n",a);//打印字符串为 aaabbb