一、指针跟二维数组之间的关系
1. 熟练掌握二维数组跟指针有关的几种写法
例子1:int类型的二维数组
int a[5][6]={78,96,741,5,12,74};
哪些是指针,如果是指针,请问是什么类型的指针?哪些不是
a a+1 是指针,表示该数组首元素(a[0])的地址&a[0],加了24个字节
a的类型是: int (*)[6]; 数组指针
&a &a+1 是指针,数组名前面加上&表示指向整个数组的一个指针
整个数组 int [5][6]这种类型
&a的类型是:int (*)[5][6]
a[0] a[0]+1 是指针,把二维数组当成特殊的一维数组看待,a[0]就是第一个成员的名字,第一个成员就是int[6],数组名出现 在表达式表示该数组(int[6])首元素的地址
a[0]的类型是: 等价于&a[0][0] int *
&a[0] &a[0]+1 是指针
&a[0]的类型是: int (*)[6]; 数组指针
a[0][1] a[0][1]+1 不是指针
&a[0][1] &a[0][1]+1 是指针, int *
#include <stdio.h> int main() { int a[5][6] = {78, 96, 741, 5, 12, 74}; /* printf("a is:%p ",a); printf("a+1 is:%p ",a+1); printf("&a[0] is:%p ",&a[0]); printf("&a[0]+1 is:%p ",&a[0]+1); printf("&a is:%p ",&a); printf("&a+1 is:%p ",&a+1); */ printf("a[0] is:%p ", a[0]); printf("a[0]+1 is:%p ", a[0] + 1); }
#include <stdio.h> int main() { int i,j; char a[5][10]={"hello","world","gec","china","hehe"}; //第一种:通过char *类型的指针访问二维数组 /* char *p=&a[0][0];//或者 char *p=a[0]; for(i=0; i<50; i++) { printf("*(p+%d) is:%c ",i,*(p+i)); } */ //第二种:通过数组指针访问二维数组 char (*q)[10]=&a[0]; //q+1每次跳过一个字符串 /* for(i=0; i<5; i++) //printf("%s ",(char *)(q+i)); //printf("%s ",*(q+i)); //18和19行结果一样 */ for(i=0; i<5; i++) { for(j=0; j<10; j++) //printf("%c ",*(*(q+i)+j)); //做个了解,强烈不推荐你这么写 printf("q[%d][%d]%c ",i,j,q[i][j]); } } /* 推导过程: *(*(q+i)+j) --》*(*(&a[0]+i)+j)--》*(*(&a[i])+j)--》*(a[i]+j) --》*(&a[i][0]+j) */
练习
char b[5][10]={"hello", ''world", "gechehe","china"};
//思路: b理解成5个 char [10]
//用字符c替换world中字符r
*(b[1]+2)='c'; // b[1]是指针--》什么类型char * 等价于 &b[1][0]
//p是数组指针
char (*p)[10]=&b[2]; // b[2]数组名,&b[2]是个数组指针
// p指向china
p++;
printf("p is:%s ",(char *)p); // %s要求打印字符串,必须是char *类型
printf("b[1] is:%s ",b[1]);
#include <stdio.h> int main() { char b[5][10] = {"hello", "world", "gechehe", "china"}; //思路: b理解成5个 char [10] //用字符c替换world中字符r *(b[1] + 2) = 'c'; // b[1]是指针--》什么类型char * 等价于 &b[1][0] //p是数组指针 char(*p)[10] = &b[2]; // b[2]数组名,&b[2]是个数组指针 // p指向china p++; //printf("p is:%s ",(char *)p); // %s要求打印字符串,必须是char *类型 //跟13行结果一样 *p等价于--》*(&b[3])--》等价于b[3] printf("p is:%s ", *p); printf("b[1] is:%s ", b[1]); }
作业:
1. 定义一个char类型的二维数组char buf[6][20],要求使用指针操作去除掉字符串中所有的非英文字母(只要不是英文字母的全部剔除)
思路有两种:第一种采用char *指针去访问这个二维数组
第二种采用数组指针 char (*p)[20] p[i][j]
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <stdio.h> #include <string.h> /* * 定义一个char类型的二维数组char buf[6][20],要求使用指针操作去除掉字符串中所有的非英文字母(只要不是英文字母的全部剔除) */ int main() { int i, j, k, len_2 = 0; char input[6][20] = {0}; char(*pn)[20] = &input[0]; //取地址一组字符串的首地址 printf("Please enter 6 string "); for (i = 0; i < 6; i++) gets(input[i]); for (i = 0; i < 6; i++) { len_2 = strlen(input[i]); //计算出这个字符长度 for (j = 0; j < len_2; j++) //逐个比较 { if (((pn[i][j] < 'a') && (pn[i][j] > 'Z')) || (pn[i][j] < 'A') || (pn[i][j] > 'z')) //当发现不是这个字母的时候 { for (k = j; k <= len_2 - 1; k++) //将字符剔除 { pn[i][k] = pn[i][k + 1]; } len_2--; //字符长度对应减少 j--; //重新比较 } } } printf("==========divide=========== "); //分界线 for (i = 0; i < 6; i++) printf("%s ", pn[i]); return 0; }
2. 定义一个char类型的二维数组char name[5][20],你从键盘输入5个字符串表示5个人的名字,编程实现用指针判断5个名字中是否包含了英文大小写以及数字,并且每个人的名字长度不能超过8个字符(人的名字要求:小写字母,大写字母,数字字符三种都要包含),如果名字符合要求就打印出来,不符合就打印缺少了那种字符(缺少了小写?大写?英文?printf打印提示即可)
思路:用指针去遍历字符串,标记字符的类型(大写,小写,数字字符)
定义三个int类型的变量去标记
int flag1=0; // 1 大写 0 非大写
int flag2=0; 1 小写 0 非小写
int flag3=0; 1 数字字符 0 非数字字符
hfdhskfhE86 //只要有一个字符不符合三种类型要求,直接退出循环
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <stdio.h> #include <string.h> int main() { int i, j, len_2 = 0; int Low_flag = 0, Hig_flag = 0, Num_flag = 0; //小写标志位/大写标志位/数字标志位 //char *pn[5]; char input[5][9] = {0}; char(*pn)[9] = &input[0]; Begin: printf("Please enter 5 string "); for (i = 0; i < 5; i++) { gets(input[i]); if (strlen(input[i]) > 8) //判断是否大于8个字符长度 { printf("Error:you enter more than 8 characters! "); goto Begin; } } printf("==========divide============= "); //分界线 for (i = 0; i < 5; i++) { // pn[i] = input[i]; //取地址一组字符串的首地址 len_2 = strlen(input[i]); //计算字符长度 for (j = 0; j < len_2; j++) //逐个判断: { if ((pn[i][j] >= 'A') && (pn[i][j] <= 'Z')) { Hig_flag = 1; //大写标志位置1 continue; } if ((pn[i][j] >= 'a') && (pn[i][j] <= 'z')) { Low_flag = 1; //小写标志位置1 continue; } if ((pn[i][j] >= '0') && (pn[i][j] <= '9')) { Num_flag = 1; //数字标志位置1 continue; } } if (Low_flag == 1 && Hig_flag == 1 && Num_flag == 1) //只有3个标志位置1的说明无误 { printf("%s ", pn[i]); //打印本身字符串 } if (Low_flag == 0) { printf("No.%d String lack Lowercase ", i + 1); //缺少小写字符 } if (Hig_flag == 0) { printf("No.%d String lack Uppercase ", i + 1); //缺少大写字符 } if (Num_flag == 0) { printf("No.%d String lack Number ", i + 1); //缺少数字字符 } Low_flag = 0; //用完清0,方便下次使用 Hig_flag = 0; Num_flag = 0; } return 0; }