C语言程序设计基础 第10章 指针进阶 刘新国
本章要点 指针数组和指向指针的指针 指针作为函数的返回值 指向函数的指针 指向结构的指针 对链表数据结构
指针数组 char * color[5] = { “red”, “blue”, “yellow”, “green”, “black” };
11.1.2 指针数组的概念 首先,它是一个数组 其次,它的元素是指针 定义格式 类型名 *数组名[长度]; 遵循数组的定义语法 只不过,元素类型为指针类型
指针数组 char * color[5] = { “red”, “blue”, “yellow”, “green”, “black” }; for( i=0; i<5; i++ ) printf("%d-th color = %s\n", i, color[i]); color[0] color[1] color[2] color[3] color[4] red\0 blue\0 yellow\0 green\0 black\0
指针数组 char * color[5] = { “red”, “blue”, “yellow”, “green”, “black” }; char *t = color[0]; color[0] = color[4]; color[4] = t; 对一般数组的操作,适合于指针数组 定义,初始化,元素的使用,赋值 color[0] color[1] color[2] color[3] color[4] red\0 blue\0 yellow\0 green\0 black\0
指向指针的指针(二级指针) int a = 10; int *p = &a; int **pp = &p; 定义语法格式 类型名 **指针变量名; a 10 *pp *p **pp
指向指针的指针(二级指针) 二级(多级)指针都是指针 可以应用指针的所有操作 定义、初始化、赋值 和数组结合使用 特殊的是:它指向一个指针
三级指针和多级指针 三级指针 四级指针 int a = 10, *p= &a, **pp = &p int ***p3 = &pp;
指针数组和二级指针 red\0 color[0] color blue\0 color[1] yellow\0 color[2] char * color[5] = { “red”, “blue”, “yellow”, “green”, “black” }; 数组名color是一指针, 指向首元素color[0]。 char **pc = color; char str[20]; scanf(“%s”, str); for ( i=0; i<5; i++ ) if( strcmp(str, *(pc+i))==0 ) break; if(i<5) printf(“color id = %d\n”,i); else printf(“not found\n”); color[0] color[1] color[2] color[3] color[4] red\0 blue\0 yellow\0 green\0 black\0 color pc pc[i]
11.1.4 指针数组与二维数组 ccolor pcolor[0] pcolor[1] pcolor[2] pcolor[3] red\0 blue\0 yellow\0 green\0 black\0 r e d \0 b l u y o w g n a c k char ccolor[][7] = { “red”, “blue”, “yellow”, “green”, “black” }; char * pcolor[5] = { “red”, “blue”,
11.1.4 指针数组与二维数组 ccolor pcolor[0] pcolor[1] pcolor[2] pcolor[3] red\0 blue\0 yellow\0 green\0 black\0 r e d \0 b l u y o w g n a c k pcolor[i]指向一个字符串,即该字符串首个字符 pcolor[i] + k 则指向该字符串的第k个字符 所以 *(pcolor[i] + k)就是该字符,也可以写作 pcolor[i][k] 注意:pcolor不是二维数组
[例11-4] 字符串排序 #define SWAP(a,b,t) t=a,a=b,b=t void fsort(char* color[], int n) { int k, j; char * tmp; for( k=1; k<n; k++ ) for( j=0; j<n-k; j++ ) if( strcmp(color[j],color[j+1])>0 ) SWAP (color[j], color[j+1], tmp); }
主程序 pcolor[0] pcolor[1] pcolor[2] pcolor[3] pcolor[4] red\0 blue\0 yellow\0 green\0 black\0 pcolor[0] pcolor[1] pcolor[2] pcolor[3] pcolor[4] red\0 blue\0 yellow\0 green\0 black\0 主程序 void main() { char *pcolor[5]={“red”, blue”, “yellow”, “green”, “black”}; int k; fsort(pcolor,5); for( k=0; k<5; k++ ) printf(“%s”, pcolor[k]); }
[例11-6] 藏头诗解密 相邻的两个字符对应一个中文字符 void main() { char *poem[4]={“一叶轻舟向东流”,“帆梢轻握杨柳手”, “风纤碧波微起舞”,“顺水任从雅客悠”}; char mean[10]; int i; for( i=0; i<4; i++ ) mean[2*i] = *(poem[i]); mean[2*i+1] = *(poem[i]+1); } mean[2*i] = ‘\0’; printf(“%s\n”, mean); 相邻的两个字符对应一个中文字符
11.2 字符定位 char * match(char *s, char ch) { while (*s) if( *s==ch ) return s; else s++; return NULL; } 指针作为函数的返回值 返回的指针必须是合法的指针。
11.2 字符定位(错误) char * match(char ch) { char str[] = “university”; char * s = str; while (*s) if( *s==ch ) return s; else s++; return NULL; } void main() { char * r; r = match(‘v’); if( r ) printf(“%s”, r); } 返回的指针不合法!!
11.2.3 函数指针 指向函数的指针。定义语法格式 类型名 (*变量名)(参数类型表); 例如 int (*funptr)(float, double); 定义了一个函数指针, 它的类型是一个指针, 可以存储一个“返回值是int, 有两个分别是float和doulbe参数的函数” 的地址
11.2.3 函数指针 函数名字本身可以作为函数指针使用 编译器不区分: add 和 &add fp 和 (*fp) int add(int a, int b) { return (a+b); } void main() int x, y; int (*fp)(int,int); fp = add; fp = &add; x = fp(3, 4); y = (*fp)(5, x); 函数名字本身可以作为函数指针使用 编译器不区分: add 和 &add fp 和 (*fp)
11.2.3 函数指针作为参数 /* 用梯形公式计算一个函数的积分 */ double calc(double (*fp)(double), double a, double b) { double z; z = (b-a)/2 * (fp(a)+fp(b)); return z; }
11.2.3 函数指针作为参数 double f1(double x) { return x*x; } double f2(double x) return sin(x)/x; void main() { double result; double (*fp)(double); fp = f1; result = calc(fp, 1,2); result = calc(f2, 1,2); }
* 指针数组与数组指针 char ccolor[][7] = {“red”, …}; ccolor是一个二维数组 它的每一行都是一个一维数组 ccolor + i 是一个指针, 指向第i行上的一维数组 ccolor+i类型“长度为7的一维数组”的指针 ccolor[i]也是一个指针,指向第i行的首元素 ccolor r e d \0 b l u y o w g n a c k