关于指针和函数

关于函数和指针

这几天瞎写的时候关于指针以及malloc产生了一些问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
int* initial(int*);
void initial(int*);
int main(void)
{
int *p = (int*)malloc(sizeof(int));
p = NULL;
printf("%p %p\n",p,&p);
p = initial(p);
printf("%p %p\n",p,&p);
}

int* initial(int* p)
{
p = (int*)malloc(sizeof(int));//在函数中,指针p的地址变了
*p = 5;
printf("%p %p\n",p,&p);
return p;
}
/*
void initial(int* p)
{
p = (int*)malloc(sizeof(int));//在函数中,指针p的地址变了
//为p分配地址,但退栈后p的地址没了(找不到了)
*p = 5;
printf("%p %p\n",p,&p);
}*/

运行截图

如果用return返回在函数中用malloc分配得到的指针

QQ截图20210429195130

p是一个指向int类型的指针,其值一开始设置为NULL,指针的地址是61fe18,但在函数中利用malloc分配后得到的新值为6b1640,并且指针本身的地址也不一样。

这是因为调用函数时,生成栈,参数只是一层浅拷贝,值相同,但地址不同,这就是函数的机制吧.

再举个例子,比如说

1
2
3
4
5
6
7
8
9
10
int main(void)
{
int num = 0;
printf("%p",&n);
func(num);
}
void func(int n)
{
printf("%p",&n);
}

QQ截图20210429200528

可以发现地址并不同,这也说明了地址的变化.

如果不用return返回,运行截图所示,根据刚才函数机制可知,指针的值(即所指向值的地址)并不会变化。

QQ截图20210429195214

所以可以得到第一个结论了。

指针也是一个变量,我们如果要改变它,必须找到它在内存中的地址,也就是指针的地址。也就是说,对于函数中,如果对指针的地址进行赋值,事实上是改变不了原指针的!

所以解决方法主要两个,在c中利用二级指针改变指针的地址.

如果在cpp中即可利用引用类型&比较方便

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
typedef struct Node 
{
int data;
struct Node* lchild;
struct Node* rchild;
}BiNode,*Bitree;
void initial(Bitree);
int main(void)
{
Bitree t = (Bitree)malloc(sizeof(BiNode));
printf("%p\n",t);
initial(t);
if(t->lchild==NULL)
printf("子孩子结点为空k\n");
printf("%p\n",t->lchild);
printf("%c\n",t->data);
printf("%d\n",t->lchild->data);
}
void initial(Bitree root)
{
printf("%p\n",root);
// scanf("%c",&root->data);
root->lchild = (Bitree)malloc(sizeof(BiNode));
printf("%p\n",root->lchild); //this pointer's value ,means pointed object addres
}

20214291

可知,指针传入函数后,其值(即指向值的地址)未变,在函数中为子节点申请了空间,在函数外也能通过其访问。

QQ截图20210429204704

内存分配的知识:

1、参数、局部变量分配在栈区中。编译器自动回收
2、malloc申请的内存分配在堆上,由程序结束OS回收3、全局(静态区),全局变量和静态变量,由程序结束OS回收

在函数中利用malloc分配空间或为指针赋值需要注意:

  1. 函数的参数是浅拷贝,地址与实参不同,如果要相同,在cpp中用&引用参数
  2. 在函数内为指针分配地址时,栈退后会使得这个分配得到的地址无法引用,指针的地址依然是调用前,值没有改变
-------------本文结束感谢您的阅读-------------
感谢阅读.

欢迎关注我的其它发布渠道