第10课 - 单引号和双引号
例子:
#include <stdio.h>
int main()
{
char* p1 = 1 ;
char* p2 = '1';
char* p3 = "1";
printf("%s, %s, %s", p1, p2, p3);
printf(' ');
printf(" ");
return 0;
}
这段程序运行起来,会显示段错误。原因是发生在第一个printf语句
p1指向1,也就是指向内存地址为1的地方。p2指向’1’,是个字符。1的ASCII对应的是49,也就是p2指向内存49的地方。p3指向了一个字符串常量。对于低地址保留起来给系统使用的,也就是没有我们要的字符串。p1和p2是野指针。p3可以打印出来1。
printf(),可以看成是给一个指针赋值。printf(' ');就是将指针赋值 , 的ASCII码是10,在低地址位置的内存是留给系统的,所以这个指针也是野指针,出现错误。
l C语言中的单引号用来表示字符常量。
‘a’表示字符串,在内存中占1个字节。
‘a’+1表示’a’的ASCII码加1,结果为’b’。
l C语言中的双引号用来表示字符串常量。
“a”表示字符串常量,在内存中占2个字节。
“a”+1表示指针运算,结果指向”a”结束符’ ’。
易混淆的代码
#include <stdio.h>
int main()
{
char c = " ";
while( c==" " || c==" " || c==" " )
{
scanf("%c", &c);
}
return 0;
}
这段程序的本意是,当键盘输入回车、空格、tab时就继续扫描键盘,否则结束。我们的c被初始化为空格,但是程序运行起来,直接就结束了。也就是说,我们的while循环,始终没有得到运行。因为,我们将一个字符串赋值给了一个字符。
但是这个程序在编译时候还是能够通过的。现在我们看一下,讲一个字符串赋值给一个字符会发生什么。字符串是保存在一段地址中的,编译器会把这段32位的地址,赋值给8位的变量,而且会强制把后面的两位给变量。我们上一段程序中给的内容是一个数值,并不是空格,所以while循环永远不会得到运行。我们作如下的修改就好。
#include <stdio.h>
int main()
{
char c = ' ';
while( c== ' '|| c== ' ' || c== ' ' )
{
scanf("%c", &c);
}
return 0;
}
我们要注意,当编译器发出警告的时候,我们除非在必要的条件下,否则我们要当做出错一样去处理。
小结:
(1) 本质上单引号括起来的一个字符代表整数。
(2) 双引号括起来的字符代表一个指针。
(3) C编译器接受字符和字符串的比较,可意义是错误的。
(4) C编译器允许字符串对字符变量赋值,其意义是可笑的