1. 以字符串形式出现的,编译器都会为该字符串自动添加一个0作为结束符。
如在代码中写"abc",那么编译器帮你存储的是"abc\0"。
2. "abc"是常量吗?
答案是有时是、有时不是。
不是常量的情况:"abc"作为字符数组初始值的时候就不是,如:
char str[] = "abc";
因为定义的是一个字符数组,所以就相当于定义了一些空间来存放"abc",又因为字符数组就是把字符一个一个地存放的,所以编译器把这个语句解析为
char str[3] = {'a','b','c'};
又根据上面的总结1,所以char str[] = "abc";的最终结果是:
char str[4] = {'a','b','c','\0'};
做一下扩展,如果char str[] = "abc";是在函数内部写的话,那么这里的"abc\0"因为不是常量,所以应该被放在栈上。
是常量的情况: 把"abc"赋给一个字符指针变量时,如:
char* ptr = "abc";
因为定义的是一个普通指针,并没有定义空间来存放"abc",所以编译器得帮我们找地方来放"abc",显然,把这里的"abc"当成常量并把它放到程序的常量区是编译器最合适的选择。所以尽管ptr的类型不是const char*,并且ptr[0] = 'x';也能编译通过,但是执行ptr[0] = 'x';就会发生运行时异常,因为这个语句试图去修改程序常量区中的东西。
记得哪本书中曾经说过char* ptr = "abc";这种写法原来在c++标准中是不允许的,但是因为这种写法在c中实在是太多了,为了兼容c,不允许也得允许。虽然允许,但是建议的写法应该是const char* ptr = "abc";这样如果后面写ptr[0] = 'x'的话编译器就不会让它编译通过,也就避免了上面说的运行时异常。又扩展一下,如果char* ptr = "abc";写在函数体内,那么虽然这里的"abc\0"被放在常量区中,但是ptr本身只是一个普通的指针变量,所以ptr是被放在栈上的,只不过是它所指向的东西被放在常量区罢了。
3. 数组的类型是由该数组所存放的东西的类型以及数组本身的大小决定的。
如char s1[3]和char s2[4],s1的类型就是char[3],s2的类型就是char[4],
也就是说尽管s1和s2都是字符数组,但两者的类型却是不同的。
4. 字符串常量的类型可以理解为相应字符常量数组的类型。
如"abcdef"的类型就可以看成是const char[7]。
5. sizeof是用来求类型的字节数的。
如int a;那么无论sizeof(int)或者是sizeof(a)都是等于4,因为sizeof(a)其实就是sizeof(type of a)。
6. 对于函数参数列表中的以数组类型书写的形式参数,编译器把其解释为普通的指针类型。
如对于void func(char sa[100],int ia[20],char *p)
则sa的类型为char*,ia的类型为int*,p的类型为char*
7. 根据上面的总结,来实战一下。
对于char str[] = "abcdef";
就有sizeof(str) == 7,因为str的类型是char[7],也有sizeof("abcdef") == 7,因为"abcdef"的类型是const char[7]。
对于char *ptr = "abcdef";
就有sizeof(ptr) == 4,因为ptr的类型是char*。
对于char str2[10] = "abcdef";
就有sizeof(str2) == 10,因为str2的类型是char[10]。
对于void func(char sa[100],int ia[20],char *p);
就有sizeof(sa) == sizeof(ia) == sizeof(p) == 4,因为sa的类型是char*,ia的类型是int*,p的类型是char*。
8.使用cin输入字符串的相关问题
8.1 cin 使用空白(空格、制表符和换行符)来定字符串的界
这意味着cin在获取字符数组输入时只读取一个单词,在读取该单词后,cin将该字符串放到数组中,并自动在结尾添加空字符。后一个字符串将不会输入到数组中。
8.2 当输入字符串可能比目标数组长时,将不能防止例如将包含30个字符的字符串放到20个字符的数组中的情况。
9.面向行的读取还不是面向单词
9.1 getline()
getline()读取一行的输入,直到到达换行符,并丢弃换行符。它有三个参数:数组名称、要读取的字符长度、第三个参数为XXX
如果为20,则函数最多读取19个字符,余下的空间用于存储空字符!!!注意!!!!
9.2 get()
get()有三个参数的版与getline()意思差不多,...,将换行符保留在输入序列中,不通过一定的手法,get()将不能通过最后的换行符!!!!如此这样使用:
cin.get(name,size);
cin.get();
cin.get(name2,size2);
9.3空行和其他问题
当getline()和get()读取空行时怎么办?思考。。。
9.4 对于一个未被初始化的字符串,其内容是随机的,也就有可能出现空字符\0!!!!要先初始化!!!
9.5向string中输入一行字符
getline(cin,string);//向string中输入一行
cin.getline(array,size);//向普通数组中输入一行