14th day

P320 课程介绍与知识点回顾14

 1. 指向函数的指针.    

    1). 我们可以定义1个指针指向1个函数.

        来使用这个指针间接的调用这个函数.

    2). 指向函数的指针的声明

        a. 拷贝函数头,去掉函数名 用小括号代替 里面写上 *指针名.

    3). 初始化

        函数名就代表函数的地址

        直接将函数名赋值给指针

    4). 使用.

        a. pFun();

        b. (*pFunc)();

 2. 结构体.

    1). 作用: 可以让程序员新创建1个数据类型. 这个数据类型的变量是由多个其他普通类型的小变量联合而成的.

    2). 使用场景: 当我们要存储1个数据的时候,发现这个数据是由多个其他的小数据组合起来的

    3). 使用结构体来创建1个新的数据类型.

struct 新类型名称
{
    成员;
};

    4). 声明结构体类型的变量.

struct 新类型名称 变量名;

    5). 初始化.

        a. 使用点 .

        b.

    -------

    值传递.

 3. 枚举

    1).可以让程序员新创建1个数据类型. 这个数据类型的变量的取值被限定.

    2).使用场景: 如果1个变量的取值要被限定.

    3).如何使用枚举来新创建1个类型.

enum 新类型
{
    枚举值1,枚举值2....
};

    4).声明变量.

 enum 新类型 变量名;

    5). 初始化

        变量中只能存储枚举类型中写好的枚举值之一.

    --------

    a. 每1个枚举值都有1个对应的整型的数 默认从0开始 依次的递增

4. typedef .

    1). 将1个已经存在的数据类型取1个别名.     

    2).枚举,结构体的定义简化~

P321 预处理指令概述

 1. 预处理指令的特点

    1). 都是以#开头.

    2). 预处理指令都是在编译之前执行.

    3). 预处理指令后面都没有分号.

 2. C程序从编写到编译、链接、执行的一个流程.

    1). 新创建1个.c的源文件.  .c的文件是C程序的源文件.

    2). 在.c的源文件中写上符合C语法规范的源代码.

        a. C语言严格区分大小写.

        b. 除了字符串常量, 其他的地方必须使用英文输入法.

    3). 使用cc -c 指令去编译源文件

        格式: cc - c 源文件名称

        编译做的事情.

        a. 先执行源文件中的预处理指令.

           如果有文件包含指令,就将文件的内容拷贝到写指令的地方.

           ....

        b. 检查.c文件中的语法是否符合规范.

           b.1 如果符合: 生成.o目标文件. 就是.c文件对应的二进制指令.

           b.2 如果不符合语法规范. 就报错. 不会生成.o的目标文件.

     4). 链接

         cc xx.o

         a. 为.o的目标文件添加启动代码.

         b. 链接函数. 告诉编译器,要调用的函数在什么地方.

            调用的时候,去正确的地方找实现.

         c. 链接成功以后. 就会生成1个可执行文件.

            这个文件就是我们程序了.

      .c源文件:  132字节.

 3. 预处理指令的分类.

    1). 文件包含指令  #include

    2). 宏定义: 可以将1段C代码定义为1个标识,使用这个标识就可以使用这段代码.

    3). 条件编译指令: 只编译指定的C代码为二进制指令.

P32203宏定义的基本使用

 1. 宏定义.

     1). 它是1个预处理指令.所以它在编译之前执行.

     2). 作用: 可以为1段C代码定义1个标识.如果你要使用这d段C代码.那么你就使用这个标识就可以了.

     3). 语法:

        #define 宏名 宏值        

#define N 10

     4). 如何使用宏.

         在C代码中.直接使用宏的名称就可以了.

          int a = N + 1;

     5). 宏的原理

         在预编译的时候,就会执行源文件中的预处理指令.

         会将C代码中使用宏名的地方替换为宏值.

         将C代码中的宏名替换为宏值的过程叫做  宏替换/宏代换.

