c语言的头文件、宏、指针

#include命令

#include是文件包含命令,主要用来引入对应的头文件。#include的处理过程很简单,就是将头文件的内容插入到该命令所在的位置,从而把头文件和当前源文件连接成一个源文件,这与复制粘贴的效果相同。

#include有两种使用方式:

#include <stdio.h>
#include "myHeader.h"

使用尖括号< >和双引号" "的区别在于头文件的搜索路径不同:包含标准库的头文件建议用尖括号,包含自定义的头文件建议用双引号

  • 一个#include命令只能包含一个头文件,多个头文件需要多个#include命令。
  • 文件包含允许嵌套,也就是说在一个被包含的文件中又可以包含另一个文件。

宏定义

#define  宏名  字符序列

#表示这是一条预处理命令,所有的预处理命令都以#开头。define是预处理命令。宏名是标识符的一种,命名规则和标识符相同。字符序列可以是常数、表达式等。

宏定义的几点说明

  • 宏定义是用宏名来表示一个字符串,在宏展开时又以该字符串取代宏名,这只是一种简单的替换。字符串中可以含任何字符,可以是常数,也可以是表达式,预处理程序对它不作任何检查,如有错误,只能在编译已被宏展开后的源程序时发现。
  • 宏定义不是说明或语句,在行末不必加分号,如加上分号则连分号也一起替换。
  • 宏定义必须写在函数之外,其作用域为宏定义命令起到源程序结束。如要终止其作用域可使用#undef命令。#define  A  123  #undef  A    A只在从定义到undef之间有效


宏定义表示数据类型和用typedef定义数据说明符的区别。

宏定义只是简单的字符串代换,是在预处理完成的,而typedef是在编译时处理的,它不是作简单的代换,而是对类型说明符重新命名。被命名的标识符具有类型定义说明的功能。

#define PIN1 int *
typedef int *PIN2;  //也可以写作typedef int (*PIN2);

从形式上看这两者相似, 但在实际使用中却不相同。
下面用PIN1,PIN2说明变量时就可以看出它们的区别:

PIN1 a,b;

在宏代换后变成:

int *a,b;

表示a是指向整型的指针变量,而b是整型变量。然而:

PIN2 a,b;

表示a、b都是指向整型的指针变量。因为PIN2是一个类型说明符。

由这个例子可见,宏定义虽然也可表示数据类型, 但毕竟是作字符代换。在使用时要分外小心,以避出错。http://c.biancheng.net/cpp/html/65.html

int a = 100;            a 是一个变量,用来存放整数,需要在前面加&来获得它的地址;

char str[20] = "abcdefg";         str 本身就表示字符串的首地址,不需要加&

printf("%#X, %#X\n", &a, str);    %#X表示以十六进制形式输出,并附带前缀0X


定义指针变量

定义指针变量与定义普通变量非常类似,不过要在变量名前面加星号*,格式为:

datatype *name;  或者  datatype *name = value;

*表示这是一个指针变量,datatype表示该指针变量所指向的数据的类型 。例如:

  int *p1;

p1 是一个指向 int 类型数据的指针变量,至于 p1 究竟指向哪一份数据,应该由赋予它的值决定。再如:

  int a = 100;

  int *p_a = &a;

在定义指针变量 p_a 的同时对它进行初始化,并将变量 a 的地址赋予它,此时 p_a 就指向了 a。值得注意的是,p_a 需要的一个地址,a 前面必须要加取地址符&,否则是不对的。

1 //定义普通变量
2 float a = 99.5, b = 10.6;
3 char c = '@', d = '#';
4 //定义指针变量
5 float *p1 = &a;
6 char *p2 = &c;
7 //修改指针变量的值
8 p1 = &b;
9 p2 = &d;

*是一个特殊符号,表明一个变量是指针变量,定义 p1、p2 时必须带*。而给 p1、p2 赋值时,因为已经知道了它是一个指针变量,就没必要多此一举再带上*,后边可以像使用普通变量一样来使用指针变量。

也就是说,定义指针变量时必须带*,给指针变量赋值时不能带*


指针变量也可以连续定义,如:int *a, *b, *c; //a、b、c 的类型都是 int*。

每个变量前面都要带*。如果写成int *a, b, c;,那么只有 a 是指针变量,b、c 都是类型为 int 的普通变量。


定义指针变量时的*和使用指针变量时的*意义完全不同。以下面的语句为例:

  1. int *p = &a;
  2. *p = 100;

第1行代码中*用来指明 p 是一个指针变量,第2行代码中*用来获取指针指向的数据。

需要注意的是,给指针变量本身赋值时不能加*。修改上面的语句:

  1. int *p;
  2. p = &a;
  3. *p = 100;

第2行代码中的 p 前面就不能加*

关于 * 和 & 的谜题

假设有一个 int 类型的变量 a,pa 是指向它的指针,那么*&a&*pa分别是什么意思呢?

*&a可以理解为*(&a)&a表示取变量 a 的地址(等价于 pa),*(&a)表示取这个地址上的数据(等价于 *pa),绕来绕去,又回到了原点,*&a仍然等价于 a。

&*pa可以理解为&(*pa)*pa表示取得 pa 指向的数据(等价于 a),&(*pa)表示数据的地址(等价于 &a),所以&*pa等价于 pa。

对星号*的总结

在我们目前所学到的语法中,星号*主要有三种用途:

  • 表示乘法,例如int a = 3, b = 5, c;  c = a * b;,这是最容易理解的。
  • 表示定义一个指针变量,以和普通变量区分开,例如int a = 100;  int *p = &a;
  • 表示获取指针指向的数据,是一种间接操作,例如int a, b, *p = &a;  *p = 100;  b = *p;

int aa = 97;

int bb = 98;

int *paa = &aa;

printf("%c\n",*paa);

*paa = 99;

printf("%c\n",paa);

paa = bb;

printf("%c\n",paa);

运行结果   a   c   b

猜你喜欢

转载自www.cnblogs.com/ren-hang/p/9979405.html
今日推荐