黑马程序员——C语言学习——预处理指令、extern与static、typedef、递归

————————Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ————————

一、 预处理指令

顾名思义,预处理,就是预先处理的指令,在代码编译之前执行。预处理指令的位置可以任意写。

作用域:从编写指令的那一行开始,一直到文件结尾,可以用#undef取消宏定义的作用

所有的预处理指令都是以#开头
预处理指令分3种
    1> 宏定义
    2> 条件编译
    3> 文件包含

1、宏定义

要义就两个字,替换。也就是编译前预先将一些 文字 替换成 另一些文字。

这些文字就叫做宏名,另一些文字可以是字符串,也可以是基本数据。宏名一般都是大写。

在编译前,完完全全就是将这个宏名换成后面的东西,只是替换操作。

注意:“” 双引号内的字符不进行宏的替换操作。


宏定义分为不带参数的和带参数的两种

不带参数的宏定义

#define 宏名 字符串

如:#define DYMOST @"dymost" // 就在本行起到结束,将文件中所有的DYMOST换成 @"dymost"


带参数的宏定义

#define 宏名(参数列表) 字符串

在编译预处理时,将源程序中所有宏名替换成字符串,并且将 字符串中的参数 用 宏名右边参数列表 中的参数替换

#include <stdio.h>
 
 #define average(a, b) (a+b)/2
 
 int main ()
 {
     int a = average(10, 4);
     
     printf("平均值:%d", a);
     return 0;
 }

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

因为宏定义仅仅是替换操作所有一定要将宏定义中 字符串中的参数用()括起来。

#include <stdio.h>
 
 #define D(a) 2*a
 
 int main ()
 {
     int b = D(3+4);
     
     printf("%d", b);
     return 0;
 }

a没用()括起来,D(3+4) 将会被替换成 2*3+4,和宏定义的本意a的2倍,大相径庭。

所有宏定义中字符串中参数一定要用()扩住


宏定义的结束

用#undef取消宏定义的作用


2、 条件编译

就是当符合某种条件的时候才进行预处理操作。和流程控制中选择结构,if语句很像

#if 条件1
  ...code1...
 #elif 条件2
  ...code2...
 #else
  ...code3...
 #endif

只有当符合某种条件的时候才,编译某段代码,其他代码不参与编译。


一般我们在C语言头文件中会采用条件编译防止文件重复拷贝

一般我们会在头文件中这么写

#ifndef 宏名

#define 宏名


需要拷贝的文件


#endif

 3、 文件包含

#include <文件名>

#include "文件名"

前面说过就是相当于拷贝操作,将文件中的所有代码 拷贝过来


二、 extern与static

我们在函数内部定义的变量叫做局部变量,会随着函数的消亡而消亡。通俗说,就是它的作用域从创建开始,只到} 截止。

在函数外面定义的变量就叫做全局变量。哪里都可以用。作用域从创建开始到程序结束

这里提到的extern与static就是扩大和缩减我们作用域的参数。


1、 extern,static和函数

现在我们是多文件开发。我们不同文件中又各种各样的函数。系统默认是将文件中写的函数转成外部函数,也就别的文件也可用的函数。C语言规定,不允许有同名的外部函数。

但是有时候我们不希望外部来调用我们的函数。使函数私有化。只有我本文件可用调用。这就是内部函数。C语言规定不同的源文件可以有同名的内部函数,并且互不干扰。

extern 就是声明这个一个外部函数

static  就是声明这是一个内部函数,只能在本文件中使用。

这两个参数是在返回值类型前加上。


一个外部函数引起的错误案例

就是直接用#include "文件名"包含.m文件。在直接调用这个.m文件中的函数。

编译器就会报错。

因为C语言中是不允许有同名的外部函数。这时候.m文件和本文件中都包含了这个调用函数。


2、 extern,static和变量

我们用extern来声明一个变量是全局变量

一是在函数内部

声明这个变量就是外部的全局变量

全局变量定义多少遍都行


二是在别的文件中

但是千万不能只声明不定义

extern int a;只是声明不是定义

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

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


我们用static来声明一个只在本文件使用的全局变量,其他文件不能访问这个变量。


三、typedef

这个关键字可以为各种数据类型定义一个新名字。也可以简化我们定义变量的方式。

比如结构体和枚举都是需要定义变量类型的。用了typedef就可以简化这一操作

1.使用场合:
 1> 基本数据类型

typedef int MyInt; // 就可以用MyInt来代替int。实现自定义变量类型名


 2> 指针

给指针类型char *起一个新的类型名称String
typedef char * String;


 3> 结构体

typedef struct
{
    int age;
} MyStu;  //用MyStu就可以代替结构体变量类型


 4> 枚举

typedef enum {
    Man,
    Woman
} MySex;  // 用MySex来代替枚举变量类型


 5> 指向函数的指针

typedef int (*MyPoint)(int, int);  //  MyPoint就是函数指针

MyPoint p = sum;


四、 递归

就是一环套着一环,套到终点再一起算账。


设计一个函数,用来计算b的n次方

int pow2(int b, int n)
{
    if (n <= 0) return 1;
    return pow2(b, n-1) * b;
}




————————Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ————————

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值