黑马程序员——C语言的关键字 typedef,static,extern和预处理指令

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

typedef

一、typedef的作用

给已经存在的数据类型起一个新的名字
定义格式:typedef 原有类型名  新名字;

二、使用场合

1.typedef与基本数据类型

例如:typedef int Myint;
     typedef Myint Myint2;  (在别名的基础上在起名)

2.typedef与指针

例如:typedef char * string;
string name = "jim"; (用string代替char *定义指针了)

3.typedef与结构体

例如:struct Student
              {
                  int age;
              }

typedef struct Student Mystu (将结构体类型Student起了一个新名字叫Mystu)
Mystu stu = {20}; (用新名字Mystu定义结构体变量并初始化)

//定义结构体类型,并且起一个新名字

typedef struct Student
              {
                int age;
              }Mystu;

这里写图片描述

注意:省略了结构体类型名称之后,就不能使用原来的名字定义结构体变量了,
而没有省略结构体名称的还可以使用struct Student stu2;定义新变量

4.typedef与指向结构体的指针
这里写图片描述

5.typedef与枚举类型
这里写图片描述

6.typedef与#define使用的区别
这里写图片描述

注意:s4是char类型,s1、s2、s3是指针类型,所以,以后给类型起别名,最好使用typedef,而不是使用#define

一、static和extern对函数的作用

1、extern对函数的作用:
1> 完整的定义一个外部函数
2> 完整的声明一个外部函数

外部函数特点:定义的函数能被本文件和其他文件访问,默认情况下所有函数都是外部函数,不允许有同名的外部函数。

2、static对函数的作用
1> 定义一个内部函数
2> 声明一个内部函数

内部函数特点:定义的函数只能被本文件访问,其他文件不能访问,允许不同文件中有同名的内部函数。

二、static和extern对全局变量的作用

1、 extern对全局变量的作用:
声明一个外部变量
特点:定义的变量能被本文件和其他文件访问。默认情况下,所有的全局变量都是外部变量,不同文件中的同名外部变量,都代表着同一个变量。

2、static对全局变量的作用
定义一个内部变量
特点:定义的变量只能被本文件访问,不能被其他文件访问。不同文件中的同名内部变量,互不影响。

3、static修饰局部变量:
1>、延长局部变量的生命周期:程序结束的时候,局部变量才会被销毁
2>、并没有改变局部变量的作用域
3>、static修饰局部变量的使用场合:用一个习题来说明

               #include <stdio.h>
                void test()
                {
                  int a = 0;

                  a++;
                  printf("a的值是%d\n",a);
                  static int b = 0;

                  b++;

                  printf("b的值是%d\n",b);
                }
                int main()
                {
                   test();
                   test();
                   test();
                   return 0;
                }

这里写图片描述

四、预处理指令

一、预处理指令简介
1.C语言在对源程序进行编译之前,会先对一些特殊的预处理指令作解释(比如之前使用的#include文件包含指令),
产生一个新源程序(这个过程称为编译预处理),之后再进行通常的编译 ->[俗称将代码翻译成0和1之前所执行的指令]

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

3.预处理指令可以出现在程序的任何位置,它的作用范围是从它出现的位置到文件尾。
习惯上我们尽可能将预处理指令写在源程序开头,这种情况下,它的作用范围就是整个源程序文件

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

预处理指令——宏定义
1.不带参数的宏定义
1>.一般形式

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

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

3>.预处理的使用习惯与注意

1)预处理的位置是可以随便写的
2)预处理指令的作用域:从编写指令的那一行开始,一直到文件结尾
3) 对程序中用双引号扩起来的字符串内的字符,不进行宏的替换操作
4) 在编译预处理用字符串替换宏名时,不作语法检查,只是简单的字符串替换。只有在编译的时候才对已经展开宏名的源程序进行语法检查。
5)宏名一般都用大写开头,变量名一般用小写
6)宏的结尾可用 #undef 命令

4>举例说明

               #include <stdio.h>
               #define COUNT 4
               int main()
               {
                  char *name = "COUNT";

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

                  int ages[COUNT] = {1,2,3,4};

                  for (int i = 0; i < COUNT; i++){

                  printf("%d\n",ages[i]);
                 }
                    return 0;
                }

这里写图片描述

结果分析

虽然前面已经通过宏定义,将程序中所有COUNT替换成4,但是双引号里面的字符串内容是不进行替换操作的,
所以输出的还是原来的值,另外数组名ages后面所跟中括号里面的内容本来是不能有变量的,但是通过宏定义后,
就可以用一个变量来替换原先的常量。

2.带参数的宏定义

1>. 一般形式

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

2>.作用

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

3>.习题分析

             #include <stdio.h>
             #define sum(v1,v2) ((v1)+(v2))
             #define pingfang(a) ((a)*(a))

              int main()
              {
                int c = pingfang(5+5)/pingfang(2); 

                int d = sum(3,4);

                printf("c is %d\n",c);

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

                return 0;
              }

这里写图片描述

分析总结
带参数的宏在展开时,只作简单的字符和参数的替换,不进行任何计算操作。所以在定义宏时,一般用一个小括号括住字符串的参数,以免导致计算结果不是我们想要的结果。

预处理指令——条件编译

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

定义格式:

#if 条件1
    内容1 
#elif 条件2
    内容2
#else
    内容3
#endif

分析说明:
1>如果条件1成立,那么编译器就会把#if与 #elif之间的内容1代码编译进去

2>如果条件1不成立、条件2成立,那么编译器就会把#elif与 #else之间的内容2代码编译进

3>如果条件1、2都不成立,那么编译器就会把#else与 #endif之间的内容3代码编译进去

4>注意,条件编译结束后,要在最后面加一个#endif,不然后果很严重

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

预处理指令——文件包含

1.基本概念
其实我们早就有接触文件包含这个指令了,就是#include,它可以将一个文件的全部内容拷贝另一个文件中。

2.一般形式

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值