P323 无参数的宏的使用

 2. 在使用宏的时候需要注意的地方.

    1). 宏值可以是任意的东西.

        在定义宏的时候,并不会去检查语法.

    2). 无论宏值是什么东西,在定义宏的时候,不会去检查语法

        只有当完成了宏替换的时候,才会去检查替换以后,是否符合语法规范.

    3). 如果宏值是1个表达式,那么宏值并不是这个表达式的结果,而是这个表达式本身.

    4). 如果宏值中包括1个变量名,那么在使用这个宏之前必须要保证这个变量已经存在.

 

    5). 无法通过赋值符号为宏 改值. 因为宏根本就不是变量.

        Expression is not assignable:表达式是不可赋值的.

    6). 宏的作用域.

        a. 宏可以定义在函数的内部 也可以定义在函数的外部.

        b. 从定义宏的地方,后面的所有的地方都可以直接使用这个宏.

           就算这个宏定义在这个大括号里面, 在这个后面 哪怕是大括号外面都可以访问.

        c. 默认情况下,宏从定义的地方一直到文件结束都可以使用.

           #undef 宏名

           可以让指定的红提前失效.

   7). 字符串中如果出现了宏名,系统不会认为这是1个宏,而认为是字符串的一部分.

         字符串中并不会出现宏替换.

     8). 宏的层层替换.

         宏值当中我们用到了另外1个宏名. 那么就会先将这个宏值当中的宏名替换为对应的宏值.

     9). 如果后面跟了分号.那么就会吧分号作为宏值的一部分

         替换的时候会连分号一起.

        虽然可以,但是不建议你加分号.

宏可以替代任意代码(演示):

 

 3. #define  和  typedef 的区别

    1).  #define是1个预处理指令.在预编译的时候执行. 在预编译的时候会吧宏名换成宏值.

         typedef 是1个C代码. 在运行的时候才会执行.

    2).  #define 可以将任意的C代码取1个标识名.

        typedef只能为数据类型取名字.

P324 带参数的宏

 1. 我们在定义宏的时候,宏名是可以带参数的.

    在这个宏值当中.可以直接使用这个参数

a是参数。调用的时候要给a赋值。  

 2. 如果使用的宏有参数,那么就必须要在使用它的时候为这个宏的参数传值.

 3. 宏代换的原理是什么?

    1). 先将传入的值传递给宏的参数,那么宏的参数的值就是我们传递的值.

    2). 再把宏值当中使用参数的地方换成参数的值.

    3). 最后,再将使用宏名的地方,替换为最后的宏值.

 4. 使用带参数几点注意

    1). 宏不是函数,所以宏的参数不需要加类型说明符. 直接写参数名就可以了.

    2). 我们在定义宏的时候,编译器是如何区分宏名和宏值.

        #define 空格 宏名  空格.

        第1个空格和第2个空格之间的内容会作为宏名

        第2个空格以后的内容会作为宏值.

        所以.在写宏的时候,空格要小心了.

 

     3). 为带参数的宏传值的时候,是本色传递.

        如果传递1个变量,并不是传递这个变的值

        而是直接传递的就是这个变量的串.

 5. 宏一定程度上可以实现和函数一样的效果.

    1). 宏值一旦换行,就任何宏定义结束了. 所以你打算使用宏去替换函数的话,那么些的很恶心.

    2). 只有当函数的代码很少的时候,只有几句的时候,就可以使用宏.

    3). 代码多的情况下,还是建议使用函数.

P325 条件编译指令的用法

  1. 条件编译指令.

     1). 它是1个预处理指令. 所以在预编译阶段执行.

     2). 作用:

        默认的情况下,我们所有的C代码都会被编译为二进制代码.

        条件编译指令的作用: 可以让编译器只编译指定部分的代码.

 2. 条件编译指令的第一种用法.

#if 条件
    C代码;
#endif

    在预编译的时候,如果条件成立. 就会将其中的C代码编译成二进制指令.

 如果条件不成立.就不会将其中的C代码编译成二进制指令.

  注意: 条件只能是宏 不能是变量.

 

 条件是变量是无效的。

 3. 条件编译指令的第二种用法

#if 条件
    C代码;
#elif 条件
    C代码
#elif 条件
    C代码
#else
    C代码
#endif

 

 4. 条件编译指令和if语句的1个对比

    1).条件编译指令是1个预处理指令.在预处理阶段执行.

       if语句是C代码. 在程序运行的时候执行.

    2). if语句无论如何全部都要被编译为二进制指令.

        条件编译指令: 只会讲符合条件的C代码编译为二进制指令.

    3). 实际上.if语句一定程度上可以换成条件编译指令.

        但是.条件编译指令的条件不能是变量参与.只能是宏.

P326 07使用条件编译指令来将输出语句替换

 5. 条件编译指令的第三种用法.

    #ifdef 宏名

        C代码;

    #endif

     如果定义了指定的宏.就编译其中的代码否则就算了.

     如果没有定义指定的宏.就编译其中的代码否则就算了

#ifndef 宏名
    C代码
#endif

应用实例:

 

 P327 08使用条件编译指令防止同1个文件被重复包含

 1. 实现的效果.

    无论1个文件被#include多少次.我只希望他最终只会被包含1次.

 

 2. 解决方案.

