嵌入式学习笔记十五——指针操作数组和函数

1.指针操作二维整型数组

        假设有:

int a[4][4] = {1,4,5,6,2,7,8,13,14,3,9,11,10,15,16,12};
int (*p)[4] = a;

        我们先看下面的代码:

printf("p = %p\n",p);// a[0]的地址,代表a这一行
printf("p + 1 = %p\n",p+1);//a[0]的下一个地址,a[1]的地址,代表这 a[1]一行。
printf("(p+1)+1 = %p\n",(p+1)+1);//a[2]这一行的地址
printf("*(p+1) = %p\n",*(p+1));//a[1][0]的地址
printf("*(p+1)+1 = %p\n",*(p+1)+1);//a[1][1]的地址

        可以发现:二维数组a的指针p,p与*p的意义并不一样。p与*p都是地址,p指向一行的地址,p+1指向下一行;*p代表数组一个元素的地址,*(p+1)则指向下一个元素。如果要取地址指向空间的数据内容,需要**p,*p指向一个元素,**p访问地址数据内容。int a[4][4]一行是十六个字节,一个元素是四个字节,如果没搞懂可以运行这段代码,得到的结果都是地址,根据结果来进行理解。

注意:  

         二维数组的操作是从二维数组的本质进行的 ,二维数组的本质一维数组的一维数组,直接的访问操作也是 一维一维的展开

练习: 实现一个函数,找出二维数组中能被3整除的数。代码如下:

void find3Mul(int (*a)[4],int row)
{
	int i = 0;
	int j = 0; 
	for (i = 0;i < row;++i)
	{
		for (j = 0;j < 4;++j)
		{
			if( *(*(a+i)+j)%3 == 0)
				printf("%d ",*(*(a+i)+j));
		}
	}
	putchar('\n');
}

2.指针操作二维字符型数组

        假设有:

char s[][10] = {"hello","world","china"};
char (*p)[10] = s; //p指向二维数组s

        二维字符型数组与整型不同,二维字符型数组用来处理字符串,指针p指向s,p表示s的地址,p等价于s[0]的地址,代表s[0]这一行的字符串的地址,p+1等价于下一行字符串的地址,*p则代表s[0]中存放的字符串。在这一点上,二维字符串型数组与二维整型数组不同,不要搞混。

练习:输入三个字符串 ,排序输出(用函数和指针)。代码如下:

//插入排序
void sort(char (*s)[10],int row)
{
	int i = 0;
	int j = 0;
	char t[10];
	for (i = 0;i < row-1;++i)
	{
		for (j = i+1;j < row;j++)
		{
			if (strcmp(*(s+i),*(s+j)) > 0)
			{
				strcpy(t,*(s+i));
				strcpy(*(s+i),*(s+j));
				strcpy(*(s+j),t);
			}
		}
	}
}

3.指针数组

        假设有

char s[10] = "hello";//存放字符串数据 
char *p = "hello";

        先思考s[10]和p的区别,不难发现:s是一维数组,存放了一个字符串,p是地址,指向了一个字符串。s的数据存放在栈上,p是指向了一个字符串常量,字符串常量的数据储存在字符串常量区,不能被修改。p的类型 是char *  既char *类型的指针变量p ,相当于代表一个字符串 

char *p1 = "hello";
char *p2 = "world";
char *p3 = "china";

        p1、p2、p3都是指针,我们把这些指针写成一个数组

char* pstr[3]= {"hello","world","china"}; //数组 --- 数组中存放是 各个字符串的地址
      //地址 ---存放这地址数据的数组 --- 指针的数组 ---指针数组 

   这个数组中存放是 各个字符串的地址,是存放地址数据的数组是指针的数组,我们称为指针数组

注意:这是一个一维的指针数组,不要与二维字符型数组搞混。

如果要在函数中调用这个指针呢个数组,形参该如何表示?

  根据之前学的指针处理一维数组的知识,如果有int a[3],形参可以设置为int型指针:int *p。char * qstr[3]是char* 型数组,所以,形参应该设置为char * 型指针:char * *p。还需要传入行数int row。**q = pstr; //q 二级指针。

练习:

1.找出字符串中最大值     
2.实现字符串逆序 
3.排序 

char* maxOfStr(char * *p,int len)
{
	//char max[10];

	char *max = *p;

	int i = 0;
	for (i = 1; i < len; ++i)
	{
		if (strcmp(max,*(p+i)) < 0)
		{
			max = *(p+i);
		}
	}

	return max;
}

void reverseStr(char **begin, char **end)
{
	while (begin < end)
	{
		char *t = *begin;
		*begin = *end;
		*end = t;

		begin++;
		end--;
	}
}

void bubbleSort(char **p,int len)
{
	int i = 0;
	int j = 0;

	for (i = len-1; i > 0; --i)
	{
		for (j = 0; j < i; ++j)
		{
			if (strcmp(*(p+j),*(p+j+1)) > 0)
			{
				char *t = *(p+j);
				*(p+j) = *(p+j+1);
				*(p+j+1) = t ;
			}
		}
	}
}


int main(void)
{
	const char *p[] = {"hello","world","china"};
	//printf("sizeof(p) = %ld\n",sizeof(p));
	//char* *q = p;
	printStr(p,3);
	
	//printf("max = %s\n",maxOfStr(p,3));

	//reverseStr(p,p+2);
	bubbleSort(p,3);
	printStr(p,3);
	return 0;
}

4.指针处理函数

既通过指针的方式 来调用函数 

int add(int a,int b) // 函数  

1.函数名 - 代表函数的入口地址 
2.add函数名对应的数据类型 int (int a,int b) 函数类型 
3.int(int a,int b)代表返回值为int型 带有两个int型的形参变量一类函数            

说明:
 1.可以定义一个函数类型的指针变量 来保存函数的入口地址 
 2.有了这个指针变量 通过指针变量 进行函数调用

c语言中,使用了 函数指针 实现回调 

练习:
    写一个程序 实现加,减,乘,除
    以回调函数的形式,打印对应的结果 
    void processData(int a,int b, int (*pfunc)(int,int))
    {
        printf();
    }

代码如下:

#include<stdio.h>

int add(int a,int b)
{
	return a+b;
}
int sub(int a,int b)
{
	return a-b;
}
int mul(int a,int b)
{
	return a*b;
}
int div(int a,int b)
{
	return a/b;
}

void processData(int a,int b,int (*p)(int,int))
{
	printf("%d\n",p(a,b));
}


int main(int argc, const char *argv[])
{
//	int a[] = {1,4,8,6,3,5,-7,-5};
//	int len = sizeof(a)/sizeof(a[0]);
	int a = 10;
	int b = 5;
	processData(a,b,add);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值