铁律2:间接赋值是指针存在的最大意义
引入
除了在一个函数体中,通过指针访问地址来间接修改一个变量的值,类似下面这样:
int a = 10;
int* p = NULL;
// 修改a的值
a = 20; //直接进行修改
p = &a; //间接修改
*p = 30; //p的值是a的地址 *就像一把钥匙 通过地址 找到一块内存空间 就间接的修改了a的值
*
就像一把钥匙,通过这个地址找到一块内存空间,也就可以间接修改a的值。
另外,体现在函数调用中,指针则是更加重要的一点,也就是标题所说的:间接赋值。
void getFileLen(int *p){*p = 41;} //指针作参数,相当于传址,可以对对应地址的值进行修改
void getFileLen3(int b){b=100;} //普通数据作参数,相当于传值,实际上这个操作对于主调函数中的值不会造成任何影响
体现到二级指针中是一样的。
零级指针求地址变成一级指针。在函数调用时,形参传给实参,用实参取地址传给形参,在被调用函数中使用
*p
改变实参,把运算结果传出来。
间接赋值成立的条件
- 定义两个变量,一个实参,一个形参。通过形参(指针)修改实参
- 建立关联,实参取地址传递给形参
*p
形参间接地修改实参的值
间接赋值的应用场景(三个条件自由组合将分别不同)
- 1、2、3这三个条件,写在同一个函数中(最简单的情况)
- 1、2写在一块,3单独卸载另外一个函数中 (函数调用)
- 1单独出来,2、3写在一起(暂时没有接触到,将用于c++中)
推断
用1级指针作形参,可以间接修改0级指针(实参)的值
…
用n级指针作形参,可以间接修改n-1级指针(实参)的值
应用
项目开发中的字符串模型 strstr-whiledowhile
问题描述:
char* p = "11abcd111122abcd33333322abcd33333322qqq";
求字符串p中
abcd
出现的次数。
问题想要解决并不难,通过while
循环和strstr()
函数
大部分内容都是之前经历过的,会在注释中说明。直接贴代码:
// mystr是字符串,sub指分串
int getCount(char* mystr/*in*/, char* sub/*in*/, int* ncount)//间接赋值是指针存在的最大意义
{
//由于使用了指针作函数参数,就可以返回错误码来标识是否查找到,或者传入的参数是否有错
int ret = 0;
int tmpcount = 0;
//初始化 让p指针达到查找的条件
char* p = mystr;//不要轻易改变形参的值
//判断是否为NULL
if (mystr==NULL || sub==NULL || ncount==NULL)
{
ret = -1;
printf("func getCount() err:%d (mystr==NULL || sub==NULL || ncount==NULL)\n", ret);
return ret;
}
do
{
p = strstr(p, sub);
if (p != NULL)
{
tmpcount++;
p = p + strlen(sub);//指针达到了下次查找的条件
}
else
{
break;
}
} while (*p!='\0');//表示到了字符串的结尾
*ncount = tmpcount; // 间接赋值是指针存在的最大意义
return ret;
}
这里引用一个百度知道的的回答:
其实计算机中的内存就像一个个抽屉,每个抽屉都有一个编号,用于存放数据。
为了方便使用,编译器允许我们在写程序的时候,对抽屉进行命名(而不是使用抽屉的编号),这就是变量名。就比如说我们在程序中定义:char C;
这个时候系统会帮我们找一个空闲的抽屉(比方说编号为981的抽屉),命名为C,用于存放一个字符变量。以后我们在程序里只要使用C这个变量,系统就知道是要对981这个抽屉里的数据进行操作。
而指针是什么呢?指针是我们申请一个空抽屉,里面不放数据,而放编号。比如我们申请一个字符指针:char *ch=&C;
这个时候,ch
里面放的是C这个变量的地址(也就是981),其中&是取址符,也就是取C这个变量的地址,而不是值。*ch
才是ch
指向的值。