字符数组

 1 #include <iostream>
 2 using namespace std;
 3 int main(){
 4     char* a = "abcd";
 5     char b[5] = "ABCD";
 6     cout << a << endl;//输出"abcd",说明a就是这个字符串名,输出内容
 7     cout << *a << endl;//输出'a',代表a也是字符串第一个字符的地址,
 8     cout << b << endl;//输出“ABCD”整个字符,说明b是字符串名,输出内容
 9     cout << *b << endl;//输出'A',说明b也是指向第一个字符的地址
10     cout << b+1 << endl;//输出“BCD”,b指向字符串的首地址,+1表示首地址向后移了一位,还是输出之后的字符串
11     a=b;//把b指向的首地址给了a,此时a就是ABCD的字符串名
12     cout << *a << endl;//输出第一个字符的内容,'A'
13     cout << a << endl;//输出整个字符串 "ABCD"
14     cout <<  b << endl;//"ABCD"
15     return 0;
16 }

 

首先 这两种类型都可以对应一个字符串,很多时候二者可以混用。

函数形参可以是char[]可以是 char *。

不同点

char*是变量,值可以改变, char[]是常量,值不能改变。

char * a=”string1”; 
char b[]=”string2”; 

a是一个char型指针变量,其值(指向)可以改变; 
b是一个char型数组的名字,也是该数组首元素的地址,是常量,其值不可以改变 。

char[]对应的内存区域总是可写,char*指向的区域有时可写,有时只读:

char * a=”string1”; 
char b[]=”string2”; 
gets(a); //试图将读入的字符串保存到a指向的区域,运行崩溃! 
gets(b) //OK 

a指向的是一个字符串常量,即指向的内存区域只读;   所以一般:const char * a=”string1”; 
b始终指向他所代表的数组在内存中的位置,始终可写! 

char *本身是一个字符指针变量,但是它既可以指向字符串常量,又可以指向字符串变量,指向的类型决定了对应的字符串能不能改变。

char * 和char[]的初始化操作有着根本区别:

1 #include <iostream>
2 using namespace std;
3 int main(){
4     char* a = "hello word";
5     char b[] = "hello word";
6     cout << "hello word" << '\t' << (int)"hello word" << endl;
7     cout << "a:" << a << '\t' << "int a: " << (int)a << '\t' << "&a: " << &a << endl;
8     cout << "b:" << b << '\t' << "int b: " << (int)b << '\t' << "&b: " << &b << endl;
9 }

输出结果:

尽管都对应了相同的字符串,但”Hellow World”的地址 和 a对应的地址相同,与b指向的地址有较大差异。

&a 、&b都是在同一内存区域,且&b==b ;

局部变量都创建在栈区,而常量都创建在文字常量区,显然,a、b都是栈区的变量,但是a指向了常量(字符串常量),b则指向了变量(字符数组),指向了自己。

说明以下问题:

char * a=”string1”;是实现了3个操作: 
1声明一个char*变量(也就是声明了一个指向char的指针变量)。 
2在内存中的文字常量区中开辟了一个空间存储字符串常量”string1”。 
3返回这个区域的地址,作为值,赋给这个字符指针变量a 
最终的结果:指针变量a指向了这一个字符串常量“string1” 
(注意,如果这时候我们再执行:char * c=”string1”;则,c==a,实际上,只会执行上述步骤的1和3,因为这个常量已经在内存中创建)

char b[]=”string2”;则是实现了2个操作: 
1声明一个char 的数组, 
2为该数组“赋值”,即将”string2”的每一个字符分别赋值给数组的每一个元素,存储在栈上。 
最终的结果:“数组的值”(注意不是b的值)等于”string2”,而不是b指向一个字符串常量

PS: 
实际上, char * a=”string1”; 的写法是不规范的! 
因为a指向了即字符常量,一旦strcpy(a,”string2”)就糟糕了,试图向只读的内存区域写入,程序会崩溃的!尽管VS下的编译器不会警告,但如果你使用了语法严谨的Linux下的C编译器GCC,或者在windows下使用MinGW编译器就会得到警告。

所以,我们还是应当按照”类型相同赋值”的原则来写代码: const char * a=”string1”; 
保证意外赋值语句不会通过编译。

 

 

小结

1.a是const char 类型, b是char const类型 
( 或者理解为 (const char)xx 和 char (const xx) )

2.a是一个指针变量,a的值(指向)是可以改变的,但a只能指向(字符串)常量,指向的区域的内容不可改变;

3.b是一个指针常量,b的值(指向)不能变;但b指向的目标(数组b在内存中的区域)的内容是可变的

4.作为函数的声明的参数的时候,char []是被当做char *来处理的!两种形参声明写法完全等效!

 

posted @ 2019-07-14 16:09  Austin_anheqiao  阅读(216)  评论(0编辑  收藏  举报