美文网首页
C易遗忘的碎片

C易遗忘的碎片

作者: 陈_振 | 来源:发表于2018-10-02 14:39 被阅读0次

指针和数组
char a[] = "cz";定义的是一个字符串变量!
char *b = "cz";定义的是一个字符串常量!

预处理指令

预处理指令-宏定义
C语言提供的预处理指令主要有:宏定义、文件包含、条件编译

宏名和参数列表之间不能有空格,否则空格后面的所有字符串都作为替换的字符串

带参数的宏在展开时,只作简单的字符和参数的替换,不进行任何计算操作。所以在定义宏时,一般用一个小括号括住字符串的参数。
计算结果最好也用括号括起来。

带参数的宏定义与函数的区别:
1.宏定义不涉及存储空间的分配、参数类型匹配、参数传递、返回值问题。
2.函数调用在程序运行时执行,而宏替换只在编译预处理阶段进行。所以带参数的宏比函数具有更高的执行效率。

预处理指令-条件编译
在很多情况下,我们希望程序的其中一部分代码只有在满足一定条件时才进行编译,否则不参与编译(只有参与编译的代码最终才能被执行),这就是条件编译。

#if和#elif

#if condition1
code fragment
#elif condition2
code fragment
#else
code fragment
#endif

#if#elif后面的条件一般是判断宏定义而不是判断变量,因为条件编译是在编译之前做的判断,宏定义也是编译之前定义的,而变量是在运行时才产生的、才有使用的意义。

#if defined()#if !defined()
#if#elif后面的条件不仅仅可以用来判断宏的值,还可以判断是否定义过某个宏。比如:

#define Pi 3.14

#if defined(Pi)
code fragment
#endif


#if !defined(Pi)
code fragment
#endif

#ifdef用法和#if defined()基本一致
#ifndef用法和#if !defined()基本一致

预处理指令-文件包含
#include,它可以将一个文件的全部内容拷贝另一个文件中。

#include <file name>
直接到C语言库函数头文件所在的目录中寻找文件。
#include "file name"
系统会先在源程序当前目录下寻找,若找不到,再到操作系统的path路径中查找,最后才到C语言库函数头文件所在目录中查找

使用注意:

  1. #include允许嵌套包含,不允许递归包含。
  2. #include指令可能导致多次包含同一个头文件,降低编译效率。如:
    b.h 包含 a.h,但是在main.c中同时包含了b.ha.h,此时a.h被包含了两次,a.h中的代码也会被声明多次,导致编译效率降低。
    解决办法:
    在每个头文件中添加如下代码
// a.h
#ifndef _A  _H_
#define _A_H_
code fragment
#endif


// b.h
#ifndef __B_H_
#define _B_H_
code fragment
#endif

变量

C语言有丰富的数据类型和运算符,因此计算能力非常强大,计算过程中使用的值一般用变量来存储。变量也是有分类型的,不同类型的变量有不同的存储类型、不同的生命周期、不同的作用域,C语言也提供了一些关键字来设置变量的属性(比如设置存储类型、生命周期)。

变量的作用域
局部变量:
在函数内部定义的变量,称为局部变量。形式参数也属于局部变量。
全局变量:
在所有函数外部定义的变量,称为全局变量。

变量的存储类型
变量的存储类型就是指变量存储在什么地方。有3个地方可以用于存储变量:普通内存、运行时堆栈、硬件寄存器。变量的存储类型决定了变量何时创建、何时销毁以及它的值能保持多久,也就是决定了变量的生命周期。

自动变量:
自动变量是存储在堆栈中的。

静态变量:
静态变量是存储在静态内存中的,也就是不属于堆栈。
所有的全局变量都是静态变量
被关键字static修饰的局部变量也是静态变量

寄存器变量:
存储在硬件寄存器中的变量,称为寄存器变量。寄存器变量比存储在内存中的变量访问效率更高(默认情况下,自动变量和静态变量都是放在内存中的)。
被关键字register修饰的自动变量都是寄存器变量。
只有自动变量才可以是寄存器变量,全局变量和静态局部变量不行。
寄存器变量只限于int、char和指针类型变量使用。

