标题:重温了C风格字符串,有几个问题纠结以一下。
只看楼主
未未来
Rank: 3Rank: 3
等 级:论坛游侠
威 望:1
帖 子:182
专家分:157
注 册:2012-11-6
结帖率:94.87%
 问题点数:0 回复次数:8 
重温了C风格字符串,有几个问题纠结以一下。
1.字符串字面值"c"不是自动在末尾增加一个null,为什么赋值给 string对象的时候 他的长度不是2;
程序代码:
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
int main(){
string s="c";
cout<<s.size();
    return 0;
}

2.数组的名字即是指向数组的第一个元素的指针;
但是当
int shu[]={1,2,3};
cout<<shu;  是错误的
cout<<*shu;  输出1;

int ca[]="c++";
cout<<ca; 是正确的 且输出 c++ (这是为什么 ,跟int型不一样,切最后自动添加的null为什么没有输出)
cout<<*ca; 输出c
搜索更多相关主题的帖子: 字符串 color null 风格 
2013-08-08 20:55
蚕头燕尾
Rank: 10Rank: 10Rank: 10
来 自:Gryffindo
等 级:贵宾
威 望:12
帖 子:734
专家分:1546
注 册:2013-3-24
得分:0 
1、这个跟编译器有关。我试了一下,我的vs2012,确实有\0结尾。

给你个链接可以参考一下:

http://cache.

2、下面这段代码亲测可行。
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
int main(){
    int shu[]={1,2,3};
    cout<<shu<<endl;
    cout<<*shu<<endl;

    return 0;
}


不知道楼主是什么编译器,竟然允许这样赋值:

int ca[]="c++";

很好奇。

学习编程,为的是表达自己的思想,而不是被别人的思想所禁锢。要先明白自己想干嘛,而不要先问别人让你干嘛。               

                                                                                                                    Black Cat      Hello Tomorrow~
2013-08-08 23:12
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:0 
1. 是,否则C风格字符串无法确定字符串长度;因为std::string::size()返回的是字符数,效果等同于strlen(C风格字符串),也就是不包括结尾'\0'。
2. “数组的名字即是指向数组的第一个元素的指针”这种说法在很多烂书上常见,但说法是错误的,数组包含的信息比指针多个元素数目信息,但数组能丢弃元素数目信息从而隐式转化为指针。简单的说,数组名能隐式降阶为指针。
“cout<<shu;  是错误的” 不可能,std::ostream重载了 operator<<(const void *val),所以应当输出一个地址值。
“cout<<*shu;  输出1”是因为*shu的值就是1呀,且std::ostream重载了 operator<<(int val)
“cout<<ca; 是正确的 且输出 c++ ”因为std::ostream重载了 operator<<(const char* val)
“最后自动添加的null为什么没有输出”首先'\0'只是标示字符串长度用,在逻辑上其并非值的一部分,其次,你想'\0'输出成什么?
2013-08-09 08:29
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:0 
string的size()方法是一个函数,它返回元素数量,不计算'\0',事实上string类也不需要'\0'做结束符,类中有另外的变量记录元素数目,不靠寻找'\0'来标识字符串结束的,正因为如此,string才与C字符串相区别,也才需要用c_str()方法来把string字符串转换为cz字符串,这些证据证明两者根本不是一回事。不要再把C的那些东西带过来,string若与cz无区别,就不需要开发string类了。

授人以渔,不授人以鱼。
2013-08-09 10:37
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:0 
string的效率比cz串高得多,因为前者利用vector原理,vector中的元素数目是用一个字段变量记录的,任何更改元素数目的操作都会刷新这个字段,那么方法size()就仅仅是返回该字段的值,不需要再像C那样通过循环来搜索'\0'计数,所以size()的效率比strlen()高得多,串越长越显著,使用频率越高越显著。当做大循环的时候,C程序员往往先求出cz字符串的长度,用一个临时变量记忆下来,然后放在for()循环中作为结束判别条件,否则每次都strlen(),速度就慢下来了,但是在C++中,就不需要这样,直接用size()作结束条件表达式就可以了,这样代码的清晰度更高,尤其具有优势的是,如果在循环中改变了字符串的长度,那么C代码就要被迫重新求长度,但C++代码不要,仍然沿用原来的代码即可。其实这个解释,在C++ Primer中就有的,看书认真看文字就知道,所以我总说读IT书只看代码是没用的。

授人以渔,不授人以鱼。
2013-08-09 11:25
未未来
Rank: 3Rank: 3
等 级:论坛游侠
威 望:1
帖 子:182
专家分:157
注 册:2012-11-6
得分:0 
回复 2楼 蚕头燕尾
int ca[]="C++"是笔误 ,不好意思。
我的编译器还是没法
cout<<shu;
2013-08-09 14:21
未未来
Rank: 3Rank: 3
等 级:论坛游侠
威 望:1
帖 子:182
专家分:157
注 册:2012-11-6
得分:0 
回复 3楼 rjsp
这个重载是记住就可以了吗。
2013-08-09 14:28
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:0 
以下是引用未未来在2013-8-9 14:28:21的发言:

这个重载是记住就可以了吗。

不需要记,因为和C的printf一样
C的printf也不需要记,对于 printf( "???", int*类型值 ) 你想其输出什么?
2013-08-09 15:33
未未来
Rank: 3Rank: 3
等 级:论坛游侠
威 望:1
帖 子:182
专家分:157
注 册:2012-11-6
得分:0 
回复 8楼 rjsp
char型数组中每一个元素都是1个字节所以字符串之间的地址是加1的,但是int数组每个元素占4个字节所以数组中每个元素地址的间隔是4,其实它也是连续的
出现乱码是因为系统没有找到结束符,你可以把数组设大一点,然后最后一个字节添0如:char a[6]={'h','a','p','p','y',0};就可以了


我网上看到这个解答来解释 直接输出数组名导致的不同,您觉得怎么样,
2013-08-09 22:16



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-418821-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.789108 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved