C语言中的单引号用来表示字符字面量
C语言中的双引号用来表示字符串字面量
'a'表示字符字面量,在内存中占一个字节,'a'+1表示'a'的ANSIC码加1,结果为'b';
"a"表示字符串字面量,在内存中占2个字节,"a"+1表示指针运算,结果指向"a"结束符'\0'。(是一个内存地址,是一个指针值)
下面的代码合法吗?
char* p1 = 1; //1 低地址
char* p2 = '1'; //31 低地址
char* p3 = "1"; //高地址
需要注意的是:
0x 0804 8000 //低于这个地址,是不能随便访问的,会造成段错误。
所以上面代码在C语言编译器上基本上合法的,会引起警告,但是不会影响程序运行。
试图打印上述字符指针:
printf("%s, %s, %s \n", p1, p2, p3);
delphi@delphi-vm:~/will$ ./a.out
段错误
注意:
字符字面量被编译成对应的ANSIC码;
字符串字面量被编译成对应的内存地址
printf的第一个参数被当成字符串的内存地址;
内存的低地址空间不能在程序中随意访问。
同样的,下面的代码也会 出现段错误:
//printf('\n'); //low address
可修改代码为:
printf("%c\n", '\n'); //有一个合法的地址来访问转义字符
或:
printf("\n");
实例分析:混淆概念的代码
int main()
{
char c = " "; //c的值为“ ”的内存地址
while( (c == "\t") || (c == " ") || (c == "\n") )
{
scanf("%c", &c);
}
return 0;
}
运行后while循环并没有得到执行,那么
char c = " ";
这行代码执行后,发生了什么?
分析:
1、编译后字符串“string”的内存地址被赋值给字符变量c;
2、内存地址占用4个字节,字符变量c占用1个字节;
3、类型不同,赋值后发生截断。
所以,上述代码犯的错误是混淆了字符和字符串的概念。
单引号是对对应字符的ANSIC码进行操作。
而双引号是对对应字符串的内存地址进行操作。
将双引号改为单引号:
int main()
{
char c = ' ';
while( (c == '\t') || (c == ' ') || (c == '\n') ) //【和对应字符的ASCII码进行比较】
{
scanf("%c", &c);
}
return 0;
}
小结:
单引号括起来的单个字符代表整数;
双括号括起来的字符串表示字符串指针;
C编译器接收字符和字符串的混合比较,但是没有意义;
C编译器也允许字符串对字符变量赋值,但只能得到错误。