嵌入式学习第十天!(宏、指针)

1. 宏:

    1. 宏是代码的替换,中间不进行任何数据计算的操作

    2. 能加括号就加括号,不要啬小括号

    带参宏与函数的区别:

        1. 函数有参数类型、返回值、调用的概念
        2. 带参宏只是代码的替换
        3. 带参宏会让程序代码体积增大
        4. 函数不会让程序代码体积增大
        5. 函数传参会占用资源开销,增大程序运行时间
        6. 带参宏没有传参调用的过程,程序运行速度更快

    带参宏:

        用于封装比较简单的模块代码

    举例:用带参宏判断最小值、用带参宏输出

#include 

#define MINNUM(X,Y)  ((X) < (Y) ? (X) : (Y))
#define PRINTNUM(x,y,z)	 do{	\
	printf("x = %d\n",x);	\
	printf("y = %d\n",y);	\
	printf("z = %d\n",z);	\
}while(0)

int main(void)
{
	int Num1 = 0;
	int Num2 = 0;
	int MinNum = 0;

	scanf("%d%d", &Num1, &Num2);
	
	MinNum = MINNUM(Num1,Num2);
	printf("MinNum = %d\n",MinNum);

	PRINTNUM(Num1,Num2,MinNum);

	return 0;
	
}

嵌入式学习第十天!(宏、指针)_第1张图片

2. 指针

        1. 代码更加简洁高效

        2. 指针可以直接访问内存

        3. 指针可以操作硬件

    1. 概念:

        1. 地址:用来区分内存中不同字节的编号

        2. 指针:指针就是地址,地址就是指针,指针多了指向的概念

        3. 指针变量:是一个变量,变量里面存放了一个指针(地址), 称为指针变量,使用指针变量等价于使用其内部存放的指针,所以我们有时也把指针变量简称为指针

    2. 运算符:

        &:只能操作左值(变量)

        * :只能操作指针类型

        &Num:

                值:获得Num变量在内存空间中的首地址

                类型:int *   (&有类型升级的效果)

        *Num:

                值:获得&Num指针对应空间中的值

                类型:int      (*有类型降级效果)

        注意:

                1. 作为左值,将右值放入左边指针指向的空间

                2. 作为右值,直接取指针指向空间中的值

        举例:定义Num的值,输出 &Num 和 *&Num ,并对他赋值后在输出,查看效果:

#include 

int main(void)
{
	int Num = 0;

	Num = 100;

	printf("&Num = %p\n",&Num);
	printf("*&Num = %d\n",*&Num);

	*&Num = 200;
	printf("*&Num = %d\n",*&Num);

	Num = 300;
	printf("*&Num = %d\n",*&Num);

	return 0;
}

嵌入式学习第十天!(宏、指针)_第2张图片

    3. 指针变量的定义:

int *p;
int *q;
int *p, *q;

        野指针:未经初始化的指针,指向已经被释放过空间的指针称为野指针,指针一定记得初始化

        空指针NULL 0x0,指向内存地址为0x0的指针

int *p = NULL;

        注意:所有的指针变量占8个字节

        直接访问:通过变量的变量名访问内存空间

        间接访问:通过变量在内存中的地址访问变量空间

    4. 指针常见操作:

int *p = NULL;
int *q = NULL;
int a = 100;
int b = 200;

p = &a;
q = &b;

p = &b    //将b的地址给指针变量p
*p = b    //将b的值赋值给指针变量p所指向的值
p = q     //将指针变量q所存放的地址给指针变量p
*p = *q   //将指针变量q所指向的值赋值给指针变量p所指向的值

        练习:从终端接收两个数,利用指针对这两个数完成四则运算打印结果

#include 

int main(void)
{
	int Num1 = 0;
	int Num2 = 0;
	int *p = NULL;
	int *q = NULL;

	p = &Num1;
	q = &Num2;
	scanf("%d%d", &Num1, &Num2);

	printf("%d + %d = %d\n", *p, *q, *p + *q);
	printf("%d - %d = %d\n", *p, *q, *p - *q);
	printf("%d * %d = %d\n", *p, *q, *p * *q);
	printf("%d / %d = %.2lf\n", *p, *q, *p / (*q+0.1));

	return 0;
}

