3

C语言中的指针是一个难点,主要是感觉很绕,其实C/C++中的指针和Delphi的指针的原理都是一样的,所以这里讲的一个C/C++的例子也适用于Delphi

源码如下

int i, j;
int *pi, *pj;

i=10;
j=9;
pi=&i;    //相当于将指针 pi 指向 i 的地址

//比较下面两个语句
pi=&j;    //这时候是将指针 pi 指向 j 的地址,并不会对i有什么影响
*pi = j;    //在这是将 j 的值赋值给 pi 所指向的那个变量,所以就相当于 i = j;

所以这两个语句并不是等价的,要先去理解指针的指向和实际的内存的关系,再结合语言的上下文就可以理解这些语句的实际意义,并不要没有根据的瞎猜

理解这两者的区别是很有用的,因为编程时候可能有这样的情况,需要一个函数在内部完成功能的时候,要自己去分配内存,而且需要在调用的时候传递进来指针来保存这个分配的内存的地址,以便能在这个函数执行结束之后,能够不丢失去这个分配的内存的指针,能在外面进行释放,不至于造成内存泄露。

比如有两个函数:DoSomeThing()和FreeTheMem(),前者是做某些事,并且自己分配需要的内存,后者是释放掉DoSomeThing()分配的内存,比如调用关系是这样的

char *pchar;    //这个指针的目的是为了传进DoSomeThing,记录DoSomeThing分配的内存的地址

DoSomeThing(&pchar);

FreeTheMem(pchar);

所以对应的DoSomeThing和FreeTheMem的实现是这样的

void DoSomeThing(char **ppchar)
{
    char *pc;
    //为pc分配内存,比如 pc = (char*)malloc(sizeof(char));
    //利用分配的内存来做一些事....
  
    *ppchar = pc;
    //这里的传入的参数 char** ppchar是用于做输出参数的,而不是作为输入参数
    //因为在主函数中调用的形式是DoSomeThing(&pchar),
    //所以就相当于pchar=pc; 这就是想要的效果,
    //就是用主函数中pchar保存被调用的DoSomeThing里面的内存的地址

    //如果要是使用ppchar=&pc;,
    //但是因为在主函数中调用的形式是DoSomeThing(&pchar),
    //所以在这里就相当于&pchar = &pc,所以显然不是想要的效果

}

void FreeTheMem(char *pchar)
{
    ...释放pchar所指向的内存...
}

另外一个需要讲解的知识点,为什么要在DoSomeThing里面分配的内存,因为可能需要将在DoSomeThing里面处理的一些结果保存到这个内存中,供调用它的函数再使用,然后使用完这个内存中存储的信息之后,再去释放内存

所以这里就需要动态分配内存,因为如果你在DoSomeThing里面用一个数组来保存这些信息,但是当DoSomeThing结束之后,这个数组的生命周期也就结束了,所以这时候的数组就被释放了(这种情况下的数组的内存是在栈上分配的),想要保存的信息也就丢失了,所以一定要是动态分配的内存(动态分配的内存是在堆上的)。

其实C++的两种声明对象的方法也和这个类似。


xumenger
4.6k 声望588 粉丝

小学一年级时候就学到了这样一句话“活到老学到老”,但是目前还没老的我们都还在学习吗?