char*与char[]比较

来源:互联网 发布:68什么意思网络用语 编辑:程序博客网 时间:2024/06/05 15:35

BG::频繁用到的char*与char[],却理解不足,将已get内容整理至此文,以C++为主,持更。


refer:《C++ primer》
http://www.tuicool.com/articles/UZbEbm7
字符串常量到底存放在哪个存储区
C++中string、char *、char[]的转换

首先,string是标准库类型,而char是基本数据类型,二者其实有本质区别,差别也较大,应分离开来学习。
【1】char*与char[]
char* a; //定义了char类型的指针变量a
char a[]; //定义了数组a,里面存的是char类型
char* a[]; //定义了数组a,里面存的是char*指针类型
测试1:
char* get_str1(){char str[] = {"abcd"};//str在栈上申请空间,将常量内容复制进来return str;}char* get_str2(){char *str = {"abcd"};//"abcd\0"存放在常量区,str在栈上return str;}

可以发现,函数get_str1编译时有警告信息:(warning C4172: 返回局部变量或临时变量的地址),这种写法是不对的,虽然编译能通过,可以运行,但是运行的结果不对,两次运行的结果也不一样,但是换成get_str2,即char*,就正确了。
这是因为:
    在函数get_str1中,char str[] = { "abcd" },定义的是一个局部变量,该函数返回的是内部局部字符数组str的地址,当函数调用之后该数组被销毁,所以返回的指针是一个已经释放了空间的指针,指向的值不定。
      在函数get_str2中,char* str = { "abcd" },先定义一个字符串常量“abcd“,再将指针str指向它,返回值是这个指针,由于字符串常量在编译时分配内存,只有程序退出时才被销毁,所以返回它的地址没有问题。
例子2:
1)char s[5];
   s = "abcd";     //编译失败
2)char *s;
   s = "abcd";     //编译成功
原因:在1中,s是数组名,当成是常量指针,不可以作为左值修改; 而2中s是一个指针变量,可以将其指向一个常量字符串。

测试代码2
#include <iostream>using namespace std;int main(){int tmpInt = 0;int *ia = &tmpInt;cout<<ia<<" "<<*ia<<endl;char* a = "123";char* b = "123";char* c = "456";cout<<a<<" "<<*a<<endl;cout<<(a==b)<<" "<<(a==c)<<" "<<(*a == *b)<<" "<<(*a == *c)<<endl;char a2[] = "123";char b2[] = "123";char c2[] = "456";cout<<(a2==b2)<<" "<<(a2==c2)<<" "<<(a2[0] == b2[0])<<" "<<(a2[0] == c2[0])<<endl;const char* a3 = "123";const char* b3 = "123";const char* c3 = "456";cout<<(a3==b3)<<" "<<(a3==c3)<<" "<<(*a3 == *b3)<<" "<<(*a3 == *c3)<<endl;system("pause");return 0;}


【2】string
标准库类型string表示可变长的字符序列,使用时需要
#include <string>
using std::string
定义和初始化:
string s2(s1);与string s2=s1;等价,s2是s1的副本
string s3("value");与string s3 = "value";等价,都是字面值“value”的副本,不含\0
string s4(n, 'c');将s4初始化为连续n个c组成的字符串
但要注意:等号实际是拷贝初始化,编译器将等号右侧的初始值拷贝到创建的对象中去,括号则是直接初始化。

string本身类似于一个“类”的概念,自定义了os<<s, is >>s, getline, empty, size,+,=,==,!=,<,<=等操作。
也提供很多类似于关联容器的操作,erase、insert等;

string不用担心长度问题,但不能改变单个字符,必须借助其他方式曲线实现。


【3】string、char *、char[]的转换

一、string转char*。
主要有三种方法可以将str转换为char*类型,分别是:data(); c_str(); copy();
1.data()方法,如:

string str = "hello";
const char* p = str.data();//加const  或者用char * p=(char*)str.data();的形式
同时有一点需要说明,这里在devc++中编译需要添加const,否则会报错invalid conversion from const char*  to char *,这里可以再前面加上const或者在等号后面给强制转化成char*的类型。
下面解释下该问题,const char*是不能直接赋值到char*的,这样编译都不能通过,理由:假如可以的话,那么通过char*就可以修改const char指向的内容了,这是不允许的。所以char*要另外开辟新的空间,即上面的形式。
2.c_str()方法,如:
string str=“world”;
const char *p = str.c_str();//同上,要加const或者等号右边用char*
3.copy()方法,如:
string str="hmmm";
char p[50];
str.copy(p, 5, 0);//这里5代表复制几个字符,0代表复制的位置,
*(p+5)=‘\0’;//注意手动加结束符!!!


二、char * 转string。
可以直接赋值。
string s;
char *p = "hello";//直接赋值
s = p;
这里有一点要说明,当声明了string类型变量s后,用printf("%s",s);是会出错的,因为“%s”要求后面的对象的首地址。但是string不是这样的一个类型。所以肯定出错。


三、string转char[]
这个由于我们知道string的长度,可以根据length()函数得到,又可以根据下标直接访问,所以用一个循环就可以赋值了。

    string pp = "dagah";    char p[8];    int i;    for( i=0;i<pp.length();i++)        p[i] = pp[i];    p[i] = '\0';    printf("%s\n",p);    cout<<p;


四、char[]转string
这里可以直接赋值。
0 0
原创粉丝点击