1.用于存储字符的数据类型
C语言中用char类型来存储单个字符,如char a='A'(注意:单个字符要用单引号括住),而一个字符数据占用的内存空间是一个字节。实际存放的数值不是字符本身,而是字符的ASCII值编码。
下图为单个字符和十进制的转化关系:
如:
#include<stdio.h>
int main()
{
char a=65;
printf("%c",a);
}
//当以%c格式(即以单个字符输出)输出时输出结果为A
#include<stdio.h>
int main()
{
char a='A';
printf("%d",a);
}
//当字符'A'以%d格式输出时,即以十进制表示,输出为65
常见错误:1.用 " "来接收字符:如char a="A",用双引号标识时,编译器会识别为字符串类型,而字符串类型的存储方式为存储首元素地址,所以用char*(字符指针类型)即char* a="A"来表示时,则不会出错。当然此时的输出方式也会发生变化。
#include<stdio.h>
int main()
{
char* i ="a";
printf("%s",i);
return 0;
}
//以这种方式输出没有问题
#include<stdio.h>
int main()
{
char* i ="a";
printf("%c",i);
return 0;
}
//这时便会出现问题
这是为什么呢?
因为用"%s"输出时会自带解引用的功能,即能从地址中找到数据,而"%c"不具有此功能。
所以只需如此代码便可成功运行,其中*便起到了解引用作用
#include<stdio.h>
int main()
{
char* i ="a";
printf("%c",*i);
return 0;
}
推广:对于一个长字符串,我们便可以利用这种方式访问到里面的各种字符,如:
#include<stdio.h>
int main()
{
char* i ="abcdef";
printf("%c\n",*i);
printf("%c",*(i+1));
return 0;
}
//输出为:
a
b
所以我们可以通过指针的加减来访问到各个字符,因为char*类型指针为一个字节,所以+1便能跳过一个字节的地址,如从2000->2001,从而访问到字符b的地址,进而打印出字符b。
2.字符串的存储方式
因为C语言中没有用来存储字符串的类型数据,因此我们用另外的方式表示
由上面已经得到一种方法。
1.用指针存储
char* a ="abcdef";
接下来介绍另一种方法:
2.用数组存储!即:
char arr[]="abcdef"
char arr[]={"abcdef"}
以上两种方式都可以。
打印:
#include<stdio.h>
int main()
{
char i[] = "abcdef";
printf("%s",i);
return 0;
}
注意:此时数组名i表示的是首元素地址,与第一种存储方式的变量名(char* a="abc";a为变量名)的数据类型一样。
常见错误:
char i[3]="abc";
咋一看没有错误,但是编译器时却出现了问题,这是为什么呢?
这是便要讲讲字符串的存储方式。
字符串:"abc"并不是单纯的只存放"abc",而是在字符串的末尾会自动加上'\0',作为结束标志,
'\0'作为一个转义字符也需占据一个字节空间,因此字符串"abc"占据的是四个字节,当只给他分配三个空间时,'\0'无法存储,便会导致打印字符串时找不到结束标志,因此只能越界寻找,直到找到0才结束,便会出现以下状况。
方法三 :
char i[3] = {'a','b','c'};
以单个字符 存储时,即上面的方式,此时不会在末尾加上'\0',因此理论上这样存储可以,但打印时便会出现和上面一样的状况,所以我们最好自己补上'\0';如:
#include<stdio.h>
int main()
{
char i[3] = {'a','b','\0'};
printf("%s",i);
return 0;
}
但却可以如下图表示
注意:此时i中并无存储'\0' ,运行成功可能是编译器的调错功能。