#ifndef 宏名
#define 宏名
    代码;
#endif

P328 09 static和extern修饰局部变量

 1. static、extern 是用来修饰变量和函数的.

 2. 修饰局部变量

 

    1). 被static修饰的变量 我们叫做静态变量.

        静态变量是声明在常量区中的.

        静态变量在程序一启动的时候,就已经声明在常量区中.

        当我们执行函数的时候.不会再去执行声明静态变量的那句话.直接就略过.

        并且函数执行完毕之后,静态变量也不会被回收. 直到程序结束的时候才会被回收.

        无论函数执行多少次.静态变量只会有1个.

    2). 与全局变量的区别.

        全局变量可以在所有的函数里面访问.而静态变量只能在定义静态变量的函数中访问.

    3). 什么时候需要将变量定义为静态的呢?

        a. 特点和作用.

           无论函数执行多少次.这个静态变量都只有1份. N次函数共享.

        b. 当你有1个数据.你希望无论函数执行多少次 这个数据只有1份.

        实际上,如果要实现这个效果,也可以直接将这个数据定义成全局变量.

        但是全局变量是被所有的函数共享. 所有的函数都能访问

        而静态变量的特点. 只能在当前函数中访问 并且多次执行只有1个.

   4). extern不能修饰局部变量.

'extern' variable cannot have an initializer    extern不能修饰有初始值的变量。。。

P329 10 static和extern修饰全局变量

  1. 创建1个函数的完整步骤.

    a. 写函数的声明

    b. 在写函数的实现.

 

  2. 创建1个全局变量的完整步骤.

    a. 先写全局变量的声明.

       只声明1个全局变量,不去初始化.这个叫做全局变量的声明.

int num;

    b. 写全局变量的实现.

        声明这个全局变量.为其赋值.

int num = 10;

    这个时候,全局变量的声明可以放在使用全局变量的前面,全局变量的实现可以放在使用全局变量的后面.

    注意:

    a. 全局变量可以只有声明没有实现. 这个时候这个全局变量就会默认实现为0.

    b. 全局变量也可以只有实现没有声明. 但是这个时候这个全局变量的实现必须要放在使用全局变量的前面.

 3. 如果在模块中要声明全局变量.

    1). 这个全局变量就要分为声明和实现.

        声明写在.h  文件中.

        实现写在.c  文件中.

    2). 全局变量分为两种.

        a. 内部全局变量.

           使用static修饰的全局变量.叫做内部全局变量.

           这个全局变量就只能在当前模块中访问.

           如果是跨模块访问就无法正确访问.

 

        b. 外部全局变量.

            使用extern修饰的全局变量.我们叫做外部全局变量.

            这个全局变量就可以在外部的模块中访问.

 

 

 4. 关于全局变量.

    1). 在模块中定义全局变量.

        声明写在.h中

        实现写在.c中.

        写在模块中的全局变量.必须要使用static或者extern

    2). 如果使用extern 那么这个模块中的全局变量.就可以在外部访问.

    3). 如果使用static 那么这个模块中的全局变量.就不能在外部正常访问.

P330 11 static和extern修饰函数

 5. static和extern修饰函数

    extern 修饰的函数.在不包含模块的头文件的情况下,都可以调用.

     static 修饰的函数.就算包含了头文件. 也不能跨模块调用.

小总结: 

 1. 全局变量

    1). 如果要在模块中声明全局变量的

        .h 写全局变量的声明.

        .c 写全局变量的实现.

    2). 声明在模块中全局变量.必须要使用extern 或者 static 修饰.

        否则 包含编译 就会报错.

    3). 模块中的全局变量如果使用extern修饰,那么这个模块中全局变量就可以在其他模块中访问.

        模块中的全局变量如果使用static修饰,那么这个模块中全局变量就不能在别的模块中正常访问.

    4). 如果头文件中全局变量的声明我们使用的是static.那么.c实现文件中也必须要使用static

        如果头文件中全局变量的声明我们使用的是extern 那么.c实现文件中就可以不使用extern了.

 2. 修饰函数.

    1). 被static修饰的函数,只能在这个模块的内部调用,无法跨模块调用.

    2). 被extern修饰的函数,可以跨模块调用.

    3). 函数如果没有写static或者extern那么默认就是extern 外部的.

