在项目中遇到一个问题,在类外希望得到类中的字符串内容。
通过直接传递字符串指针实际并不能修改内容
可行的方法:
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的值并没有发生改变这是为什么呢??
实际上 参数的传递都是存在一次赋值的:
实参给形参赋值好比以下代码:
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; }
版权声明:本文为博主原创文章,未经博主允许不得转载。