嵌入式学习第十天!(宏、指针)_第3张图片

    5. 指针的算数运算:

        指针可以进行的算数运算:+、-、++、--

        p++:向内存高地址偏移指向数据类型大小个字节空间
        p--:向内存低地址偏移指向数据类型大小个字节空间

        p - q

        *p++;  等价于*p; p++;

        (*p)++; 等价于:*p; *p++;

    6. 指针作为函数参数:

        1. 复制传递(赋值传递)

                实参将值传递给形参,形参是实参的副本,形参改变不会影响实参

                函数体内想使用函数体外部变量值的时候使用复制传递

        2. 地址传递

                实参地址传递给形参,形参就是实参的指针,可以通过对形参取*改变实参的值

                函数体内想修改函数体外部变量值的时候使用地址传递

        练习:封装一个函数获得数组中的最大值和最小值:

#include 

int GetMaxMinNum(int array[], int len, int *Max, int *Min)
{
	int i = 0;
	*Max = array[0];
	*Min = array[0];
	for(i = 0; i < len; i++)
	{
		if(*Max < *(array+i))
		{
			*Max = *(array+i);
		}
		if(*Min > array[i])
		{
			*Min = array[i];
		}
	}
	return 0;
}

int main(void)
{
	int ary[5] = {0};
	int len = sizeof(ary) / sizeof(ary[0]);
	int i = 0;
	int MaxNum = 0;
	int MinNum = 0;
	
	for(i = 0; i < len; i++)
	{
		scanf("%d",&ary[i]);
	}

	GetMaxMinNum(ary, len, &MaxNum, &MinNum);
	printf("MaxNum = %d, MinNum = %d\n", MaxNum, MinNum);
	return 0;
}

嵌入式学习第十天!(宏、指针)_第4张图片

作业:

        1. 封装一个函数,完成传入两个数值,获得这两个数值的最大公约数和最小公倍数

#include 

int GetDivMulNum(int a, int b, int *Div, int *Mul)
{
	int max = 0;
	int min = 0;
	int i = 0;
	if(a > b)
	{
		max = a;
		min = b;
	}
	else
	{
		max = b;
		min = a;
	}
	for(i = max; i > 0; i++)
	{
		if(i % a == 0 && i % b ==0)
		{
			*Mul = i;
			break;
		}
	}
	for(i = min; i > 0; i--)
	{
		if(a % i == 0 && b % i == 0)
		{
			*Div = i;
			break;
		}
	}

}

int main(void)
{
	int Num1 = 0;
	int Num2 = 0;
	int divisor = 0;
	int multiple = 0;

	scanf("%d%d", &Num1, &Num2);

	GetDivMulNum(Num1, Num2, &divisor, &multiple);

	printf("最小公倍数 = %d, 最大公约数 = %d\n", multiple, divisor);
}

嵌入式学习第十天!(宏、指针)_第5张图片

        2. 求出数组a[N][N]中主对角线最大值和辅对角线最小值

        注意:#define N   5

                   int a[N][N];

#include 
#define N 5

int main(void)
{
	
	int a[N][N] = {{12, 84, 91, 41, 51},                            
         {54, 67, 16, 28, 34},
         {84, 71, 46, 96, 33},
         {63, 37, 73, 57, 11},
         {77, 73, 39, 67, 98}};
	int i = 0;
	int max = 0;
	int min = 0;
	
	max = a[0][0];
	min = a[0][0];
	for(i = 0; i < N; i++)
	{
		if(max < a[i][i])
		{
			max = a[i][i];
		}
		if(min > a[i][i])
		{
			min = a[i][i];
		}
	}
	printf("主对角线:max = %d, min = %d\n", max, min);

	max = a[0][4];
	min = a[0][4];
	for(i = 0; i < N; i++)
	{
		if(max < a[i][N-1-i])
		{
			max = a[i][N-1-i];
		}
		if(min > a[i][N-1-i])
		{
			min = a[i][N-1-i];
		}
	}
	printf("逆对角线:max = %d, min = %d\n", max, min);

}

嵌入式学习第十天!(宏、指针)_第6张图片

你可能感兴趣的:(学习)