1.表现形式:由双引号括起来,以‘\0’(00)结尾
2.占位符:%s
3.存储形式(两种):
存储在常量区:存储在常量区中的字符串在声明时即赋值,赋值后字符串不可修改
==>内存结构(分为四个区):
1)栈区(数据:临时数据)
存放函数的返回地址、函数的值、参数等等
2)堆区(数据:需要长期使用的数据)
是由程序员控制的一块区域
3)代码区(算法)
不可更改的
4)常量区(数据:不可修改)
存放一些不可修改的数据
扩展:
数值(如int num=48),并不存在于常量区,它是字面值(所见即所得,所有的数字都是字面值)
“Hi!你的名字是?”其中的文字看起来也是字面值,但是它是存在于常量区的
=>它是由字符组成的,虽然字符也是数值,但是与十进制、十六进制有着很大的区别:这些数值代表的意义是一个一个的字符
=>这个字符串不可更改(以后可用指针进行测试),如果我们需要一个能够被修改的字符串怎么办?
以数组方式进行存储(存储在栈区):以下标的方式进行访问,以‘\0’结尾=>把字符存储于数组(同一个数据的集合:如char name[40])中,会存放在栈区
=>声明中的变量(40)是规定数据的长度
数组:数组名即是这段空间的地址,通过下标可以定位到当前数组所指定的元素
=>元素:例如:给数组分配了40个空间,我们就说当前数组存在40个元素(注:元素标号从0~39)
4.用scanf接收外部输入的字符串:
当输入的字符串大于规定的长度时,scanf输入并没有报错
存储名字的数组我们刻意设置成了只可以存储3个字符,但是在运行时,我输入了10个1,程序无碍的向下执行了!那么超过长度的字符去哪了呢?
它会向下覆盖,如果被覆盖的值是有用的,那么这种行为就很危险了,会使程序出现不可知的错误
如上图,在程序执行scanf前,查看数组char name[3]的内存,其地址是0x0040F930,连续的3个byte已经初始化为0(上图左)。我们可以发现,在0x0040F938~0x0040F93C这一段内存存有一些值(并不是无效值,关于那些cc,在VS的Debug下,为了方便程序员查找错误,会将未初始化的变量赋值为cc),但是,在执行scanf之后,对于超长的字符,是直接往下覆盖,修改了原来的值(上图右),继续执行,结果如下:
程序发生了中断
解决方法:
1.将数组的大小定为MAXBYTE ,但是这样做很浪费空间
2.用scanf("%s",name,sizeof(name)); 在接收的时候判定所接收字符串的大小是否符合,但是,限制用户输入这种方法比较不妥
3.先动态分配内存,在用户输入完成后再用另一块内存进行处理