数组名和字符串指针的那些事

写在前边:
都说数组名和字符指针可以混用,其实这是个很片面的说法,下面为你详细解释一下:


  1 #include <stdio.h>
  2
  3 int main()
  4 {
  5     char a[30] = "ASDASD";
  6     a[3] = 'g';
  7     printf("a is %s\n",a);
  8     return 0;
  9 }
编译通过并执行:
输出:a is ASDgSD
这段代码很容易理解吧,就是简单地字符串数组某一个元素的修改。


  1 #include <stdio.h>
  2
  3 int main()
  4 {
  5     char *a = "ASDASD";
  6     a[3] = 'g';
  7     printf("a is %s\n",a);
  8     return 0;
  9 }
编译通过并执行:
输出:Segmentation fault (core dumped)
奇怪了吧,不是说数组名和字符指针功能相同吗?
其实,我个人认为,这主要是变量定义的时候,空间内存的问题,也就是存储位置的问题。
第一个代码里,数组变量存储的空间在栈上,并且字符串"ASDASD"是一个连续存储的变量,
而第二段代码中的字符串"ASDASD"是字符串常量,存储在文字常量区,你去修改一个常量的值,当然是不行的了。
*********************************************************************************************
  1 #include <stdio.h>
  2
  3 char *func()
  4 {
  5     char a[20] = "ASDASD";
  6     return a;
  7 }
  8
  9 int main()
 10 {
 11     char *recv;
 12     recv = func();
 13     printf("recv is %s\n",recv);
 14     return 0;
 15 }
编译时会有警告:warning: function returns address of local variable
但仍可以执行:recv is  -(


别急,看这个程序:
  1 #include <stdio.h>
  2
  3 char *func()
  4 {
  5     char *a = "ASDASD";   //就这一点差别,警告都没有了
  6     return a;
  7 }
  8
  9 int main()
 10 {
 11     char *recv;
 12     recv = func();
 13     printf("recv is %s\n",recv);
 14     return 0;
 15 }
运行结果当然是你期待的:
recv is ASDASD
为什么会这样呢?其实还是存储方式的不同,字符串数组变量在函数结束时就不存在了,而字符串指针
在函数消失的的时候也不见了,但是它所指向的字符串还在常量存储区里。
是不是又有点晕了,别急,再看看这个
*************************************************************************************
  1 #include <stdio.h>
  2 #include <string.h>   //之所以加这个库是因为字符串数组没有办法用=直接赋值,这也是不同点之一了
  3
  4 char *func(char a[])
  5 {
  6     strcpy(a,"ASDASD");
  7     return a;
  8 }
  9
 10 int main()
 11 {
 12     char recv[10];
 13     func(recv);
 14     printf("recv is %s\n",recv);
 15     return 0;
 16 }
编译通过并执行:
recv is ASDASD


  1 #include <stdio.h>
  2
  3 char *func(char *a)
  4 {
  5     a = "ASDASD";
  6     return a;
  7 }
  8
  9 int main()
 10 {
 11     char *recv;
 12     func(recv);
 13     printf("recv is %s\n",recv);
 14     return 0;
 15 }
编译通过并执行:
猜猜结果是什么?一样吗?
结果:recv is |?;
我去,这是什么玩意?我也没见过,但是至少有一点是肯定的,出麻烦了。(貌似是废话哈,别介意,调节一下紧张的气氛嘛)
我就觉得,字符串指针和字符串数组保持着高度的一致性对外性就是,差不多功能的程序总会有一个有问题(是不是K&R故意玩我们的)
接下来我们分析一下为什么会出现这种情况:
第一个程序应该很好理解吧,在main函数没有结束之前,字符数组recv一直可以使用,
所以改变了其中的值是可以反映出来的,对吧(在这里我想很友好的提一句传值和传址的区别,另附上程序一枚)
  1 #include <stdio.h>
  2
  3 int func(int n)
  4 {
  5     n = 9;
  6     return n;
  7 }
  8
  9 int main()
 10 {
 11     int m = 0;
 12     func(m);
 13     printf("m is %d\n",m);
 14     return 0;
 15 }
我们来看看第二个为什么不行,事实上,在进入函数之前,recv不知道指向哪里,出来函数的时候,
recv依然不知道指向哪里,因为func函数没有对recv做任何操作,只是对它的拷贝a操作了。
我们这样修改一下函数
  1 #include <stdio.h>
  2
  3 char *func(char **a)
  4 {
  5     *a = "ASDASD";
  6     return *a;
  7 }
  8
  9 int main()
 10 {
 11     char *recv;
 12     func(&recv);
 13     printf("recv is %s\n",recv);
 14     return 0;
 15 }
编译并运行:
recv is ASDASD
看到了什么?
有那么一点传值和传址的韵味吧?
*********************************************************************************
以上均为本人愚见,希望大家批评指正。代码在Linux环境下C99标准下gcc (GCC) 4.4.4 20100726 (Red Hat 4.4.4-13)下测试通过
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值