在项目中遇到一个问题,在类外希望得到类中的字符串内容。
通过直接传递字符串指针实际并不能修改内容
可行的方法:
1.传递字符串数组的地址
2.传递字符串二级指针,即字符串地址
3.按照C++的方式传递一个 string引用, 通过引用直接修改
失败的方式:(截取代码:将函数封装到类里了,....代码太多,总体测试代码在文章末尾.感兴趣的同学自己复制)
void GetStringC(char *a){
a = "Hi,Kemeng~: GetStringC";
}
char * a2 = NULL;
test.GetStringC(a2);
printf("\n%s\n", a2);
可以看到实际上a2的值并没有发生改变这是为什么呢??
所以原因如下:形参a 在函数结束的时候已经被释放了,而本身只是改变了a 的值 ,让其指向 "Hello, KeMeng~"字符串,并没有更改a2,所以输出仍为null,那我们想到了以下办法:
实际上 参数的传递都是存在一次赋值的:
实参给形参赋值好比以下代码:
printf("\nTest of Assign of Char pointer\n"
"Print their address\n");
char * p2 = "Hello, KeMeng~";
char * p3 = p2;
printf("p2:%p p3:%p\n", p2, p3);
p2好比上面的实参a2, p3相当于形参a.
输出:
这么样一次复制相当于将p2与p3都指向了一块地址, 这个地址存放着 常量字符串 "Hello, KeMeng~"
但是p2. p3指针的地址是不一样的
printf("\nTest of Assign of Char pointer\n"
"Print their address\n");
char * p2 = "Hello, KeMeng~";
char * p3 = p2;
printf("p2:%p p3:%p\n", p2, p3);
printf("address of p2:%p, address of p3:%p\n", &p2, &p3);
这里不得不说一下:
char *p = "Hi, Kemeng";
这里的字符串"Hi, Kemeng"是不可修改的
原因见如下:
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"当成常量并把它放到程序的常量区是编译器
最合适的选择。
相关文章链接:
http://blog.csdn.net/u010003835/article/details/48087629
所以以下方式是不可行的:
void ChangeStringA(char *a){
a[0] = 'H';
a[1] = 'i';
a[2] = ':';
a[3] = '\0';
}
printf("\ntest.ChangeStringA(hh):\n");
char *hh = "Hello, KeMeng~";
printf("%s\n", hh);
test.ChangeStringA(hh); //error
printf("%s\n", hh);
但是指针p 所指的空间可以修改(指向其他位置)
printf("\nTest of change char pointer content\n");
char * p4 = "Hello, KeMeng~";
printf("p4: %s\n", p4);
p4 = "Hi";
printf("p4: %s\n", p4);
下面介绍几种可行的方式:
1.传递字符串数组的地址(两种写法)
<pre name="code" class="cpp"> void ChangeStringB(char *a){
strcpy(a, "Hi:");
}
void ChangeStringC(char a[]){
strcpy(a, "Hi:");
}
printf("\ntest.ChangeStringB(dd):\n");
char dd[100] = "Hello, KeMeng~";
printf("%s\n", dd);
test.ChangeStringB(dd);
printf("%s\n", dd);
printf("\ntest.ChangeStringC(ff):\n");
char ff[100] = "Hello, KeMeng~";
printf("%s\n", ff);
test.ChangeStringC(ff);
printf("%s\n", ff);
2.传递字符二级指针,即字符指针的地址(方法丑陋不建议使用)
void GetStringB(char **a){
*a = "Hi,Kemeng~: GetStringB";
}
char * aa = NULL;
test.GetStringB(&aa);
printf("\n%s\n", aa);
3.按照C++的方式传递一个 string引用, 通过引用直接修改
void GetStringA(string &a){
a = "Hi,Kemeng~: GetStringA";
}
string cstring;
test.GetStringA(cstring);
printf("\n%s\n", cstring.c_str());
另附上完整测试代码供大家参考:
#include <iostream>
#include <string>
using namespace std;
#pragma warning(disable:4996)
class A
{
public:
void GetStringA(string &a){
a = "Hi,Kemeng~: GetStringA";
}
void GetStringB(char **a){
*a = "Hi,Kemeng~: GetStringB";
}
void GetStringD(char *a){
strcpy(a, "Hi,Kemeng~: GetStringD");
}
void GetStringE(char a[]){
strcpy(a, "Hi,Kemeng~: GetStringE");
}
void GetStringC(char *a){
a = "Hi,Kemeng~: GetStringC";
}
void PrintStringAddress(char *a){
printf("%p\n", a);
}
void PrintCharPointAddress(char *a){
printf("%p\n", &a);
}
void ChangeStringA(char *a){
a[0] = 'H';
a[1] = 'i';
a[2] = ':';
a[3] = '\0';
}
void ChangeStringB(char *a){
strcpy(a, "Hi:");
}
void ChangeStringC(char a[]){
strcpy(a, "Hi:");
}
};
int main()
{
A test;
string cstring;
test.GetStringA(cstring);
printf("\n%s\n", cstring.c_str());
//char * aa = NULL;
//test.GetStringB(&aa);
//printf("\n%s\n", aa);
//char * a2 = NULL;
//test.GetStringC(a2);
//printf("\n%s\n", a2);
//printf("\ntest.PrintStringAddress(bb):\n");
//char *bb = "Hello, KeMeng~";
//printf("%p\n", bb);
//test.PrintStringAddress(bb);
//printf("\ntest.PrintCharPointAddress(c2):\n");
//char *c2 = "Hello, KeMeng~";
//printf("%p\n", &c2);
//test.PrintCharPointAddress(c2);
//printf("\nTest of Assign of Char pointer\n"
// "Print their address\n");
//char * p2 = "Hello, KeMeng~";
//char * p3 = p2;
//printf("p2:%p p3:%p\n", p2, p3);
//printf("address of p2:%p, address of p3:%p\n", &p2, &p3);
//注意 "Hello, KeMeng~" 存放在字符串内存空间中
//p2[1] = '\0';
//printf("%s\n", p2);
//printf("\nTest of change char pointer content\n");
//char * p4 = "Hello, KeMeng~";
//printf("p4: %s\n", p4);
//p4 = "Hi";
//printf("p4: %s\n", p4);
//
//printf("\ntest.ChangeStringC(cc):\n");
//char *cc = "Hello, KeMeng~";
//printf("%s\n", cc);
//test.ChangeStringC(cc); //error
//printf("%s\n", cc);
//printf("\ntest.ChangeStringC(c3):\n");
//char *c3 = "Hello, KeMeng~";
//printf("%s\n", &c3);
//test.ChangeStringC(c3); //error
//printf("%s\n", c3);
//printf("\ntest.ChangeStringB(dd):\n");
//char dd[100] = "Hello, KeMeng~";
//printf("%s\n", dd);
//test.ChangeStringB(dd);
//printf("%s\n", dd);
//printf("\ntest.ChangeStringC(ff):\n");
//char ff[100] = "Hello, KeMeng~";
//printf("%s\n", ff);
//test.ChangeStringC(ff);
//printf("%s\n", ff);
//printf("\ntest.ChangeStringC(gg):\n");
//char gg[100] = "Hello, KeMeng~";
//printf("%s\n", gg);
//test.ChangeStringA(gg);
//printf("%s\n", gg);
//printf("\ntest.ChangeStringA(hh):\n");
//char *hh = "Hello, KeMeng~";
//printf("%s\n", hh);
//test.ChangeStringA(hh); //error
//printf("%s\n", hh);
return 0;
}