目录
1.宏:
分类:
不带参宏
带参宏(宏函数)
带参宏与函数的区别:
1.指针:
2.概念:
1.地址:
2.指针:
3.指针变量:
3.运算符:
4.指针变量的定义:
5.指针常见操作:
6.指针的算数运算:
7.指针作为函数参数:
1.复制传递(赋值传递)
2.地址传递
作业:
1.宏是代码的替换,中间不进行任何数据计算的操作
2.能加括号就加括号,不好吝啬小括号
#define N 5
#define MAT(x,y) (x > y ? x : y)
1.函数有参数类型、返回值、调用的概念
2.带参宏只是代码的替换
3.带参宏会让程序代码体积增大
4.函数不会让程序代码体积增大
5.函数传参会占用资源开销,增大程序运行时间
6.带参宏没有传参调用的过程,程序运行速度更快
带参宏:
用于封装比较简单的模块代码
==============================================================================================================================================================
1.代码更加简洁高效
2.指针可以直接访问内存
3.指针可以操作硬件
用来区分内存中不同字节的编号
指针就是地址,地址就是指针,指针多了指向的概念
是一个变量, 变量里面存放了一个指针(地址), 称为指针变量,
使用指针变量等价于使用其内部存放的指针,所以我们有时也把指针变量简称为指针
&:只能操作左值(变量)
*:只能操作指针类型
int Num;
&Num:
值:获得Num变量在内存空间中的首地址
类型:int * (&有类型升级效果)
*&Num:
值:获得&Num指针对应空间中的值
类型:int (*有类型降级效果)
注意:
作为左值,将右值放入左边指针指向的空间
作为右值,直接取指针指向空间中的值
*&Num = 100;
*&Num;
int main(void)
{
int *p = NULL;
int a = 100;
p = &a;
return 0;
}
int *p;
int *q;
int *p, *q;
野指针:未经初始化的指针,指向已经被释放过空间的指针称为野指针
指针一定记得初始化
空指针:NULL 0x0, 指向内存地址为0x0的指针
int *p = NULL;
所有的指针变量占8个字节
直接访问:通过变量的变量名访问内存空间
间接访问:通过变量在内存中的地址访问变量空间
int *p = NULL;
int *q = NULL;
int a = 100;
int b = 200;
p = &a;
q = &b;
1.p = &b
2.*p = b
3.p = q
4.*p = *q
从终端接收两个数,利用指针对这两个数完成四则运算打印结果
#include
int main(void)
{
int a = 0;
int b = 0;
int *p = NULL;
int *q = NULL;
scanf("%d%d",&a,&b);
p = &a;
q = &b;
printf("a + b = %d\n",*p + *q);
printf("a - b = %d\n",*p - *q);
printf("a * b = %d\n",*p * *q);
printf("a / b = %d\n",*p / *q);
return 0;
}
int *p = NULL;
int *q = NULL;
+
-
++
--
p++:向内存高地址偏移指向数据类型大小个字节空间
p--:向内存低地址偏移指向数据类型大小个字节空间
p - q:
int *p = NULL;
int a = 100;
p = &a;
*p++; 等价于: *p;
p++;
(*p)++; 等价于: *p
(*p) ++
#include
int main(void)
{
int a = 0;
int b = 0;
int *p = (int *)0x10;
int *q = (int *)0x20;
printf("%p\n",p + 1);
printf("%p\n",p++);
printf("%ld\n",q - p);
return 0;
}
实参将值传递给形参,形参是实参的副本,形参改变不会影响实参
函数体内想使用函数体外部变量值的时候使用复制传递
实参地址传递给形参,形参就是实参的指针,可以通过对形参取*改变实参的值
函数体内想修改函数体外部变量值的时候使用地址传递
封装一个函数获得数组中的最大值和最小值
int GetMinMaxNum(int array[], int len);
#include
int getfun(int b[],int len,int *p,int *q)
{
int i;
*p = b[0];
*q = b[0];
for(i = 1;i < len;i++)
{
if(*p < b[i])
{
*p = b[i];
}
if(*q > b[i])
{
*q = b[i];
}
}
return 0;
}
int main(void)
{
int a[5] = {0};
int max = 0;
int min = 0;
int i;
int len = 0;
len = sizeof(a) / sizeof(a[0]);
for(i = 0;i < len;i++)
{
scanf("%d",&a[i]);
}
getfun(a,len,&max,&min);
printf("max = %d,min = %d\n",max,min);
return 0;
}
1.封装一个函数,完成传入两个数值,获得这两个数值的最大公约数和最小公倍数
6 9
最大公约数:3
最小公倍数:18
2.求出数组a[N][N]中主对角线最大值和辅对角线最小值
#define N 5
int a[N][N];
1,
#include
int fun(int x,int y,int *yue,int *bei)
{
int i = 0;
int min = 0;
int max = 0;
max = y;
min = x;
if(y < x)
{
min = y;
max = x;
}
for(i = min;i > 0;i--)
{
if(x % i == 0 && y % i == 0)
{
*yue = i;
break;
}
}
for(i = max;i <= x * y;i++)
{
if(i % x == 0 && i % y == 0)
{
*bei = i;
break;
}
}
return 0;
}
int main(void)
{
int a,b;
int yue = 0;
int bei = 0;
scanf("%d%d",&a,&b);
fun(a,b,&yue,&bei);
printf("最大公约数:%d\n最小公倍数:%d\n",yue,bei);
return 0;
}
2,
#include
#define N 5
int main(void)
{
int a[N][N] = {0};
int i = 0;
int j = 0;
int zmax = 0;
int fmin = 0;
for(i = 0;i < N;i++)
{
for(j = 0;j < N;j++)
{
scanf("%d",&a[i][j]);
}
}
for(i = 0;i < N;i++)
{
for(j = 0;j < N;j++)
{
printf("%d\t",a[i][j]);
}
printf("\n");
}
zmax = a[0][0];
for(i = 1;i < N;i++)
{
if(a[i][i] > zmax)
{
zmax = a[i][i];
}
}
fmin = a[0][N - 1];
for(i = 1,j = N - 2;i < N;i++,j--)
{
if(a[i][j] < fmin)
{
fmin = a[i][j];
}
}
printf("zmax = %d\nfmin = %d\n",zmax,fmin);
return 0;
}