char a[]="abcd"
chara[]="abcd";cout<<a<<endl;会输出abcd指针问题有点不太理解a不是存储字符串abcd的地址吗那输出这个地址为什么会输出abcd呢?...
char a[]="abcd";
cout<<a<<endl;
会输出abcd
指针问题 有点不太理解
a不是存储字符串abcd的地址吗
那输出这个地址为什么会输出abcd呢? 展开
cout<<a<<endl;
会输出abcd
指针问题 有点不太理解
a不是存储字符串abcd的地址吗
那输出这个地址为什么会输出abcd呢? 展开
展开全部
(本来这个问题并不复杂,但是由于LS个别概念有些问题,所以还是深入回答一下算了- -。)
关于LZ的问题:a本身的值确实只是一个const char*类型的地址。但C++中cout是被定义好的一个类的对象,它和运算符“<<”连用时<<发生重载,语义被解释为输出<<右端指示的字符串。具体是通过运算符重载实现,类似于调用函数,只是右操作数作为地址被传入这个函数,然后函数内解析地址进行输出。注意重载是区分类型的,所以如果a不是字符数组名而是int变量或者其它类型的话,(只要有定义过——对于基本类型在STL中已有定义)调用的是不同的输出函数,仍能得到正确结果。至于这里的具体行为,是由重载的运算符(函数)对传入的参数指向的地址开始依次(从低地址到高地址,逐个地)扫描并输出该地址的char字符(准确来说是写入标准输出流stdout,至于stdout里的字符怎么跑到屏幕上的实现过程是操作系统的事),直至遇到'\0'停止运行。它和C标准I/O方式的printf("%s",a)类似(而不是puts(a),puts会把末尾的'\0'转化为换行)。
----
昏昏灯火语生平 说,a是char[]类型,这是不确切的。
a在编译期由右端的字符串字面量(引号为边界的部分)初始化,确定为常量,类型为const char[]而不是char[]。
无论如何,这确实是一个地址常量而非指针(以整数形式保存地址值的变量),这点是正确的。但LZ并没提到指针- -...
经过参数传递后,地址常量退化为对应类型的指针。也就是说在“<<”重载函数对应实现的内部而言,通过值参传递(a的值被复制在函数内产生一个副本),可以成为一个const char*类型的变量。注意这里const指指针指向的内容不可改变,而不是指针本身的值不可改变。
----
robinren240 提到的大体正确,细节错误上面已经说了。
----
qds316 说:“当使用cout()或者printf()输出该类型变量,就是字符串数组的时候,就会输出数据直至遇到\0为止”。
这里有问题。首先,cout()写法错误;其次,a是常量,不是变量。当然,对于cout来说,常量作为“<<”的操作数也能和变量以一样的形式输出(参见以上讨论),因为本身是只读操作,而a又是可以合法访问的,自然没有影响。
----
以上讨论的问题引发的关于数组名称的问题:
数组名本身是个地址常量,但是某些特殊情况下它的语义可以发生改变。例如sizeof(a),这时a表示整个数组对象(这里指语法对象,不是指类的实例)而不是这个常量本身。基于这个语义,对数组名取地址也是合法的,对于数组a来说&a的结果等于a这个地址常量本身的值。这是C/C++标准委员会为了维护语法对象a作为一个左值(l-value)总可以取地址这条原则的妥协。
----
C/C++是传统的强类型语言。尽可能清楚掌握“类型”对于理解程序和写出更高质量C/C++的代码都有帮助。
====
[原创回答团]
关于LZ的问题:a本身的值确实只是一个const char*类型的地址。但C++中cout是被定义好的一个类的对象,它和运算符“<<”连用时<<发生重载,语义被解释为输出<<右端指示的字符串。具体是通过运算符重载实现,类似于调用函数,只是右操作数作为地址被传入这个函数,然后函数内解析地址进行输出。注意重载是区分类型的,所以如果a不是字符数组名而是int变量或者其它类型的话,(只要有定义过——对于基本类型在STL中已有定义)调用的是不同的输出函数,仍能得到正确结果。至于这里的具体行为,是由重载的运算符(函数)对传入的参数指向的地址开始依次(从低地址到高地址,逐个地)扫描并输出该地址的char字符(准确来说是写入标准输出流stdout,至于stdout里的字符怎么跑到屏幕上的实现过程是操作系统的事),直至遇到'\0'停止运行。它和C标准I/O方式的printf("%s",a)类似(而不是puts(a),puts会把末尾的'\0'转化为换行)。
----
昏昏灯火语生平 说,a是char[]类型,这是不确切的。
a在编译期由右端的字符串字面量(引号为边界的部分)初始化,确定为常量,类型为const char[]而不是char[]。
无论如何,这确实是一个地址常量而非指针(以整数形式保存地址值的变量),这点是正确的。但LZ并没提到指针- -...
经过参数传递后,地址常量退化为对应类型的指针。也就是说在“<<”重载函数对应实现的内部而言,通过值参传递(a的值被复制在函数内产生一个副本),可以成为一个const char*类型的变量。注意这里const指指针指向的内容不可改变,而不是指针本身的值不可改变。
----
robinren240 提到的大体正确,细节错误上面已经说了。
----
qds316 说:“当使用cout()或者printf()输出该类型变量,就是字符串数组的时候,就会输出数据直至遇到\0为止”。
这里有问题。首先,cout()写法错误;其次,a是常量,不是变量。当然,对于cout来说,常量作为“<<”的操作数也能和变量以一样的形式输出(参见以上讨论),因为本身是只读操作,而a又是可以合法访问的,自然没有影响。
----
以上讨论的问题引发的关于数组名称的问题:
数组名本身是个地址常量,但是某些特殊情况下它的语义可以发生改变。例如sizeof(a),这时a表示整个数组对象(这里指语法对象,不是指类的实例)而不是这个常量本身。基于这个语义,对数组名取地址也是合法的,对于数组a来说&a的结果等于a这个地址常量本身的值。这是C/C++标准委员会为了维护语法对象a作为一个左值(l-value)总可以取地址这条原则的妥协。
----
C/C++是传统的强类型语言。尽可能清楚掌握“类型”对于理解程序和写出更高质量C/C++的代码都有帮助。
====
[原创回答团]
参考资料: 原创
展开全部
char a[]中的a绝对不是一个指针,a的正确形式是char [],只有在char *p=a这样写的时候,a才会隐式转换位指向a首元素的地址,你可以做个试验,在程序
char a[]="hello,world";
char *p=a'
cout<<sizeof(a)<<sizeof(p)<<endl;
输出的结果是不相同的。原因就是一个是指针,一个是char []类型。
char a[]="hello,world";
char *p=a'
cout<<sizeof(a)<<sizeof(p)<<endl;
输出的结果是不相同的。原因就是一个是指针,一个是char []类型。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
char a[]中的a应该理解为字符数组名,或者&a[0],即字符串首地址
当使用cout()或者printf()输出该类型变量,就是字符串数组的时候,就会输出数据直至遇到\0为止
这里面会有以下几个方面需要考虑:
1.如你提到的这种初始化,由于已经隐含包括\0,而且没有指定字符个数,这个时候编译器为你搞定;
2.在1的情况下,若你指定字符数组元素小于实际字符个数(注意上述初始化方式下,实际字符个数为5个),会编译错误;而大于或等于只是会在剩余的存储空间中填\0而已,数据输出至第一个\0为止
个人拙见,希望对你能够有所帮助。
当使用cout()或者printf()输出该类型变量,就是字符串数组的时候,就会输出数据直至遇到\0为止
这里面会有以下几个方面需要考虑:
1.如你提到的这种初始化,由于已经隐含包括\0,而且没有指定字符个数,这个时候编译器为你搞定;
2.在1的情况下,若你指定字符数组元素小于实际字符个数(注意上述初始化方式下,实际字符个数为5个),会编译错误;而大于或等于只是会在剩余的存储空间中填\0而已,数据输出至第一个\0为止
个人拙见,希望对你能够有所帮助。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
C++中,cout具有很强大的功能。既可以输出一个字符,也可以输出字符串。有点儿像C中的printf和puts的集合。那puts为例,它接收的是地址,并根据那个地址,依次顺延输出(系统内部设置,无需明白)。这样就输出了字符串(直到碰到\0为止)。cout同理。当它接收到一个首地址的时候,它会自动判别,发现这是个首地址,所以就输出字符串。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询