一丶字符数组
定义:用来存在字符量的数组就叫字符数组
形式:char[]/中括号中间有数字表示数组的长度。
初始化:可以通过字符串子面值进行初始化,也可以通过字符子面值进行初始化。
- char a[] = "hello,devin";//长度为12 char a1[10] = "hello";//长度为10 char a2[] = { 'h','e','l','l','o',',','d','e','v','i','n' };//长度为11
注意上面的a[]跟a1[]是c风格的字符串,C风格字符串,是指以\0结尾的字符数组。因此在给字符数组初始化时,会默认的在字符数组的尾部添加'\0',因此sizeof(a)会是12,而不是11。但是用strlen函数时,计算的是字符串的实际长度,而不包括'\0'。而且当字符数组定义之后,不能对整个字符数组赋值,只能对字符数组
元素定义。
在输出时,对于c风格的字符数组直接使用cout(a)就可以输出整个字符数组,但是对于不是c风格的a2来说,直接用cout会导致意想不到的后果。
二丶字符指针
可以使用char *str指向一个字符串,如
- char *ptr = "devin"; char strArr[] = "handsome"; char *ptr2 = strArr;
使用cout<<ptr即可以输出整个字符串,使用cout<<*ptr输出字符串的第一个字符。
三、区别
- char s[]="abc";
- char *ptr="abc";
- cout<<s<<endl; // abc
- cout<<*s<<endl; // a
- cout<<&s<<endl; // 地址
- cout<<(s+1)<<endl; // bc
- cout<<*(s+1)<<endl; // b
- cout<<&s[1]<<endl<<endl; // a
- cout<<ptr<<endl; // abc
- cout<<*ptr<<endl; // a
- cout<<&ptr<<endl; // 地址
- cout<<(ptr+1)<<endl; // bc
- cout<<*(ptr+1)<<endl; // b
- cout<<&ptr[1]<<endl; // a
这是他们的相同点,可以看出都是指向字符串的指针。
下面的代码是区别
原因在于两种方式对字符数组操作的机制不同。使用char *p="C++"语句后,编译器在内存的文字常量区分配一块内存,保存”C++“这一字符串
- char ss[]="hello";
- ss[0]='c'; // 合法
- char *p="hello";
- p[0]='c'; // 合法但不正确
字面值,然后在栈上分配内存保存p,p的内容为"C++"的地址。p[0]='c'试图修改常量”C++“,程序当然就会崩溃了。而char ss[]="C++"语句,定义了
一个数组,编译器为其在栈上分配了内存空间,因而可以进行修改操作。
因此,可以总结如下:
(1)char ss[]定义了一个数组,ss可认为是一个常指针,ss不可改变,但ss指向的内容可以发生改变。
(2)char *p定义了一个可变指针,p可以指向其它对象。但对于char *p=”abc“这样的情况,p存储的是一个地址,如果内容改变,就不是指向之前
的位置。
综上,可以看出使用char []较容易出错,可能出现不确定的结果。C++提供的string类相比之下,要安全的多了