数组名和字符串指针的那些事
来源:互联网 发布:区间交易软件 编辑:程序博客网 时间:2024/05/17 03:34
写在前边:
都说数组名和字符指针可以混用,其实这是个很片面的说法,下面为你详细解释一下:
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)下测试通过
都说数组名和字符指针可以混用,其实这是个很片面的说法,下面为你详细解释一下:
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)下测试通过
- 数组名和字符串指针的那些事
- 指针和数组名及字符串的区别
- 字符数组名与字符串指针变量名的区别
- 数组名 和 指针
- 数组名和指针
- 数组名和指针
- 数组名和指针
- 数组名 和 指针
- 数组名和指针
- 数组名和指针
- 数组名和指针
- 指针和数组名
- 指针和数组名
- 数组名和指针
- 指向数组的指针&数组名和指针的区别
- 指针那些事(算术运算、和数组的关系)
- 数组名和数组名取地址、指针数组和数组指针的区别
- 字符串与指针,数组名
- Tomcat自定义错误页面
- ext4 笔记三(结构体描述)
- vim在新建文件时插入模板文件的内容
- 每天一算法(巴斯卡三角,又称杨辉三角),复习一下下
- OpenStack系列讲座4:OpenStack在CentOS 5.6下的安装
- 数组名和字符串指针的那些事
- 广州查处多处蓝月亮假厂
- SpringMVC + ajaxfileupload的多文件上传
- 进程的定向输出
- 【小蒙淘金】你不知道的“黄金故事”
- 第一个函数SystemInit()里面有些啥
- Objective-c里各种布尔类型什么区别
- Java引用类型
- Model/View Programming