**p,*p和&p使用有感

*p两种使用状况:数组

1.定义指针变量,如char *p;这里p是一个变量,单单在这一点上与int a 无差异;但p这个变量特殊在其中只能存地址。函数

引伸:对于char **p,p中存一个地址add1,add1对应存储区存放add2,而add2地址对应存储区才存放有真正的data;以下图1所示:spa

2.*p,用来取p中所存地址对应存储区的数据,如上图2所示。指针

例如:主函数main中有char *p,p=。。。令p中存放某一内存首地址。这时调用子函数,若想在子函数fun中修改p指向的内存,必须:code

(1)要获得p的地址即fun(&p),而后用*p=。。。才能需改p指向的内存,具体以下:blog

void func(char **p2) { char *p1 ; //p1 = (char *)malloc(sizeof(char) * 8); p1 = "hello"; *p2 = p1; } int main(){ char *p = NULL; func(&p); printf("p=%s\n",p);//打印p指向内存所存字符串。
 getchar(); return 0; } 输出:hello

 (2)若不想传地址,就须要子函数带返回值,程序以下:内存

char * func(void) {
  
char *p1 ;
  p1
= "hello";
  
return p1; } int main(){ char *p = NULL; p=func(); printf("p=%s\n",p);//打印p指向内存所存字符串。 getchar(); return 0; }
输出:hello

引伸:下面给出一些案例字符串

一个典型错误:get

看你能不能找出来:class

1 void t(char **p2){ 2     char *p1 ; 3     p1 = (char *)malloc(1); 4     *p2 = p1; 5 } 6 int main(){ 7     char **p ; 8 
 9 t(p); 10     return 0; 11 } 为何一运行就提示p没有初始化。

 改进:下面为对**p正确应用的例子:

void t(char **p2) { char *p1 ; //p1 = (char *)malloc(1);
    p1 = "hello"; *p2 = p1;//*p原本指向arr[],如今指向"hello"所在内存区域首地址,因此堆arr[]没影响。 } int main(){ char **p; p = (char **)malloc(sizeof(char) * 8); char arr[] = "zhang"; *p = arr;//*p中存放arr地址,区别于p = (char **)arr直接p中存放arr地址
printf("a[0]=%c\n",arr[0]); 
t(p);
printf(
"*p=%s,p=%d\n",*p,p);
printf(
"a[0]=%c\n",arr[0]);
return 0;
}
 

输出:

a[0]=z
*p=hello,p=13531344//不一样人结果不同。
a[0]=z

这种方式本来的arr[]数据还在,只是*p不指向了,*p指向了“hello”所在内存的地址。

再看一种:注意与上面程序对比,你就能明白**p到底这么用。

void t(char **p2) { char *p1 ; p1 = "hello"; *p2 = p1;//p存放arr地址,*p 对应arr[0]的值,所以这句会破坏原理的arr数组。 } int main(){ char **p; //p = (char **)malloc(sizeof(char) * 8);
    char arr[] = "zhang"; p = (char **)arr;//*p = arr思考注释中的这种方式的差异?//p存放arr地址
    printf("a[0]=%c\n",arr[0]); t(p); printf("p=%s,p=%x\n",*p,p); printf("a[0]=%c\n",arr[0]); return 0; }
输出: a[0]=z p=hello,p=75fe70 a[0]=?思考:为何结果和上面程序不同。其实注释里已经给出了答案,哈哈。
相关文章
相关标签/搜索