P33112模块开发实战

 1. main函数的参数,可以写也可以不写.不会有太大的影响. 2. 根据最新的C标准. C语言的main函数要返回1个int类型的数据.

    main函数是系统在调用.

    系统日志: 可以查看系统中某个程序的运行时间,结束的时间.如何结束的.

    main函数的返回值代表这个程序是如何结束的.

    0 代表正常结束.

    非0代表非正常结束. 这个时候系统就会额外的多做1些事情.

    main函数如果不写返回值.默认就是返回0.

 3. main函数的参数

    1). int argc 代表后面那个字符串数组的长度.

    2). const char * argv[]. 是1个数组.

        这个数组的第0个元素代表: 代表这个程序的路径.

       /Users/Itcast/Library/Developer/Xcode/DerivedData/Day14-预处理指令-dotynutpblhquqclujeicyjqtfhx/Build/Products/Debug/11-main函数的返回值和参数

    3). 将数据传递到函数内部使用的方式.

        a. scanf函数.

        b. 就是执行程序的时候.在终端执行程序的时候,可以将要传入的数据以参数的形式写在程序名后面.

           ./a.out xxx yyy jjj 

          这个时候,通过参数argv数组就可以拿到通过这种方式传入的数据.

    4). main函数的参数. 特别是那个字符串数组.

 '       第0个元素的值 是当前程序的路径.

        允许运行程序的时候.由用户在终端传入数据.终端传入的数据可以通过数组拿到.

 -------

 1. 我们在Xcode中写的程序.按下运行按钮.

    自动的编译 链接 成1个可执行文件.

 2. 我们可以找到这个可执行文件,将他单独的在终端运行.

 3. 在终端中运行程序的时候.可以给这个程序传递一些数据.

    程序名称 数据1 数据2 数据3.....

 4. 在程序内部 如何拿到从终端中拿过来的数据?

    就是通过参数数组 argv 拿到.

    第0个元素代表当前这个程序的路径.

    从第1开始.每1个元素的值就是 在终端中传入的数据.

 5. 如果你希望某个变量的值不是在写代码的时候写死.

    而是程序运行的时候,由用户输入.

   1). scanf

    2). 使用终端传数据.

P332 13知识点补充

 1. 总结数据类型.

    1). 基本数据类型.

        int

        double

        float

        char

    2). 构造类型.  构建创造.  

        数组.

        结构体.

        枚举.

    3). 指针.

    4). void 空类型.

    5). typedef 定义类型.

        typedef int itheima;

 2. IF结构.

    1). 如果if块中只有1句代码,那么大括号可以省略.

 

    2). 如果if块后面没有大括号.你记住,只有第1句代码才是属于这个if块的.

     3). 如果if块中只有1个语法块,那么这个时候if的大括号也能省略.

 

 3. for循环也是一样的.

 

 4. 忠告.    

     1) 虽然有时候,可以省略if或者循环大括号,但是我不建议你省略,因为这样的可读性很低.

    2).就算你要省略,那么最好也是Tab缩进.

 

P333 14 大总结

 Day01

  1. OS X

  2. 终端的使用.

  3. C语言.

 Day02

  1. Xcode的使用

  2. 数据的处理.

  3. 程序的运行模式.

  4. 数据类型

  5. 变量.

  6. printf函数

 Day03-表达式

  1. scanf

  2. 算术表达式.

  3. 复合赋值运算符

  4. 自增和自减

  5. 逗号表达式

  6. 比较运算

 Day04 流程控制

  1. 逻辑运算

  2. IF结构

  3. 变量的作用域

  4. IF-ELSE

  5. IF_ELSEIF/. 

  6. 三元表达式

  7. 产生随机数

 Day05. 循环

  1. switch-case

  2. 程序的调试

  3. while循环

  4. 6种应用.

 Day06-循环

  1. 复习.

  2. do-while

  3. for

  4. 嵌套循环.

 Day07-函数

  1. 无参数无返回值的函数

  2. 带参数的函数

  3. return

  4. 带返回值的函数

  5. 函数的声明和实现

 Day08-进制

  1. 文本包含指令.

  2. 多文件开发

  3. 进制.

          比较少用.

 Day09-数组

  1. 数组的基本使用.

  2. 数组在内存中的存储.

  3. 数组与函数.

  4. 常用算法.

     排序.

     查找.

     翻转

   C语言的数组在后面几乎不会用.

 Day10-字符串

  1. 二维数组

  2. 字符串.

 C语言的字符串在后面几乎不会用.

 Day11-指针

  1.  使用

  p

  *p

  2. 指针的应用.

  3. 多级指针.

  4. 为什么要分类型.

  5.  + - 

   Day12-指针

   1. 指针与字符串.

   2. 迷宫

 一级指针指向结构体.

 Day13- 结构体枚举.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值