在项目中遇到一个问题,在类外希望得到类中的字符串内容。
通过直接传递字符串指针实际并不能修改内容
可行的方法:
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;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/u010003835/article/details/48087729