先看一段代码:
#include <iostream>
#include <typeinfo>
using namespace std;
int main()
{
// char *ps = "west";
const char *ps = "west";
// *ps = 'k';
cout<<typeid("west").name()<<endl;
cout<<typeid(ps).name()<<endl;
return 0;
}
输出char [5]
char const *
如果使用被注释掉的代码,则编译可以通过,但运行出错。可以看出C风格字符串"west"的类型为字符数组char[],而其首地址的指针类型为char const *,故不能通过*ps='k',来改变这个字符数组,那么我们很容易可以看到char *ps = "west"或者char s[5] = "west"都是是一种危险的赋值方式,其将一个const char*类型的指针赋值给了一个char *指针,给用户造成了一种可以改变给指针所指对象值的假想。正确的赋值方式应该实const char *ps = "west";。
总结:
'a',其数据类型为char,char c = 'a';
"a",其数据类型为const char *,既是指向常量字符串的指针类型,const char * cc = "a";
再来辨析一下这两个定义;
int main()
{
char ch[4] = "abc"; //在main函数的堆栈区分配四个字节,然后分别存放'a','b','c','/0'到这四个字节中,将首地址 //(也就是存放'a'的地址)赋值给ch
char *pc = "abc"; //将文字常量区的"abc"的首地址赋给指针pc,故安全的赋值方式应该为const chat *pc = "abc"; ch[2] = 'd'; //成功,因为ch保存的是堆栈中的地址,类型为char*
*(ch+1) = 'e'; //成功,理由同上
*(pc+1) = 'f'; //编译通过,运行失败,pc保存的地址是文字常量区中的地址,类型为const char *,所以最好把 //pc声明为const char*类型,使得错误尽可能的在编译时候就发现
return 0;
}
#include <iostream>
#include <typeinfo>
using namespace std;
int main()
{
// char *ps = "west";
const char *ps = "west";
// *ps = 'k';
cout<<typeid("west").name()<<endl;
cout<<typeid(ps).name()<<endl;
return 0;
}
输出char [5]
char const *
如果使用被注释掉的代码,则编译可以通过,但运行出错。可以看出C风格字符串"west"的类型为字符数组char[],而其首地址的指针类型为char const *,故不能通过*ps='k',来改变这个字符数组,那么我们很容易可以看到char *ps = "west"或者char s[5] = "west"都是是一种危险的赋值方式,其将一个const char*类型的指针赋值给了一个char *指针,给用户造成了一种可以改变给指针所指对象值的假想。正确的赋值方式应该实const char *ps = "west";。
总结:
'a',其数据类型为char,char c = 'a';
"a",其数据类型为const char *,既是指向常量字符串的指针类型,const char * cc = "a";
再来辨析一下这两个定义;
int main()
{
char ch[4] = "abc"; //在main函数的堆栈区分配四个字节,然后分别存放'a','b','c','/0'到这四个字节中,将首地址 //(也就是存放'a'的地址)赋值给ch
char *pc = "abc"; //将文字常量区的"abc"的首地址赋给指针pc,故安全的赋值方式应该为const chat *pc = "abc"; ch[2] = 'd'; //成功,因为ch保存的是堆栈中的地址,类型为char*
*(ch+1) = 'e'; //成功,理由同上
*(pc+1) = 'f'; //编译通过,运行失败,pc保存的地址是文字常量区中的地址,类型为const char *,所以最好把 //pc声明为const char*类型,使得错误尽可能的在编译时候就发现
return 0;
}