1、概念不同
c语言中没有特定的字符串类型,常用以下两种方式定义字符串:1)字符数组;2)指向字符串的指针。
char *str
声明的是一个指针,这个指针可以指向任何字符串常量。
char str[]
声明的是一个字符数组,数组的内容可以是任何内容,严格意义上说,末尾加上'\0'
之后才能算是字符串。
2、变量不同
char *str
的str
是指针变量,str
的值未初始化(局部变量的话,全局则自动初始化为NULL
)
char str[]
的str
是地址常量,str
的值是str[]
的地址
3、内存的分配方式不同
内存分配可分为三种:静态存储区、栈区、堆区
1、静态存储区:该内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在,它主要存放静态数据、全局数据和常量。
2、栈区:它的用途是完成函数的调用。在执行函数时,函数内局部变量及函数参数的存储单元在栈上创建,函数调用结束时这些存储单元自动被释放。
3、堆区:程序在运行时使用库函数为变量申请内存,在变量使用结束后再调用库函数释放内存。动态内存的生存期是由我们决定的,如果我们不释放内存,就会导致内存泄露。
char []
定义的是字符串数组,该字符数组保存在全局数据区或栈区,因此数组的内容是可以改变的:
char str[6] = {"hello"}; //虽然只初始化了5个元素,但由于编译器会自动在末尾加'\0',所以size为6
str[0] = 'H'; //合法
char *
定义的是字符串指针变量,该指针变量指向一个字符串,该指针的值是该字符串在内存中的地址,所以可以修改指针的值,但不能修改指针指向的值:
char *str = {"hello"};
str[0] = 'H'; //非法
4、char *
作为函数返回值时
指针作为返回值时会出现:在函数返回后,指针指向的内存单元被释放了,这样就会导致指针成了野指针。
//这样会报错,因为str数组元素为局部变量,存储在栈内,函数结束后,内容失效
char* func(char* name)
{
char str[5];
strcpy(str,name);
return str;
}
错误分析:
str
为地址,返回值为char*
,是进行了值传递,没有问题,但是,数组中的元素为局部变量,存储在栈中,函数外无效。
- 解决方法1:将数组定义为
static
char* func(char *name)
{
static char str[5];
strcpy(str,name);
return str;
}
- 解决方法2:字符串为静态常量(存储在常量区)
char* func()
{
char *str= "hello";
//char str[]= "hello";
return str;
}
- 解决方法3:设置为动态数组
char* func(char* name)
{
char *str= (char*)malloc(5*sizeof(char));
strcpy(str,name);
return str;
}
- 解决方法4:设置为全局变量
char str[10];
char* func(char* name)
{
strcpy(str,name);
return str;
}
小结:通过以上方法,返回字符串,只要返回字符串首地址即可。
1)调用函数时,若直接输出的话,用一个字符指针接受即可:char *result = func();
2)调用函数时,若要获取返回的字符串:char result[5];
strcpy(result, func());