`
isiqi
  • 浏览: 16051393 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

char str[] 和 char *str 的区别

 
阅读更多
char* get_str(void)
{
	char str[] = {"abcd"};
	return str;
}

char str[] = {"abcd"};定义了一个局部字符数组,尽管是数组,但它是一个局部变量,返回它的地址肯定是一个已经释放了的空间的地址。
此函数返回的是内部一个局部字符数组str的地址,且函数调用完毕后 此数组被销毁,所以你返回的指针也就指向一块被销毁的内存,这种写法是错误的。

char* get_str(void)
{
	char *str = {"abcd"};
	return str;
}

char* str = {"abcd"};表示先定义个字符串常量,并将其地址赋给str。
此函数返回的是字符串常量的地址,而像这种字符串都是属于全局的,在编译的时候就已经分配了内存了,只有程序退出的时候才会被销毁,所以返回它的地址是没有问题的,但是你最好返回常量指针,因为你不能去改变字符串常量的值。

这个str就在栈里面,但后面的字符串在常量区,函数返回的时候,先将常量区的地址返回,然后作用域结束,释放str在栈里面的空间。。

const char str[] = "abcd";        //abc存储在堆栈中
const char *str = "abcd";         //abc存储在静态存储区

准确的说,上面两个“abc"都是存储在静态存储区,即常量区。常量区是可读不可写的。所以任何试图对常量区进行写的操作都是非法的,当然了,这也不是一定不可写的,你可以采取某种渠道改变常量区的内存属性,比如改变pe相关节的属性就可以对常量区进行读写,当然了,这个目前可以忽略。。。
那么为什么str[] = "abc";可以写呢? 答案就在str[] = "abc";会有一个额外的拷贝过程,即把常量区的 "abc"拷贝到栈内存去,所以就可以写了。

总结:
所有以" "或' '包含的字符、字符串都是常量,应该是存储在堆上。
char *str = "xxxxx",str指向该常量地址。
char str[] = "xxxxx",str在栈上申请空间,将常量内容复制进来,所以是局部变量。

首先,数组和指针是不同的数据类型,有本质的区别:
char str[] = "abcd"; //sizeof(str) == 5 * sizeof(char)
char * str = "abcd"; //sizeof(str) == 4(x86) or 8(x64)
数组可以自动转型成指针,指针不能转成数组。

然后,字符串等价于字符数组,而不等于字符指针。根据上一条,字符串可以自动转型成字符指针。

再然后,"abcd"叫做“字符串常量”,任何类型的常量都是右值(没有名字的临时变量),必须让"abcd"成为左值(有名字的变量),才能够修改"abcd"这个字符串。
char str[] = "abcd"; //等号两端是相同的数据类型,右值成为左值
char * str = "abcd"; //等号两端是不同的数据类型,右端自动转型成char*,该char*得到了str的名字,而"abcd"这个char数组仍然没有名字。

char * str是存储在全局静态存储区,所以,虽然是局部变量但函数返回后依然可以拿到正确的值!
char str[] 是存储在栈上的,local variable ,函数返回后,OS就收回空间了,就不复存在了,所以,拿不到正确的结果!

char str[]="name";与char str[5];str="name" 的不同之处在哪,能不能从内存分配的角度讲一讲,我知道数组名字是一个常量地址(指针),第一个为什么对,第二个为什么错?

第二个先定义了一个数组,要知道数组名str是数组分配到的空间的首地址,str="name"应该是等号两边类型不匹配的错误。一般的常量应该没有内存地址的,除非有某个变量指向了该常量。
数组名是地址常量,那么常量当然不允许被重新赋值。
"name"是一个字符串常量他存储在常量存储区,只能用一个指针指向它却不允许改变:char*p;p="name";
一般情况下char str[]="name";数组是在栈上的空间由编译器分配,内容可以由用户改变。



分享到:
评论

相关推荐

    char str[] 与 char *str的区别详细解析

    代码如下:char* get_str(void) { char str[] = {“abcd”}; return str; }char str[] = {“abcd”};定义了一个局部字符数组,尽管是数组,但它是一个局部变量,返回它的地址肯定是一个已经释放了的空间的地址。 ...

    字符串的各个函数写法

    自己编写的字符串函数。 char *strcopymy(char *str1,const char *str2); int strclen(char *str1); char *strlink(char *str1, char *str2); int strcompa(char *str1, char *str2);

    *,&的区别,输出*str,&str和str

    程序能够实现指针和引用的区别,输出*str,&str和str,使对这三者的区别一目了然。

    如何把char str,或unsigned char str转换成CString

    如何把char str,或unsigned char str转换成CString

    字符串子串替换函数

    int replace_str(const char * src, const char * key_src, const char * key, char ** buf); int replace_count(const char * src, const char * key_src, int * n); int main() { char * str = "a 123 b 156 LL a...

    c代码-C: []数组、*指针、&引用(别名) const char* str;等同于char const* str; char* const str;

    c代码-C: []数组、*指针、&引用(别名) const char* str;等同于char const* str; char* const str;

    strEX.rar_memcpy_strcpy

    void memsetEX(unsigned char *dst,unsigned char val,unsigned char len); void memcpyEX(unsigned char *dst,unsigned char *... char* strchrEX(char* str, char c); char* itoaEX(int num,char* str,int radix);

    QString和char以及string之间的赋值详解

     char *str = qstr.toLatin1().data();//这样便把qstr中的值传给了str 二 、char [] 赋值给string  char str[32];  string str2(str);//这样便把str中的值传给了str2 三 、char* 赋值给QString  例如:char *str...

    CString,string,char*之间的转换

    string的c_str()也是非常常用的,但要注意和char *转换时,要把char定义成为const char*,这样是最安全的。 以上函数UNICODE编码也没问题:unicode下照用,加个_T()宏就行了,像这样子_T("%s") 补充: CString ...

    c语言字符串分割,截取,子串查找,插入,删除

    int strarray_cat(char (*arr)[str_max_len],int i,char *str) //把二维arr字符串数组拼接成一个串,i是第一维的长度,存入str int replacate(char *res,int n,char const *str) //产生n个重复的str(串或者字符)存入...

    c语言字符串操作大全

    c语言字符串个函数操作大全 函数名: stpcpy 功 能: 拷贝一个字符串到另...函数名: strncmpi 功 能: 将一个串中的一部分与另一个串比较, 不管大小写 用 法: int strncmpi(char *str1, char *str2, unsigned maxlen);

    C++中string转换为char*类型返回后乱码问题解决

    在写二叉树序列化与反序列化时发现序列化函数为char* Serialize1(TreeNode *root) 其函数返回类型为char*,但是我在实现的过程中为了更方便的操作添加字符串使用的是C++中string类型的变量,这就导致我最后得到的...

    Untitled2.cpp

    本题要求实现一个函数,将两个字符串连接起来。 函数接口定义: char *str_cat( char *s, char *t ); 函数str_cat应将字符串t复制到字符串s的末端,并且返回字符串s的首地址

    新嵌入式Linux笔试题

    char str[] = “Hello” ;char *p = str ;int n = 10; 请计算: sizeof (str ) = 6 sizeof ( p ) = 4 sizeof ( n ) = 4 void Func ( char str[100]) void *p = malloc( 100 ); { sizeof ( p ) = 4 sizeof( str ...

    不用string.h库函数的,方便易用的字符串处理函数,减少库带来代码量

    void LettersChange(unsigned char*str, unsigned char font);//大小写字母变成大小写字母 signed int st_strlen(unsigned char* str);//获取字符串长度 signed int st_strcmp(unsigned char *s,unsigned char *t);/...

    C 语言中strstr函数实例详解

    C 语言中strstr函数实例...const char* strstr(const char* str1,const char* str2); char* strstr(char* str1,const char* str2); 库中实现的strstr #include #include <string> int main () { char str[] =This

    C语言求两个字符串的最长公共子串

    void getCommon(char str1[],char str2[],char * str3); int stringLength(char * str); void main(){ char str1[50]; char str2[50]; char str3[50]; gets(str1); gets(str2); getCommon(str1,str2,str3);

Global site tag (gtag.js) - Google Analytics