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。
此函数返回的是字符串常量的地址,而像这种字符串都是属于全局的,在编译的时候就已经分配了内存了,只有程序退出的时候才会被销毁,所以返回它的地址是没有问题的,但是你最好返回常量指针,因为你不能去改变字符串常量的值。


代码如下:

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";数组是在栈上的空间由编译器分配,内容可以由用户改变。

(0)

相关推荐

  • 基于C语言char与unsigned char的区别介绍

    在C中,默认的基础数据类型均为signed,现在我们以char为例,说明(signed) char与unsigned char之间的区别. 首先在内存中,char与unsigned char没有什么不同,都是一个字节,唯一的区别是,char的最高位为符号位,因此char能表示-127~127,unsigned char没有符号位,因此能表示0~255,这个好理解,8个bit,最多256种情况,因此无论如何都能表示256个数字. 在实际使用过程种有什么区别呢?主要是符号位,但是在普通的赋值,读写文

  • C语言中char*和char[]用法区别分析

    本文实例分析了C语言中char* 和 char []的区别.分享给大家供大家参考之用.具体分析如下: 一般来说,很多人会觉得这两个定义效果一样,其实差别很大.以下是个人的一些看法,有不正确的地方望指正. 本质上来说,char *s定义了一个char型的指针,它只知道所指向的内存单元,并不知道这个内存单元有多大,所以: 当char *s = "hello";后,不能使用s[0]='a':语句进行赋值.这是将提示内存不能为"written". 当用char s[]=&q

  • c语言中getch,getche,getchar的区别

    getchar 是stdio.h中的库函数,它的作用是从stdin流中读入一个字符,也就是说 ,如果stdin有数据的话不用输入就可以直接读取了.而getch()和getche()是conio.h中的库函数,它的作用是从键盘接收字符. getch() 实际是一个输入命令,作用是从键盘接收一个字符,而且并不把这个字符显示出来,就是说,你按了一个键后它并不在屏幕上显示你按的什么,而继续运行后面的代码,所以我们在C++中可以用它来实现"按任意键继续"的效果,即程序中遇到getch();这行语

  • 深入理解char *a与char a[]的区别

    前言 指针和数组存在着一些本质的区别.当然,在某种情况下,比如数组作为函数的参数进行传递时,由于该数组自动退化为同类型的指针,所以在函数内部,作 为函数参数传递进来的指针与数组确实具有一定的一致性,但这只是一种比较特殊的情况而已,在本质上,两者是有区别的. 下面来看看详细的介绍. char *a = "hello" 中的a是指向第一个字符'a'的一个指针 char a[20] = "hello" 中数组名a也是执行数组第一个字符'h'的指针 但二者并不相同: 看实例

  • 深入char、varchar、text和nchar、nvarchar、ntext的区别详解

    很多开发者进行数据库设计的时候往往并没有太多的考虑char, varchar类型,有的是根本就没注意,因为存储价格变得越来越便宜了,忘记了最开始的一些基本设计理论和原则,这点让我想到了现在的年轻人,大手一挥一把人民币就从他手里溜走了,其实我想不管是做人也好,做开发也好,细节的把握直接决定很多东西.当然还有一部分人是根本就没弄清楚他们的区别,也就随便选一个.在这里我想对他们做个简单的分析,当然如果有不对的地方希望大家指教. 1.CHAR.CHAR存储定长数据很方便,CHAR字段上的索引效率级高,比

  • sql中varchar和nvarchar的区别与使用方法

    问: sql server中的varchar和Nvarchar有什么区别啊,varchar好像是一个英文和一个汉字都站两个字节,而Nvarchar则是一个英文占一个字节,汉字占两个字节.可是这个对asp程序有什么影响? 答: varchar(n) 长度为 n 个字节的可变长度且非 Unicode 的字符数据.n 必须是一个介于 1 和 8,000 之间的数值.存储大小为输入数据的字节的实际长度,而不是 n 个字节. nvarchar(n) 包含 n 个字符的可变长度 Unicode 字符数据.n

  • mysql中char与varchar的区别分析

    char与varchar的区别 char (13)长度固定, 如'www.jb51.net' 存储需要空间 12个字符 varchar(13) 可变长 如'www.jb51.net' 需要存储空间 13字符, 从上面可以看得出来char 长度是固定的,不管你存储的数据是多少他都会都固定的长度.而varchar则处可变长度但他要在总长度上加1字符,这个用来存储位置.所以实际应用中用户可以根据自己的数据类型来做. 再看看char,与varchar在速度上的区别吧. 复制代码 代码如下: mysal>

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

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

  • 全局变量与局部变量在内存中的区别详细解析

    一.预备知识-程序的内存分配 一个由c/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)- 由编译器自动分配释放,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈. 2.堆区(heap) - 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 .注意它与数据结构中的堆是两回事,分配方式倒是类似于链表. 3.全局区(静态区)(static)-,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域(.data),未初始化的全局变量

  • C语言中auto,register,static,const,volatile的区别详细解析

    1)auto这个关键字用于声明变量的生存期为自动,即将不在任何类.结构.枚举.联合和函数中定义的变量视为全局变量,而在函数中定义的变量视为局部变量.这个关键字不怎么多写,因为所有的变量默认就是auto的. (2)register这个关键字命令编译器尽可能的将变量存在CPU内部寄存器中而不是通过内存寻址访问以提高效率. (3)static常见的两种用途:1>统计函数被调用的次数; 2>减少局部数组建立和赋值的开销.变量的建立和赋值是需要一定的处理器开销的,特别是数组等含有较多元素的存储类型.在一

  • C++标准库中sstream与strstream的区别详细解析

    在C++有两种字符串流,一种在sstream中定义,另一种在strstream中定义.它们实现的东西基本一样. strstream里包含class strstreambuf;class istrstream;class ostrstream;class strstream;它们是基于C类型字符串char*编写的 sstream中包含class istringstream;class ostringstream;class stringbuf;class stringstream;class --

  • C/C++动态分配与释放内存的区别详细解析

    1. malloc()函数1.1 malloc的全称是memory allocation,中文叫动态内存分配.原型:extern void *malloc(unsigned int num_bytes); 说明:分配长度为num_bytes字节的内存块.如果分配成功则返回指向被分配内存的指针,分配失败返回空指针NULL.当内存不再使用时,应使用free()函数将内存块释放. 1.2 void *malloc(int size); 说明:malloc 向系统申请分配指定size个字节的内存空间,返

  • CreateThread()与beginthread()的区别详细解析

    我们知道在Windows下创建一个线程的方法有两种,一种就是调用Windows API CreateThread()来创建线程:另外一种就是调用MSVC CRT的函数_beginthread()或_beginthreadex()来创建线程.相应的退出线程也有两个函数Windows API的ExitThread()和CRT的_endthread().这两套函数都是用来创建和退出线程的,它们有什么区别呢? 很多开发者不清楚这两者之间的关系,他们随意选一个函数来用,发现也没有什么大问题,于是就忙于解决

  • iostream与iostream.h的区别详细解析

    C++的标准类库被修订了两次,有两个标准 C92和C99,这两个库现在都在并行使用,用 .h 包含的是c92 ,不带 .h 的是c99的头文件,对于普通用户来说这两者没有什么区别,区别是在内部函数的具体实现上.旧的C++头文件是官方明确反对使用的,但旧的C头文件则没有(以保持对C的兼容性).据说从 Visual C++ .NET 2003 开始,移除了旧的 iostream 库.其实编译器制造商不会停止对客户现有软件提供支持,所以在可以预计的将来,旧的C++头文件还会嚣张一段时间.如果能明白字符

  • JavaScript中instanceof与typeof运算符的用法及区别详细解析

    JavaScript中的instanceof和typeof常被用来判断一个变量是什么类型的(实例),但它们的使用还是有区别的: typeof 运算符返回一个用来表示表达式的数据类型的字符串. typeof expression ; expression 参数是需要查找类型信息的任意表达式. 说明typeof 是一个一元运算符,放在一个运算数之前. typeof 运算符把类型信息当作字符串返回.typeof 返回值有六种可能: "number" ,"string",

  • c++中#include <>与#include""的区别详细解析

    首先是区别: <>先去系统目录中找头文件,如果没有在到当前目录下找.所以像标准的头文件 stdio.h.stdlib.h等用这个方法. 而""首先在当前目录下寻找,如果找不到,再到系统目录中寻找. 这个用于include自定义的头文件,让系统优先使用当前目录中定义的. 然后是使用习惯的问题: 假设A是常被包含的文件. 则A中写的应该是一些 常用的函数,和一些宏定义.而且,不能出现main函数.

  • js判断undefined类型,undefined,null, 的区别详细解析

    js判断undefined类型 今天使用showModalDialog打开页面,返回值时.当打开的页面点击关闭按钮或直接点浏览器上的关闭则返回值是undefined所以自作聪明判断 var reValue=window.showModalDialog("","","");   if (reValue== undefined){  alert("undefined"); } 发现判断不出来,最后查了下资料要用typeof 方法:

随机推荐