由于计算机中寄存器数目有限,不能使用太多的寄存器变量。如果寄存器使用饱和时,程序将寄存器变量自动转换为自动变量处理
为了提高运算速度,一般会将一些频繁使用的自动变量定义为寄存器变量,这样程序尽可能地为它分配寄存器存放,而不用内存

static和extern

static和extern对函数的作用
外部函数:
如果在当前文件中定义的函数允许其他文件访问、调用,就称为外部函数。C语言规定,不允许有同名的外部函数。

内部函数:
如果在当前文件中定义的函数不允许其他文件访问、调用,只能在内部使用,就称为内部函数。C语言规定不同的源文件可以有同名的内部函数,并且互不干扰。

在编译阶段,编译器只会检测单个源文件的语法合不合理,并不检测函数有没有定义,只有在链接的时候才会检测这个函数存不存在,也就是有没有被定义。

static:

  • 在定义函数时,在函数的最左边加上static可以把该函数声明为内部函数(又叫静态函数),这样该函数就只能在其定义所在的文件中使用。如果在不同的文件中有同名的内部函数,则互不干扰。

  • static也可以用来声明一个内部函数

extern:

  • 在定义函数时,如果在函数的最左边加上关键字extern,则表示此函数是外部函数,可供其他文件调用。C语言规定,如果在定义函数时省略extern,则隐含为外部函数。

  • 在一个文件中要调用其他文件中的外部函数,则需要在当前文件中用extern声明该外部函数,然后就可以使用,这里的extern也可以省略。

static和extern对变量的作用

  1. extern可以用来声明一个全局变量,但是不能用来定义变量

  2. 默认情况下,一个全局变量是可以供多个源文件共享的,也就说,多个源文件中同名的全局变量都代表着同一个变量

  3. 如果在定义全局变量的时候加上static关键字,此时static的作用在于限制该全局变量的作用域,只能在定义该全局变量的文件中才能使用,跟其他源文件中的同名变量互不干扰

extern是用来声明已经定义过而且能够访问的变量。它不能用来声明在其他文件中定义的static变量。

参考:
预处理指令

相关文章

  • C易遗忘的碎片

    指针和数组char a[] = "cz";定义的是一个字符串变量!char *b = "cz";定义的是一个字符串...

  • 遗忘的碎片

    什么是遗忘呢 或许它就像一把铁锤 把过往所有的回忆都 敲得支离破碎 散落在缝隙里 然后一片一片逐渐 被时间风化成靡...

  • 易被遗忘的C/C++要点总结

    一、 数据类型及运算 求补码 原码的基础上, 符号位不变, 其余各位取反, 最后+1 原码转补码不考虑符号位 补码...

  • 遗忘的记忆碎片

    前言:第一眼看到这个主题,我有点懵。因为校园生活离我已经太遥远了,远得一瞬间我都想不起来什么。似乎过去的酸甜苦乐在...

  • 点滴C学习之“#”和“##”使用

    从今天开始,混子争取花少量时间都能够输出一个C语言小知识点,也是容易遗忘的知识点。卷起来吧,抓住碎片时间,日积月累...

  • 军中碎片之十七,被碎片遗忘的角落

    被碎片遗忘的角落 写点东西成了瘾而一发不可收拾,凡有空闲时间就打开写作板,管它有无灵感低头便写,为此必然良莠不齐,...

  • 不会被遗忘的生活碎片

    好怀念小时候的暑假。 每天睡到自然醒,乱糟糟的起床,外面的知了一直叫。中午吃完饭,就在家里地板上铺上凉席,...

  • 最易遗忘的爱

    从黑发到白发只不过沧桑的瞬间,总有那么一种情感牵挂内心最深处。总是感叹一生何求,却不曾珍惜陪伴成长的人,等到...

  • 阅读记录(79)|消除焦虑的行动

    阅读目的/碎片出处 碎片出处: [消除焦虑,抵制压力的 11 条建议]https://mp.weixin.qq.c...

  • 今日思考之信息碎片化

    信息碎片化并不是指信息分解为碎片,而是指我们接受的信息越多,某一条信息所占的比重就越小,最后像碎片一样被遗忘和忽视...

网友评论

      本文标题:C易遗忘的碎片

      本文链接:https://www.haomeiwen.com/subject/xzjooftx.html