字符常量与变量
在这一节中,我们来讨论字符与字符串。
1. 字符常量
如果我想在屏幕上打印"HelloWorld"。应该怎样做呢?大家应该很熟悉这个代码了。
#include <stdio.h>
int main()
{printf("HelloWorld\n");return 0;
}
我们使用printf函数,第一个参数是需要输出的字符串。字符串用双引号包括。
不知道大家有没有考虑过,字符串是由什么组成的呢?没错,就是我们这一节讨论的字符了。
那如果我单独用字符来打印HelloWorld,将代码改为如下这样。
#include <stdio.h>
int main()
{printf("H");printf("e");printf("l");printf("l");printf("o");printf("W");printf("o");printf("r");printf("l");printf("d");printf("\n");return 0;
}
这样看上去是在单个单个的输出字符。但是,我们要注意,字符串是用双引号包括的。也就是说,这上面输出的仍然是字符串,只不过是只有一个可打印字符的字符串罢了。
那我们怎样,用单个字符的形式来输出呢?
定义:字符常量由单引号包括
类似于’a’ , ‘b’ , ‘c’ , ‘1’ , ‘2’ , ‘\n’。这样的都是字符常量。
'ab’这样的写法是错误的,字符常量只允许有一个字符。如果需要多个字符,请使用字符串"ab"。
那么,’\n’不是两个字符吗?是的,\n是两个字符,但是它代表的是换行符。我们C语言中,换行符没法直接打在代码当中。难道要像下面这样打出来?
'
'
而且,会和代码格式的换行弄混淆。所以,我们用\来表示转义,斜杠加字母的形式,表示为另一个意思。这样的字符有很多,例如,换行’\n’,退格’\b’,制表’\t’等等。
好的,那我们知道了,单引号包括的是字符,那我们这样打印行不行?
#include <stdio.h>
int main()
{printf('H');printf('e');printf('l');printf('l');printf('o');printf('W');printf('o');printf('r');printf('l');printf('d');printf('\n');return 0;
}
答案是不行的,这样会编译报错。为什么呢?printf的第一个参数必须是字符串。那如果是这样的话,我们考虑能不能用printf函数的占位符来给字符占位。然后,在printf的后续参数里面传入字符串呢。之前我们已经了解到了,整数用%d,浮点数用%f。那么字符用什么呢?
字符请使用转换方式%c。
#include <stdio.h>
int main()
{printf("%c%c%c%c%c%c%c%c%c%c%c", 'h', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd', '\n');return 0;
}
正如你看到的,%c可以用于给字符占位。
2. 字符类型与字符变量
有了字符常量,那我们肯定需要一种类型,来定义字符变量。
关键词char,是字符类型。
定义一个字符变量
char c1 = 'a';
char c2 = '1';
char c3 = '\n';
打印这三个变量
#include <stdio.h>
int main()
{char c1 = 'a';char c2 = '\n';char c3 = '1';printf("c1=%c c2=%c c3=%c", c1, c2, c3);return 0;
}
第一个%c被替换成了a,第二个被替换成了换行,第三个被替换成了1。
那么我们来看看,char这种类型的数据大小吧,用关键词sizeof。
好的,我们证实了,char都是1个字节的。
接下来,我们思考一个问题。事实上,我们在整型那一节中,已经见过char了,char也属于一种整型变量。而在printf那一节中,我们知道了对于变参函数的可变参数部分。比int小的整型类型,都会转换为int。所以,我们可以用%d来打印short类型。很显然,char是一个字节,肯定是比int小的。那么,我们也可以用%d来打印char。来看看,char里面所存储的数值是多少。
观察结果,a,b,c,d,e,居然是连续的。那我们有理由推测,字符和数值,存在某种联系。
是的,这种猜测是正确的。字符在计算机里面就是以数值形式存储的。关键是,你把它看做是字符,还是数值。
97,98,99,100,101如果你以%d打印,那么它们输出的是数值。如果你以%c打印,那么它们输出的是字符。那么,我们为什么还要char,字符类型char呢?int也可以呀。因为在早期,计算机只考虑了拉丁字符集,小写的a到z,大写的A到Z加上数字0到9,标点符号。全部加起来就127个。char的数值范围是-128到127,那么完全足够了。所以,不需要使用其它更大的类型来存储。
那我们来看一下这0-127数值与字符的对应关系吧。这个对应关系被称之为ASCII(American Standard Code for Information Interchange),美国信息交换标准代码。
图片来自百度百科
在表中,我们可以明确看到a对应97,b对应98,c对应99,d对应100,e对应101。和我们刚刚代码运行的结果一致。
3. 字符串
那么字符串,自然可想而知,就是由一个个字符组成的了。为了区分,字符串由双引号包括。例如:“HelloWorld”,“a”。
我们也来测试一下字符串的占用的空间大小。
HelloWorld一共10个字符,为什么sizeof测试出来的结果是11呢?
回答这个问题之前,我们先看下面的代码。
#include <stdio.h>
int main()
{printf("%s", "HelloWorld");return 0;
}
我们用%s来作为字符串的占位。
我们思考一个问题,为什么%s能打印HelloWorld完就结束了呢?它是怎么知道,我们这次输送的一共10个字符呢?我们来看一下字符串的内存组成。
这下是11个了吧。没错,C语言自动帮我们添加了结束的字符’\0’。我们尝试一下,将\0添加在字符串中间。会是一个什么效果。
没错,%s在解析的时候发现了’\0’就认为字符串结束了,所以world就没有被打印出来了。
那我们来看看’\0’和’\n’的数值是多少。
‘\0’对应的数值是0,’\n’,对应的数值是10。在ASCII表中,位置如下。
注意,千万不要将数值与字符搞混了。字符’0’的ascii码是48,而’\0’才是ascii的0。
'\0’被认为是结束符,而’0’被认为是普通的字符。
'\0’的数值为0,而’0’的数值为48。
最后,我们知道%号和\都被用作特殊用途了。一个被用于占位符的开始,一个被用于字符转义。那如果我们确实需要打印%号和\怎么办呢?
4. getchar、putchar函数
getchar函数用于从键盘读取一个字符。
putchar函数用于输出一个字符。
使用getchar的时候,输入完字符,请按回车键。
5. 中文字符串
C语言支持中文字符串,但是你会发现ASCII中没有中文。
早期在制定标准的时候,并且考虑到非拉丁字符。目前,计算机已经在全世界范围内使用。为了兼容早期的ASCII,高于127的数值,将会被用于其他语言字符。但是,这还是不够用于所有的非英文字符的。所以,中文字符会是由多个char组成。
在下面的例子中我们看到"你好"的空间大小为5。除去’\n’,那么就是每个中文汉字占用2个字节。