- 首先:下面的例子发现有如下结果和代码,发现传入的str参数值并没有改变。于是对指针的传递产生了疑问?GetMemory(char *p, int num)传递的p指针是传递的str的地址,还是传递的str的内容((char *)malloc(sizeof(char) * 10)返回的指针)呢?
zion6135@zion6135-VirtualBox:~/Desktop$ ./a.out
--1--1707778720
--2--1707779792
--3---1707778720
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
void GetMemory(char *p, int num)
{
printf("--1--%d\n", p);
p = (char *)malloc(sizeof(char) * num);
printf("--2--%d\n", p);
}
void Test(void)
{
char *str = (char *)malloc(sizeof(char) * 10);
GetMemory(str, 100);
{
printf("--3---%d\n", str); // 与--2--的结果不同!!!!
}
strcpy(str, "hello");
}
int main()
{
Test();
exit(0);
}
- 指针传递传递了什么。为什么参数修改传入的指针,没有被改变
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <string.h> void GetMemory(int *p, int num) { printf("--2--mem-addr %p\n" ,&p); printf("--2--content %p\n" ,p); printf("--2--ptr-obj %d\n\n" ,*p); p = (int*)malloc(sizeof(int)); printf("--3--mem-addr %p\n" ,&p); printf("--3--content %p\n" ,p); printf("--3--ptr-obj %d\n\n" ,*p); } void Test(void) { int a = 10; int *str = &a; { printf("--1---mem-addr %p\n",&str); // 与--1--的结果不同!!!! printf("--1--content %p\n" ,str); printf("--1--ptr-obj %d\n\n" ,*str); } GetMemory(str, 100); { printf("--4---mem-addr %p\n",&str); // 与--1--的结果不同!!!! printf("--4--content %p\n" ,str); printf("--4--ptr-obj %d\n" ,*str); } // strcpy(str, "hello"); } int main() { Test(); exit(0); }
打印结果:
zion6135@zion6135-VirtualBox:~/Desktop$ g++ test.cpp zion6135@zion6135-VirtualBox:~/Desktop$ ./a.out --1---mem-addr 0x7ffda01e2a50 --1--content 0x7ffda01e2a4c --1--ptr-obj 10 --2--mem-addr 0x7ffda01e2a28 --2--content 0x7ffda01e2a4c --2--ptr-obj 10 --3--mem-addr 0x7ffda01e2a28 --3--content 0x5643f224c6b0 --3--ptr-obj 0 --4---mem-addr 0x7ffda01e2a50 --4--content 0x7ffda01e2a4c --4--ptr-obj 10 zion6135@zion6135-VirtualBox:~/Desktop$
分析上述结果可知:
1和2 的打印可知:指针参数是拷贝传递,只不过拷贝的是指针,所以在GetMemory()函数里面修改传入的指针p 是不会修改传入的str的, 等于是str 和p是两片一样的内存(内存地址不同,内容相同),所以GetMemory()修改p指针不会更新到str, 但修改p的内容(*p)却可以更新到变量a
- 如何用指针传递参数
比如1当中:希望传递的是mem-addr, 那么可以用二级指针,那么二级指针被复制,一级指针也就是mem-addr是一样的!!即可达到相同的目的。
也就是把void GetMemory(int *p, int num)改为 void GetMemory(int **p, int num)即可传递指针。并在函数中去修改指针的值
- char * p= "Hello"; 与char p[] = "Hello";的区别
char func() {
char a = 'c ';
return a; // 正确,返回的是a的值,不是局部内存地址&a;
}
char* func() {
char* p = "Hello"; // 表示p指向一个字符常量区,但 &p是局部变量
return p; //正确,因为p是值, p == &("Hello"); p 不是局部变量
}
char* func() {
char p[] = "Hello"; // p表示局部变量被赋值为 "Hello" , 等价于char p[]; strcpy(p, &("Hello"), 5);
return p; //p代表地址,返回地址错误,因为局部变量地址返回后即失效
}
- 二级指针作为函数参数传递
首先需要明白:函数的参数传递是值拷贝,也就是说无论传递int a,还是int* b, 还是传递 int** c, 变量的传递都是传递的值。
以
void GetMemory(int *p, int num);
GetMemory(str, 100);
为例子, int* p 其实是拷贝传递的str的值,并不是传递的str的地址。所以想要修改str的内容,就需要传递str的地址, str是一个指针,指针的地址就是二级指针。
可以把&p 和 &str打印出来可发现地址不是同一个地址。
- 指针也是有内存地址的
- 函数传递指针的是指针变量值,并不是传递指针的地址
- 所以会有形参,实参的说法;形参只有实参的值,没有实参的地址,所以在函数内只能修改形参的值,不能修改实参的值。