加载中…
个人资料
狼骑
狼骑
  • 博客等级:
  • 博客积分:0
  • 博客访问:1,391
  • 关注人气:18
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

C/C++中的单引号

(2012-07-03 22:42:55)
标签:

it

分类: c

http://blog.csdn.net/qiyuan2009/article/details/4140163

 

昨天群里一个朋友问了一个问题,

这个语句输出什么?当时看到他在一个单引号里放这么多字符,甚是荒唐,没去搭理他。他依然持续地在那求助。然后他又打上一段话:为什么我使用了8个/后编译器才报错,而之前编译器一直都没反应?这种状况立马引起了我的兴趣。我也感到不解。如果说在单引号内放置多个字符本来就是错误的——无论是逻辑上还是本质上,那么编译器为何偏偏要到有了8个/(实际上就4个/——ASCII字符)时才报错呢?我也赶紧编写了一个试验程序,果然如此,甚是不解。

    于是找了一下C的基础结构中关于单引号的描述。一个”新奇“的说法出现在我的面前:单引号只是起到定界的作用。这比我平日里对单引号的理解宽泛,深入得多。单引号不仅仅用来表示一个字符,实际上,它是对内存的一种直接展示。我们可以看看例子:

  1. int a1 '/1/0/0/0' 
  2. int a2 '/0/1/0/0' 
  3. int a3 '/0/0/1/0' 
  4. int a4 '/0/0/0/1' 
  5.   
  6. cout << "a1 is: " << a1 << endl;  
  7. cout << "a2 is: " << a2 << endl;  
  8. cout << "a3 is: " << a3 << endl;  
  9. cout << "a4 is: " << a4 << endl;  

输出:

  1. a1 is 
  2. a2 is256  
  3. a3 is65536  
  4. a4 is16777216  

对于上面的结果你有何看法呢?

你可以判断出我的机器的cpu是intel的。intel的little-endian存储方式决定了以上的输出结果。比如a1,它的内存表示是(从低位内存到高位):

第一字节:0000 0001

第二字节:0000 0000

第三字节:0000 0000

第四字节:0000 0000

以上是真实的内存展示。但是由于little-endian的原因,这段内存表示的int型的值为1. 所以a1的值就是1.其他的也是如此。

好,我们继续回到putchar上来。从以上分析我们知道,往putchar传'//t'这样的值是合法的,它表示一个16位的单位,其中第一个字节为/所对应的ASCII码值,第二字节对应地是t的ASCII码值。当把它传递给putchar时,就是把一个16位的单位传给putchar(我们姑且认为是一个short类型吧,O(∩_∩)O~)。由于putchar接受int型的形参,故此单位提升到int型,即32位。然后在putchar内部做截断,再输出。也因为如此,当你传入8个/和一个t(即'////////t')时,此时的五个字节自然超出int的范围,故而报错。(此时编译器的报错信息很有意思,我也是搞不懂)。

关于如何截断,刚开始我一直以为会把高位的三个字节去掉。比如对于'abcd'来说,输出的便是字母d。但是对于'////t'这样的组合,输出竟然是/。真是莫名其妙了,实在想不通。

 

http://topic.csdn.net/u/20110610/01/09d7bcb7-8a93-4014-91f2-3053923d589e.html

C/C++ code
#include
<stdio.h>
void main() { //char c='abcde';
  

 
//char c='abcd';
 

 
char c='abc';
 

  printf(
"%c\n",c);
}

相关链接
http://blog.csdn.net/qiyuan2009/archive/2009/04/30/4140163.aspx
http://zhidao.baidu.com/question/28843588.html?fr=qrl&cid=866&index=1&fr2=query

求解释:出现错误警告的详细原因。关于变量的初始化的详细过程(从程序开始,初值的处理,类型的处理,相关动作)
是缓冲区的原因(申请一个字节,所以编译器读取后面的字符把前面的覆盖了,为嘛多余四个字符报错?)
还是char类型引发的截取部分内存的原因?为嘛多于四个字符报错
C/C++ code
#include<stdio.h>void main() { //char c='abcde'; //char c='abcd'; char c='abc'; printf("%c\n",c); }


相关链接
http://blog.csdn.net/qiyuan2009/archive/2009/04/30/4140163.aspx
http://zhidao.baidu.com/question/28843588.html?fr=qrl&cid=866&index=1&fr2=query

求解释:出现错误警告的详细原因。关于变量的初始化的详细过程(从程序开始,初值的处理,类型的处理,相关动作)
是缓冲区的原因(申请一个字节,所以编译器读取后面的字符把前面的覆盖了,为嘛多余四个字符报错?)
还是char类型引发的截取部分内存的原因?为嘛多于四个字符报错

仔细查了下标准,贴个标准的解释吧:
An ordinary character literal that contains more than one c-char is a multicharacter literal. A multicharacter literal has type int and implementation-defined value.
既然是int值,那也就是32bit了,超过4个字节那就不是int了吧

 

单引号、双引号区别

C语言中的单引号和双引号含义迥异,用单引号引起的一个字符实际上代表一个整数,整数值对应于该字符在编译器采用的字符集中的序列值,因此,采用ASCII字符集的编译器而言,‘a’的含义与0141或97严格一致。而用双引号引起的字符串,代表的却是一个指向无名数组起始字符的指针,该数组被双引号之间的字符以及一个额外的二进制值为零的字符‘\0’初始化。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有