流言终结者(二)——“数组名”和“指针变量名”是一回事吗?

经常听到别人说:“数组名和指针变量名是一回事”,事实真的是这样吗?
话不多说,先上一份儿代码!

================================================================

源代码1:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
    char *p1       = NULL;
    char *p3       = NULL;
    char  p2[1024] = {0};
    if (NULL == (p1 = malloc(1024))) {
        printf("error in malloc\n");
        return -1;
    }
   
    printf("[%p]\n",   &p1   );
    printf("[%p]\n\n",  p1   );


   
    printf("[%p]\n",   &p2   );
    printf("[%p]\n",    p2   );
    printf("[%p]\n\n", &p2[0]);


    p3 = &p2[0];
    printf("[%p]\n",   &p3   );
    printf("[%p]\n",    p3   );


    return 0;
}
================================================================
运行结果打印1:
Administrator@1427-Michael ~/array
$ ./a.exe
[0x22ac4c]
[0x20010230]


[0x22a848]
[0x22a848]
[0x22a848]


[0x22ac48]
[0x22a848]
================================================================
总结:
1. { &数组名,数组名,&数组名[0] },这三者是同一个东西,都表示数组中第一个元素的地址值!!!
2. “&数组名”的功能并不等价于“&指针变量名”,尤其要注意!!!
================================================================
举例说明如果没弄清楚这二条总结所带来的危害
源代码2:
int foo(char **input)
{
    char *p = *input;
    if (NULL == p) {
        printf("no memory to write\n"); //为了避免调用者传来一段不可写内存
        return -1; // for fail
    }
    else {
        // do something!!
        return 0; // for success
    }
}
int main()
{
    char *p1       = NULL;
    char *p3       = NULL;
    char  p2[1024] = {0};
    if (NULL == (p1 = malloc(1024))) {
        printf("error in malloc\n");
        return -1;
    }
    p3 = &p2[0];
    printf("ret is [%d]\n", foo(&p1) );
    printf("ret is [%d]\n", foo(&p2) );
    printf("ret is [%d]\n", foo(&p3) );
    
    return 0;
}
================================================================
运行结果打印2:
$ ./a.exe
ret is [0]
no memory to write
ret is [-1]
ret is [0]

================================================================

再看下一段代码:
源代码3:

int foo(char *input)
{
    if (input != NULL) {
        printf("input is [%s]\n", input);
        return 0;
    }
    else {
        printf("empty input\n");
        return -1;
    }
}
int main()
{
    char *p1   = "abcdefg";
    char  p2[] = "abcdefg";
    
    foo(p1);
    foo(p2);
    
    return 0;
}
================================================================
运行结果打印3:
$ ./a.exe
input is [abcdefg]
input is [abcdefg]
总结:
3. “数组名”和“指针变量名”在这种情况下有着一样功效。

综上:
1. { &数组名,数组名,&数组名[0] },这三者是同一个东西,都表示数组中第一个元素的地址值!!! 
2. “&数组名”的功能并不等价于“&指针变量名”,尤其要注意!!! 
3. “数组名”和“指针变量名”在这种情况下有着一样功效。

最后我想说,“数组名”和“指针变量名”在不同的情况下有不同的功效,所以流言被终结!

下面才是关键,为什么“数组名”和“指针变量名”有时候相同,有时候不同呢?
从第一份代码中,我们可以清楚的来了解这几个东西的具体意义到底是什么!


而第二份代码中,对于函数int foo(char **input),它期待调用者传入一个指针变量的地址值,并且这个指针变量要指向一段合法可读写内存,而不是NULL。换句话说,这个指针变量存储了那段合法可读写内存的首地址。话说得比较绕口。所以在这种情况下,传入“&数组名”和“&指针变量名”的意义就不同了,对吧!
有人说,我非得把数据弄到p2数组定义时的那块内存,有什么办法吗?答案是有的,还有两种!
第一种:

char *tmp = NULL;
tmp = p2;
foo(&tmp);

第二种:
char *tmp = malloc(1024);
foo(&tmp);
strncpy(p2, tmp, 1024);
free(tmp);

都达到了功效,把操作后的数据存入了p2的那块内存区,因为p2很可能是全局数组,所以才会有这种非要使用p2内存区的需求。


在第三份代码中,就体现了在传递参数时,“数组名”和“指针变量名”都是传递首地址值,所以相当于功效一样了。

文中难免出现错误,如果您发现了,请及时告诉我,我一有时间就会马上修改的,以免误导大家,谢谢!

转载于:https://my.oschina.net/michaelyuanyuan/blog/112390

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值