6154|21

2804

帖子

0

TA的资源

五彩晶圆(初级)

楼主
 

【每周讨论】C语言简单问题-但是你不一定能回答正确-0829 [复制链接]

#include <stdio.h>
int main()
{
char *p="abcdef"; //很多书上说:p在栈,“abcdef”在数据区
p[2]='W';
printf(p);
getchar();
return 0;
}
这个程序编译通过,但是问什么程序运行会出错?

另一个:
#include <stdio.h>
int main()
{
char s[]="abcdef";//s在栈,“abcdef”在数据区
s[2]='W';
  printf(s);
getchar();
return 0;
}
这个程序能够正常输出!


请问这是为什么?
p,s和“abcdef”分别在那个区?

最新回复

 似乎不少筒子比较专注从语法找毛病,其实语法应该是对的,这只是嵌入式的特殊性问题,在不同环境下没准情况都不一样。假如程序放在有OS的PC上执行,过程是  1、把代码从磁盘拷贝到RAM  2、执行代码 那么不会有问题,因为反正所有代码都在RAM里,没有一部分数据可读写,另一部分只可读不可写之分。(系统保护另当别论。)    但在不带OS的嵌入式系统里,程序往往在只读存储器(EPROM、Flash ROM等)里被直接执行,于是对存放于这个区域里的数据存取就有了限制,因硬件不支持写操作,软件执行写也白写,所以编译器为方便使用,减少编程错误起见,定义了一些只读区域,如果程序里有对该区域进行写操作时就报错。    以前做过几个H8和SH程序,它的编译环境默认有以下4个区: P:程序指令码区 C:常数数据区 B:已初始化数据区 D:未初始化数据区 链接默认P、C在ROM里,B、D在RAM里,程序对P、C区自然是不能写的。不过区域位置设置可以任意改,也可另加区域名,当然改错了自己负责。有人说嵌入式难,难在没OS帮忙什么都得自己打理;也有人说嵌入式灵活,灵活在没了OS限制,程序员想咋做都行,只要充分理解了系统。  详情 回复 发表于 2011-9-2 10:46
点赞 关注
个人签名QQ:1625345502
 
 

回复
举报

3138

帖子

0

TA的资源

裸片初长成(初级)

沙发
 
 前者的*p指向已被初始化的数据区,被有些嵌入式链接器默认为不可更改的ROM区,因此往里写就出错了。
 
 
 

回复

381

帖子

0

TA的资源

纯净的硅(高级)

板凳
 
char *p 不是单个字符指针么?  "abcdef" 字符串啊?这个指向有问题吧

char s[] 是没定长度的数组,那么就是可以往里面塞多个字符吧
 
 
 

回复

6

帖子

0

TA的资源

一粒金砂(中级)

4
 
char *p="abcdef";   // "abcdef"是只读数据区的字符串常量,p指向这个字符串
char s[]="abcdef";  // 这个是数组声明,并初始化。相当于
char s[7] = {'a', 'b', 'c', 'd', 'e', 'f', '\0'};

两个是完全不同的概念!
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(中级)

5
 
支持4楼的解释
 
 
 

回复

242

帖子

0

TA的资源

纯净的硅(中级)

6
 
顶楼上的
 
 
 

回复

36

帖子

0

TA的资源

一粒金砂(中级)

7
 
4楼说的很对~
 
 
 

回复

36

帖子

0

TA的资源

一粒金砂(中级)

8
 
char *p="abcdef"; // "abcdef"是只读数据区的字符串常量,p指向这个字符串
char s[]="abcdef"; // 这个是数组声明,并初始化
字符常量不能改变~
 
 
 

回复

422

帖子

0

TA的资源

纯净的硅(高级)

9
 

回复 楼主 wanghongyang 的帖子

谢谢了!我回来的时候正考虑今天的每周讨论该怎么办呢,上来一看,你已经出了,太好了,谢谢!
 
 
 

回复

422

帖子

0

TA的资源

纯净的硅(高级)

10
 

原帖由 wanghongyang 于 2011-8-29 09:35 发表 #include int main(){char *p="abcdef"; //很多书上说:p在栈,“abcdef”在数据区p[2]='W';printf(p);getchar();return 0;}这个程序编译通过,但是问什么程序运行会出错?另一个:#include int m ...

 

这题目以前是不是出过啊!

 
 
 

回复

43

帖子

0

TA的资源

纯净的硅(初级)

11
 
很好的问题,C语言真是博大精深啊!实际调试了一下,屏蔽p[2]='W';就运行正常了,同意2楼的见解
 
 
 

回复

353

帖子

0

TA的资源

五彩晶圆(中级)

12
 
还真的没有注意过这些细节,哎,不精啊
 
 
 

回复

350

帖子

0

TA的资源

纯净的硅(中级)

13
 
这个问题我以前研究过,数组名不是一般的指针,是常量指针,而我们定义的p访问的是常量字符串,只能返回地址,不能修改里面的值,不信可以printf("%p",p);看所指向的地址,而第二个实现是数组,数组的实现是定义并且初始化一系列连续的内存。数组才在栈中!
 
 
 

回复

350

帖子

0

TA的资源

纯净的硅(中级)

14
 
1、栈区(stack)     由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap)      一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static),全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放
4、文字常量区    ?常量字符串就是放在这里的。 程序结束后由系统释放
5、程序代码区?存放函数体的二进制代码。
 
 
 

回复

29

帖子

0

TA的资源

一粒金砂(中级)

15
 
4楼正解
 
 
 

回复

9

帖子

0

TA的资源

一粒金砂(中级)

16
 
同意4楼的
 
 
 

回复

6

帖子

0

TA的资源

一粒金砂(中级)

17
 
给那个指向字符串的指针开辟空间应该就没有问题了 (char *)malloc(sizeof(char) *7)
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(中级)

18
 
ANSI C标准不允许这种方法,可能会导致内存访问错误。K&R C对这一问题的解释是试图修改字符串常量的行为是未定义的。有些编译器允许这种方法。为了避免出错,在这种情况下定义指针时应加上const修饰符,提示该指针指向的字符串不可修改。如果需要修改,用字符串文字来初始化一个非const的数组,因得到先前字符串的一个拷贝,所以不会出现问题。
 
 
 

回复

67

帖子

0

TA的资源

一粒金砂(中级)

19
 

回复 楼主 wanghongyang 的帖子

我比较认同十八楼的观点,关于四楼的观点,我又查阅了谭浩强的C语言,上面一般都是先定义一个地址,然后用一个指针指向这个地址,以前用avr的时候总是不懂const怎么来的,今天懂了
 
 
 

回复

12

帖子

0

TA的资源

一粒金砂(中级)

20
 

同意4楼的说法

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表