c语言程序结构

1.全局变量

  定义在函数外部的变量叫做全局变量

  全局变量具有全局的生存周期,作用域从声明他开始到末尾

  没有初始化的全局变量会得到0值,指针会得到NULL值(本地变量不会给初值,保存的是内存中原有的值)

  全局变量的初始化只能用编译时已知的值来初始化(只有常数,和常量const(不建议) 可以用来给它赋值

  如果函数内部存在和全局变量同名的本地变量,全局变量会被隐藏

2.静态本地变量  static 关键字  

  用static修饰的本地变量是静态本地变量(也可以修饰全局变量,加了之后表示只能在该c文件中使用,同一个项目下的其他c文件不能共享)

  当函数执行结束离开时,函数内部的静态本地变量会继续保持其值

  静态本地变量的初始化只会在第一次进入这个函数的时候做,以后进入这个函数的时候会保持上次离开的值

  void fun(){

    static int x=10;      //只做一次

    x++;            //每次调用都执行,因此调用n次之后x值时10+n而不是11

  }

  静态本地变量的本质是全局变量,它和全局变量保存在相同的内存区域中,static关键字实质只是限制这个全局变量的范围为这个函数内

3.返回指针的函数

  返回本地变量的指针是危险的,因为一旦函数结束,这块地址就相当于回收了,这个地址可能之后会被分配给其他变量

  返回全局、静态本地变量、malloc的地址是安全的,最好的做法是返回传入的指针

4.使用全局变量tips

  不要使用全局变量来在函数间传递参数或者作为返回结果

  尽量避免使用全局变量

  全局变量和静态本地变量对于多线程的环境是不安全的

5.编译预处理指令和宏

  #开头的是编译预处理指令,他们不是C语言的部分,但是C语言离不开他们

  #define  用来定义一个宏(c99以前没有const,只能用define来定义常量)

    例:#define PI 3.1415   在编译器预处理的时候,会把程序中所有的PI换成3.1415

  编译预处理

    .c->.i->.s->.o->可执行文件

    其中.c是源文件,.i是编译预处理后的文件,.s是汇编程序,.o是目标文件

  可以用宏来定义宏

    例如:#define PI2 2*PI

  一行宏的定义没结束可以在末尾加一个反斜杠\

  除了可以定义有值的宏,还可以定义没有值的宏,这类宏是用于条件编译的

  预定义宏:

    _LINE_  源代码当前的行号  

    _FILE_  源代码文件的文件名

    _DATE_   编译时候的日期

    _TIME_  编译时候的时间

 

6.带参数的宏

  像函数一样的宏

    例如 #define cube(x) x*x*x  

      之后在程序中 cube(5) 会表示5*5*5

  错误定义的宏

    #define RADTODEG(x) (x*57.29578)  //printf("%f\n",RADTODEG(5+2))表示printf("%f\n",(5+2*57.29578)  //从而导致2先乘以57.29578

    #define RADTODEG(x) (x)*57.29578  //printf("%f\n",180/RADTODEG(1))表示printf("%f\n",180/(1)*57.29578)    //导致180先/1

  带参数宏的原则:一切都要有括号

    a.整个值要有括号

    b.参数出现的每个地方都要有括号

      #define RADTODEG(x) ((x)*57.29578)  //正确

  宏可以带多个参数

    #define MIN(a,b) ((a)>(b)?(b):(a))

  宏可以嵌套组合使用其他宏

  宏后面不要加分号

  带参数的宏在大型程序代码中使用非常普遍,可以非常复杂,例如产生函数

7.大程序结构

  main函数里面内容太多可以写到新的函数里面

  源文件太大可以分为多个源文件,但是需要解决多个源文件不能编译成可执行文件的问题

  解决方案:在dev-c++中新建一个项目,然后将这多个源文件加入进去,dev-c++会将所有源文件编译之后链接起来(有的IDE会先分开编译,再对整个项目做链接)

 

8.头文件

  把函数原型放到头文件(以.h结尾的文件)中,在需要调用这个函数的源代码文件(.c文件)中#include这个头文件,就能让编译器在编译的时候知道函数原型

  在自定义函数的源文件中也要#include这个函数的头文件

  #include是一个编译预处理指令,在编译之前就处理了,它将会把被include的的文件的全部内容原封不动的插入到它所在的地方

 

9.两种#include

  #include"" 要求编译器首先在当前.c文件所在目录下寻找这个文件,如果没有,就到编译器指定目录中去寻找

  #include<>让编译器只在指定目录去找

  编译器自己知道自己的标准库的头文件在哪(windows下一边在ide的某个include目录下)

  

  注意:#include 不是用来引入库的,真正的函数原型可能在某个.lib文件中,#include只是为了让编译器知道printf函数的原型,保证调用时参数类型匹配

10.变量的声明

  在头文件中 :extern 变量类型 变量名      //声明一个变量,这个变量可以在这个项目下的所有.c文件中使用,前提是.c文件中有#include这个.h文件

    注意声明的时候是不能初始化的

  在C中,声明是不会产生代码的东西,具体有

    函数原型

    变量声明

    结构声明

    宏声明

    枚举声明

    类型声明  

    inline函数

  而定义是会产生代码的东西

  .h中声明常常用到一下东西,称为标准头文件结构

#ifndef _MAX_H_    //_MAX_H_ 表示max.h头文件
#define _MAX_H_




#endif

  避免调用重复的声明从而产生的编译错误

posted @ 2020-09-04 00:25  9761滴  阅读(228)  评论(0编辑  收藏  举报