C语言中指针实在是太强大了!
我们就不再复习,指针与基本数据类型的关联了.
简单说一下,
指针与整形数组,指针与浮点型数组,等等基本数据类型组成的数组与指针用起来大同小异,用一个整型数组概括了.
int intNum[5] = {1,3,5,7,9};
int *pIntNum = intNum;
//打印
for(int i = 0 ; i < 5; i ++) {
printf("pIntNum[i] =%d", *(pIntNum + i))
}
所以, *(pIntNum + i) <=> pIntNum[i] <=> intNum[i] <=> *(intNum + i)
虽说在访问每一个数时他们有相同效果,但也要注意他们的本质区别.,其他各种操作都容易了.
然后,从字符数组和字符串指针开始吧.
字符数组,顾名思义,存放字符变量的数组.
如:
char greet[20] = “welcom to you”;
这里的初始化的greet[20]是一个字符数组,也是一个字符串.我们知道数组名greet即为字符串”welcome to you” 的首地址,而字符串有一个特性,即可以通过访问首地址访问整个数组.如:
打印welcom to you :
printf(“我是首地址但我能访问:%s\n”,greet);
那么字符串指针呢?
由上边字符数组字符串指针就很好理解了,也就是指向一个字符串的指针,如:
char* pConst = “come on , can you change me?”
又如:
char* pGreet = greet;
pGreet就是一个字符串指针,它存放的也是字符串”welcom to you”的首地址. 因此就可以通过pGreet访问字符串了.如:
同样打印welcome to you :
printf(“其实,我存得也是地址但我也能访问:%s\n”,pGreet);
看出来了吗,从字符串的访问看,字符串指针和字符数组没神马区别呀? 那访问单个字符呢?
.
当然,你早已理解指针的定义是地址,数组是多个变量的组合,这些对你都是小case!
我们来试试逐个输出字符串中的字符:
用指针:
for (int i = 0 ; i < strlen(greet); i ++) {
printf(“greet[%2d = %c\n", i ,*( pGreet + i ));
}
用数组:
for (int i = 0 ; i < strlen(greet); i ++) {
printf(“greet[%2d] = %s\n",i , greet[i]);
}
虽然输出结果相同,但是 用指针访问就是移动地址(pGreet + i),然后取出字符( 用 * 取值);数组就简单了,直接访问存放这个字符的变量(greet[i])就是了.
我想改变一个字符串中的某个字符可以吗?
Of course.如:
greet[10] = ‘M’;
greet[11] = ‘M’;
greet[12] = ‘ ‘;
printf(“我想重新说一句:%s\n”, greet);
or
*(pGreet + 10) = ‘M’;
*(pGreet + 11) = ‘M’;
*(pGreet + 12) = ‘ ’;
printf(“其实,我想说的是:%s\n”,pGreet);
结果真的改变了.
然而,看着好像用了两种方法,其实都一样.
因为,(pGreet + 10)是变量greet[10]的地址,而*(pGreet + 10) = ‘M’ 就是改变这个地址存放的字符,同greet[10] 一样.
那这个呢?
char *pConst = “come on , can you change me?”
能通过指针去改变吗? of course ,you can not.为什么呢?
因为,” come on , can you change me?” 这么一大串是一个字符串常量.常量是不可以该变的.
其实字符串指针可以这样,通过改变指针变量存得地址,改变它的指向:
如:pGreet = pConst;
printf(“改变了我存的地址,我也能访问%s了.”)
这里
⚠️通过改变pGreet指向改变了它能访问的字符串
那么真正不同在哪呢?
*** 一个字符串指针 是指针变量,一.它可以指向不同字符串地址,从而改变所能取到得值;二.它占内存大小只与操作系统有关,操作系统是几位的它就占多少地址,与类型无关;三.①指向变量时,可以通过它改变变量的值.②指向常量时,不能改变常量的值.
*** 一个字符数组,是多个变量的组合,操作.用法不用说了,但值得注意的是:因为数组名也是常量,所以数组名是不能进行算术运算滴.即: greet++; greet = greet + 1 都是错误的.
※.复习完字符数组与字符串, 我们来看看字符串指针数组与字符串数组.
字符串数组,如:
char weekday[7][15]= {“sunday”,”monday”,”tuesday”, “wednesday”,”thursday”,”firday”,”saturday”};
字符串指针,如:
定义字符串指针数组并初始化:
1⃣. char * pWeekday[7] = {“sunday”,”monday”,”tuesday”, “wednesday”,”thursday”,”firday”,”saturday”};
太low了吧 , 用这种方式一不小心,你就用指针操作常量了,就出现错误了.
2⃣. char * pWeekday[7] = {0};
for (int i = 0; i < 7; i ++) {
pWeekday[i] = weekday[i];
printf("%s\n",pWeekday[i]);
}
瞬间高大上有木有? 同时也看出来了,第一种定义的字符串指针数组,是一组指向字符串常量的指针;第二种字符串指针数组定义的是一组指向字符串数组weekday[7][15](变量)的指针.
然后,我们来对这7个字符串进行排序:
用数组:
for (int i = 0 ; i < 7 - 1; i ++) {
for (int j = 0 ; j < 7 - 1 - i; j ++) {
if (strcmp(weekday[j], weekday[j +1]) > 0) {
char weekdayTemp [15] = {0};
strcpy(weekdayTemp ,weekday[j] );
strcpy(weekday[j], weekday[j +1]);
strcpy(weekday[j +1], weekdayTemp);
}
}
}
for (int i = 0 ; i < 7; i ++) {
printf("%s,",weekday[i]);
}
和整型数组排序一样,进行各个字符数组本身值的变化.
注意 这里是改变的是字符串数组各个字符串变量(如:weekday[1])所存储的字符串.字符存在内存的顺序发生了改变.
用指针:
for (int i = 0 ; i < 7 - 1; i ++) {
for (int j = 0 ; j < 7 - 1- i ; j ++) {
if (strcmp(pWeekday[j], pWeekday[j + 1]) > 0) {
char * pTemp = pWeekday[j];
pWeekday[j] = pWeekday[j + 1];
pWeekday[j + 1] = pTemp;
}
}
}
for (int i = 0 ; i < 7; i ++) {
printf("%s,",pWeekday[i]);
}
字符串指针,我们只要理解了pWeekday[i] 是什么,其他的就没什么了.
pWeekday[i],是指针数组中的一个,当然它就是每个字符串的首地址了,所以 紫色字体部分 就是进行字符串指针数组的重新指向.改变字符串的首地址当然就改变了它们各自可以访问整个字符串了(字符串本身是没有交换的).