黑马程序员——C语言知识点总结之预处理指令和typedef关键字

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

预处理指令

1、C语言在对源程序进行编译之前,会先对一些特殊的预处理指令作解释(比如之前使用的#include文件包含指令),产生一个新的源程序(这个过程称为编译预处理),之后再进行通常的编译

2、为了区分预处理指令和一般的C语句,所有预处理指令都以符号”#”开头,并且结尾不用分号

3、宏名一般用大写或者以k开头,变量名一般用小写

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

宏定义

一般分为不带参数的宏定义和带参数的宏定义

不带参数的宏定义

1、一般形式

#define 宏名 字符串
例:#define ABC 10

右边的字符串也可以省略,比如#define ABC

2、作用

它的作用是在编译预处理时,将源程序中所有”宏名”替换成右边的”字符串”,常用来定义常量。

例:

#include <stdio.h>
#define Count 4

int main()
{
    int ages[Count] = {1, 2, 67, 89};
    for ( int i = 0; i<Count; i++) 
    {
        printf("%d\n", ages[i]);
    }
    return 0;
}

输出结果:
1
2
67
89

3、作用域
预处理指令可以出现在程序的任何位置
预处理指令的作用域:从编写指令的那一行开始,一直到文件结尾,可以用#undef取消宏定义的作用
例:

#include <stdio.h>
#define Count 4

int main()
{
    int ages[Count] = {1, 2, 67, 89};
    for ( int i = 0; i<Count; i++) 
    {
        printf("%d\n", ages[i]);
    }

    #undef Count; // 从此行开始取消宏定义的作用
    return 0;
}

带参数的宏定义

1、定义格式:
#define 宏名(参数列表) 字符串
#define sum(v1, v2) ((v1)+(v2))

2、使用注意—括号
例:定义平方的时候不加括号

#include <stdio.h>
#define pingfang(a) a*a // 未加括号

int main()
{
    int c = pingfang(5+5); // c = 5+5*5+5 = 35
    printf("c is %d\n", c);
    return 0;
}

输出结果:
c is 35

#include <stdio.h>
#define pingfang(a) ((a)*(a)) // 加括号

int main()
{
    int c = pingfang(5+5); // c = (5+5)*(5+5) = 100
    printf("c is %d\n", c);
    return 0;
}

输出结果:
c is 100

3、带参数的宏定义与函数的区别

1> 宏定义不涉及存储空间的分配、参数类型匹配、参数传递、返回值问题

2> 函数调用在程序运行时执行,而宏替换只在编译预处理阶段进行,所以带参数的宏比函数具有更高的执行效率

条件编译

只有当程序的其中一部分代码在满足一定条件时才进行编译,否则不参与编译(只有参与编译的代码最终才能被执行)

基本用法

// 条件是对宏定义进行判断
#if 条件1
  ...code1... // 如果条件1成立,就把code1代码编译进去
#elif 条件2
  ...code2... // 如果条件2成立,就把code2代码编译进去
#else
  ...code3... // 如果条件3成立,就把code3代码编译进去
#endif        // #endif不能少

例:

#include <stdio.h>
#define A 5

int main()
{
    #if (A == 10)
        printf("a是10\n");
    #elif (A == 5)
        printf("a是5\n");
    #else
        printf("a其他值\n");
    #endif
    return 0;
}

运行结果:
a是5

if defined()和#if !defined()

判断是否定义过某个宏

例:

// 如果定义了宏A,编译code1
#if defined(A)
    ...code1...
#endif

// 如果没有定义宏A,编译code2
#if !defined(A)
    ...code2...
#endif

ifdef()和#ifndef()

#ifdef的使用和#if defined()的用法基本一致

// 如果定义了宏A,编译code1
#ifdef A 
    ...code1...
#endif

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

// 如果没有定义宏A,编译code2
#ifndef A
    ...code2...
#endif

文件包含

一般形式

1、第1种形式
#include <文件名>
直接到C语言库函数头文件所在的目录中寻找文件

2、第2种形式
#include “文件名”
系统会先在源程序当前目录下寻找,若找不到,再到操作系统的path路径中查找,最后才到C语言库函数头文件所在目录中查找

< >表示系统自带的文件,” “表示自定义的文件

使用注意

#include指令允许嵌套包含,比如a.h包含b.h,b.h包含c.h,但是不允许递归包含,比如 a.h 包含 b.h,b.h 包含 a.h

关键字typedef

作用:给已经存在的类型起一个新的名称

使用场合

基本数据类型

例:

#include <stdio.h>
typedef int MyInt; // 给int起了个别名Myint
int main() 
{
     MyInt a = -10;
     printf("%d", a);
     return 0;
}

指针

#include <stdio.h>
// 给指针类型char *起一个新的类型名称String
typedef char * String;
int main()
{
    String str = "This is a string!";
    printf("%s", str);
    return 0;
}

运行结果:
This is a string!

注意:“*”不能少

结构体

1、方式1

struct Student
{
    int age;
};
typedef struct Student MyStu;

2、方式2

typedef  struct Student
{
    int age;
} MyStu;

枚举

1、方式1

enum Sex {Man, Woman};
typedef enum Sex MySex;

2、方式2

typedef enum {
    Man,
    Woman
} MySex;

指向函数的指针

#include <stdio.h>
typedef int (*MyPoint)(int, int);
int minus(int a, int b)
{
    return a - b;
}
int sum(int a, int b)
{
    return a + b;
}

int main()
{
    // 定义一个指向函数sum的指针p
    MyPoint p = sum;
    // 定义一个指向函数minus的指针p2
    MyPoint p2 = minus;
    // 利用指针变量p调用sum函数
    int a = (*p)(4, 5);
    int b = (*p)(10, 3);
    printf("%d,%d",a,b);
    return 0;
}

运行结果:
9,7

typedef与#define

例:

typedef char *String1;
String1 str1, str2;
/* 
经过typedef处理后,String1也算是一种数据类型,所以第3行代码相当于:
String1 str1;
String1 str2;

由于String1就是char *,所以上面的两行代码等于:
char *str1;
char *str2;
*/

#define String2 char *
String2 str3, str4;
/*
因为宏定义纯粹是字符串替换,用char *代替String2,所以相当于:
char * str3, str4;

其实也就相当于:
char * str3;
char str4;
*/

可以看出,只有str4是基本数据类型,str1、str2、str3都是指针类型。

所以,以后给类型起别名,最好使用typedef,而不是使用#define

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值