C 笔记_1

来源:互联网 发布:怎样提高淘宝店铺浏览量 编辑:程序博客网 时间:2024/05/22 12:39

 
1。前菜:
extern int f(); 和 int f();
没有什么正是的区别,除了前者在格式上暗示了,f()函数被定义在其他的文件中。

2。正体:
 typedef struct {
   char *item;
   NODEPTR next;
 } *NODEPTR;
  上面的代码,编译时会出错,但原因并不是C语言不允许在结构中包含指向它自己的指针。
新结构建立的过程中遇到了next域的声明,类型是NODEPTR,要知道next表示的是类型的新名字,那么在类型本身还没有建立完成的时候,这个类型的新名字也还不存在,也就是说这个时候编译器根本不认识NODEPTR。

于是,偶们可以这样解决:
  typedef struct tagNode {
    char *item;
    struct tagNode *next;
  } *NODEPTR;

标准点的写法是:
 struct tagNode {
   char *item;
   struct tagNode *next;
 };

 typedef struct tagNode *NODEPTR;

3。展开:
   typedef在C程序中无处不在,作为C语言的关键字,作用是为一种数据类型定义一个新名字。
   比如:
   [数组]
   /* 将DataType定义为int型,便于扩充 */
   typedef int DataType;
  
   /* 定义一个一维数组,数组的元素为整型值,n为元素的个数 */
   typedef DataType ARR1[n];

   /* 再定义一个一维数组,数组的元素为ARR1型,
    * 可知 ARR2 实际上是一个矩阵 */
   typedef ARR1 ARR2[n];  /* 此处完全等价为typedef int ARR2[n][n]; */

   /* 同上可以定义一个三维数组:ARR3 */
   typedef ARR2 ARR3[n];  /* 此处完全等价为typedef int ARR3[n][n][n]; */

   使用的时候,只要
   ARR1 a;
   ARR2 b;
   ARR3 c;
 
   [结构体]
   typedef struct _TS1{
     int x, y;
   } TS1, *PTS1, **PPTS1; 
   /* 也就是将结构体struct _TS1 命名为TS1, 
    * 将struct _TS1 * 命名为 PTS1,    
    * 将struct _TS1 ** 命名为 PPTS1  */
   当然可以可以将struct后面的说明去掉

   同样的代码可以写成下面的样子:
   typedef struct {
     int x, y;
   } TS1;

   typedef TS1 *PTS1;   // 定义PTS1是指向TS1的指针
   typedef PTS1 *PPTS1; // 定义PPTS1是指向PTS1的指针

   使用的话:
    TS1 ts1 = {100, 200};
    PTS1 pts1 = &ts1;    // 完全等价于TS1* pts1 = &ts1;
    PPTS1 ppts1 = &pts1; // 完全等价于TS1** ppts1 = &pts1;

   [函数]
   在typedef的使用中,最麻烦的是指向函数的指针。
   typedef int (*FP_CALC)(int, int);
   /* 定义一个函数calc_func,它有一个char型参数,
    * 它将返回一个指向相应函数的指针,指向的函数将有两个int型参数,
    * 并返回一个int型的值 */
   FP_CALC calc_func(char op);

   使用的时候:
   FP_CALC fp = calc_func(op);
   fp(a,b);

   如果,不用typedef的话,就要如下的操作了
   int (*s_calc_func(char op))(int, int);

   使用的时候:
   int (*s_fp)(int, int) = s_calc_func(op);
   s_fp(a,b);     /* 理解上难了很多 */

4。收尾:
   typedef的作用:
   1,使程序简单,typedef命名好的话,光看类型名字就能知道,这个类型是来干啥的。
   2,typedef值去定义变量时,可以不用把精力放在判断结构是数组还是结构体,或是函数上。