预处理与初级指针

目录

预处理过程:

预处理流程:

编译过程:

1.预处理

2.编译

3.汇编:

4.链接:

宏定义:

4.宏名的作用域:从定义那行到代码下面全部(宏和宏之间可以嵌套使用,不分定义的前后位置)。即使放在{}里面作用域与一样。

带参宏定义:宏函数

注意:带宏参数和函数有本质区别:

指针

指针概念:指针就是地址,内存单元(一个字节即为一个内存单元)的编号

指针数据类型:处理指针(地址)数据

语法:基类型* 指针变量名

3.指针变量的引用:


预处理过程:

预处理流程:

1 .编辑  2.编译  3.运行  4.调试

编译过程:

1.预处理

//将代码中相关预处理命令执行,最终生成一个只包含C语言代码的文件

2.编译

//对语法进行检查,将这个c的源代码生成汇编代码

3.汇编:

//表示将汇编源代码最终生成机器代码

4.链接:

//将使用到的其他代码链接到一起,生成可执行文件(修改权限命令 chomd +x main.o)

宏定义:

语法:#define 标识符 字符串(#define 宏名 宏值)

eg:define N 10

含义:表示将来代码中出现的N都代表10

预处理命令将宏值进行文本替换

假设 #define N 10;(加了分号)

预处理命令替换文本为原样替换(printf("%d",N)原样替换为printf("%d",10;))分号也直接替换过来

  1 #include <stdio.h>
  2 #define N 10;
  3 
  4 int main()
  5 {
  6     printf("%d",N);                                                                                                                  
  7 
  8     return 0;
  9 }

预处理直接原样替换(10;)到N;

 int main()
 {
  printf("%d",10;);
 
  return 0;
 }  

1.预处理命令一般用#开头

2.宏名命名规则与标识符相同

3.应用:①提高代码可读性②一改全改,方便代码修改

4.宏名的作用域:从定义那行到代码下面全部(宏和宏之间可以嵌套使用,不分定义的前后位置)。即使放在{}里面作用域与一样。

除非定义#undef取消宏名的定义时作用域就在#define到#undef之间。

带参宏定义:宏函数

语法:#define ADD(a,b)  a*b

   #include <stdio.h>
   #define ADD(a,b) a+b
   #define SUB(a,b) a-b
   #define MUL(a,b) a*b
   #define DIV(a,b) a/b
   
   int main()
   {
       int a,b;
  
      scanf("%d %d",&a,&b);
  
      printf("a + b = %d\n",ADD(a,b));
      printf("a - b = %d\n",SUB(a,b));
      printf("a * b = %d\n",MUL(1+2,3+4));
      printf("a / b = %d\n",DIV(a,b));
  
      return 0;                                                                                                                        
  }

文本直接替换(1+2*3+4),与我们想要的结果不同,所以避免出现这种情况应该在宏定义时加括号,防止优先级破坏你想要的效果。

 int main()
 {
  int a,b;
 
  scanf("%d %d",&a,&b);
 
  printf("a + b = %d\n",a+b);
  printf("a - b = %d\n",a-b);
  printf("a * b = %d\n",1+2*3+4);
  printf("a / b = %d\n",a/b);
 
  return 0;
 
 }

注意:带宏参数和函数有本质区别:

①处理的阶段不一样:宏定义在预处理阶段;而函数在编译阶段。

②使用不一样:

宏:

1.预处理阶段就使用结束了,宏的使用;本质上时文本的原样替换。

宏参数:

2.宏的参数:只是文本的替换,不进行语法检查。

函数:

1.在调用时使用(即函数的使用,本质上是函数代码的调用)

2.函数参数:函数的参数是有类型的,编译阶段要进行类型检查

带参宏的应用:一般对于短小的代码,考虑写成带参宏

(可以减少函数的调用,减少函数压栈的步骤,提高效率)

文件包含:

①#include <文件名>②#include "文件名"

<>与""的区别:

<>:到系统默认的路径下寻找对应的头文件

“”:表示先到当下目录下找到头文件,如果没有,再到系统默认路径下寻找

3.条件编译:

①:#ifdef  标识符

   程序段1:

        #else

   程序段2:

哪个条件符合,在预处理就处理哪个代码段,不成立那个不出现在预处理中

用途:①调试代码②设计头文件

②:#if 表达式

      程序段1;

      #else

       程序段2;

表达式为真则执行代码程序段1,假则执行表达式2;

指针

指针概念:指针就是地址,内存单元(一个字节即为一个内存单元)的编号

指针数据类型:处理指针(地址)数据

指针也是一种数据类型;这种数据类型专门用来处理地址这种数据。

指针变量的命名:

数据类型 + 变量名

语法:基类型* 指针变量名

基类型(即数据类型:整型、浮点型、字符型、数组型、结构体类型等)

eg:

int* p;p即为指针变量

int a;//a所在的内存空间是用来存放int的数据类型的

float b = 10;

int *p =&a;(✔) a的数据类型为int型,&a的数据类型为int*类型

&a含义:①表示获得a所在空间的首地址;②表示获得了一块可以存放int型数据的内存空间的地址

int* p;int*含义:① 表示这是一个指针类型 ②表示指向int型数据的指针类型

2.指针类型:int*整体类型叫指针类型

3.指针变量的引用:

int a = 10;

int *p = &a;//p指向了a(因为p中保存了a中的地址)

指针运算符:*为单目运算,运算对象只能是指针(即地址)

*p表示访问p所指向的基类型的内存空间。

通过*p访问为间接访问,通过a的访问为直接访问

int *p = &a;

解析:

step1:首先拿出p中的地址,到内存中定位

step2:看p的类型,偏移出sizeof(基类型)大小的一块空间

step3:将偏移出的这块空间,当作一个基类型变量来看。 

  • 35
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值