赞
踩
假设有:
- 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');
- }
假设有:
- 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);
- }
- }
- }
- }
假设有
- 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;
- }
既通过指针的方式 来调用函数
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;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。