请c++高手指点
#include<iostream>
using namespace std;
//-------------------------------------
int main(){
cout<<("join"=="join" ? "" : "not ")<<"equal\n"; // 直接字面值比较
char* str1="good";
char* str2="good";
cout<<(str1==str2 ? "" : "not ")<<"equal\n"; // 字符指针比较
char buffer1[6]="Hello";
char buffer2[6]="Hello";
cout<<(buffer1==buffer2 ? "" : "not ")<<"equal\n"; // 字符数组比较
}//====================================
疑问:join==join 书上说是不相等的,但是我分析,"join"作为常量是放在程序代码区或者全局数据区,到底放在哪个我搞不清了,但是他们应该是相等的啊??
str1==str2,这二个是新建了二个字符串型,他们明显是建了二个,应该是不等的啊,但是在vc中及devc++中输出都是相等的,但是语言本身告诉我它是不相等的,莫名其妙,朋友们说是做了优化了。
java中如下
package begin;
class Hello {
public static class TestHello{
public static void main(String[] args){
String h = "helloworld";
System.out.println(("helloworld"=="helloworld")?"等于":"不等于");
System.out.println("helloworld"==h?"等于":"不等于");
}
}
}
以上程序是在java中,上面的程序中的输出结果都是等于,我非常的不明白,helloworld==helloworld我还可以理解,但是"helloworld"==h我感觉莫名其妙,二者的内存地址明显不同?
另外有没有能把(1)String a ="helloworld"; 和(2)String a = new String("helloworld");建立的本质过程的区别说清楚,
我先分析一下,"helloworld"放在全局数据区,(1)直接定义了一个a,指向了这个内存地址
(2)先建立了一个"helloworld"的一个形参变量,根据这个变量,在堆区分配了一段内存空间,再把这段内存空间给了a
这些相关的知识点,我现在是搞的不清楚
希望这能成为一个讨论贴,有人能把这些说清楚
问题点数:100、回复次数:15Top
1 楼fancyf(凡瑞)回复于 2006-03-04 09:04:59 得分 0
有个“字符串池”的概念,编译程序可以把同一个程序中的所有相同的字符串常量都指向同一个内存地址,以节省内存空间
不过相等不相等是依赖于编译器的,如果不做这样的优化,就不相等了
这个结果不是语言的标准所规定的Top
2 楼zhNKUjw(淡淡的云彩悠悠的游)回复于 2006-03-04 09:14:05 得分 0
java的我一点都没有接触过
在C++里面:
"join"=="join"是两个常量字符串的比较,它们的值相等,所以返回值是true
char* str1="good"; char* str2="good"; 它们的赋值方式是先建立一个字符串常量
“good”,然后将str1(和str2)都指向这个字符串常量,它们的值是该常量的地址,所以
str1==str2 返回true
char buffer1[6]="Hello";
char buffer2[6]="Hello";
在栈上创建char型的数组并分配空间,然后将“hello”的值逐个拷贝给数组。buffer1和buffer2指向了栈空间中不同位置,所以buffer1==buffer2 返回false
Top
3 楼xiaoxiangfei(蜗牛)回复于 2006-03-04 09:27:22 得分 0
"join"=="join" 一定是相等的。这两个用了双引号就是常量了。
char *str1="good" 这条语句首先会为"good" 在内存中分一个存放地址,str1是指针其中存的是"good"的地址。str2是指针,其中也是存的“good"的地址。所以二者是相等的。但是&str1就不会等于&str2了。(即他们的地址比较)
而buffer1是一个数组,其中的内容是“Hello"另个一个数组中的内容也是"Hello"但是他们是数组,是有两个不同的存储空间的。所以拿他们的地址来比较时是不等的。
Top
4 楼flyrain000(假日笛声)回复于 2006-03-04 09:27:36 得分 0
markTop
5 楼freezh(只提供思路)回复于 2006-03-04 09:29:24 得分 0
在C++里面:
"join"=="join"是两个常量字符串的比较,它们的值相等,所以返回值是true
此值在c++语言中说明是false的,但在vc及dev c++中是true的Top
6 楼zh2817()回复于 2006-03-04 09:35:54 得分 0
join==join,不相等,是因为两个常量在内存存储区的起始地址不同,但是在存储区内所存储的值是相同的,所以书上说不同是有道理的。
(1)String a ="helloworld"; 和(2)String a = new String("helloworld");
(1)定义了一个字符窜常量helloworld,并把字符窜常量helloworld赋给变量a;
(2)是动态的字符窜的定义,在内存中创建变量a,并将helloworld存放在字符窜起止地址a中。
Top
7 楼vcmute(BCare4 H1Rest Good9!)回复于 2006-03-04 09:44:25 得分 0
和编译器有关Top
8 楼zzw820626(偶要分,偶要星星)回复于 2006-03-04 12:42:49 得分 0
和编译器有关
Top
9 楼zw24127(政委)回复于 2006-03-04 13:58:51 得分 0
张孝祥得《Java就业培训教程》上有关于地址分配得问题!Top
10 楼wjd7623054(千古风流)回复于 2006-03-05 13:06:02 得分 0
主要是看那==运算符是怎么实现的,我一般用strcmp来比较字符串
Top
11 楼wjd7623054(千古风流)回复于 2006-03-05 13:07:20 得分 0
许多C++特性我真的太不了解了
Top
12 楼Lcisware()回复于 2006-03-05 13:34:32 得分 0
直接支持字符串类型的编译器会重载==操作符Top
13 楼ox_thedarkness()回复于 2006-03-05 14:11:20 得分 0
//-------------------------------------
int main(){
cout<<("join"=="join" ? "" : "not ")<<"equal\n"; // 直接字面值比较
char* str1="good";
char* str2="good";
cout<<(str1==str2 ? "" : "not ")<<"equal\n"; // 字符指针比较
char buffer1[6]="Hello";
char buffer2[6]="Hello";
cout<<(buffer1==buffer2 ? "" : "not ")<<"equal\n"; // 字符数组比较
}//====================================
1 结果不确定
2 结果不确定
3 结果肯定是不等
要知道,C/C++ 语言本身虽然有“字符串字面值常量”这种类型,但是没有“字符串变量”这种类型的。
C/C++中,“字符串字面值常量”的类型是什么呢? C++规定,一个通常字符串常量拥有是类型 "const char [n]",存储期为静态存储[C++03, 2.13.4.1]。 而且,字符串常量是否拥有不同的存储空间是与实现相关的[C++03,2.13.4.2]。
所以我们来看下面的例子:
"join"=="join"
这是两个字符串常量,其值为“静态区const char数组”。C/C++中数组是不能比较的, 但是他们可以隐式转换为对应首地质的指针。
所以,这里实际上是比较两个指针(亦即两个数组的首地址)坐标是否相同 —— 结果取决于,编译器是否合并这两个 "join",并且让这两个指针指向同一个位置 —— 这个不但取决于编译器、上下文,还取决于编译环境的优化选项。所以,结果是不确定的。
char* str1="good";
char* str2="good";
cout<<(str1==str2 ? "" : "not ")<<"equal\n";
同样,这两个"good"是否指向唯一的静态串,也取决于编译器。结果是不确定的。
顺便说一句,正确的写法是:
const char* str1 = "good";
因为 "good" 的真正类型为 const char[5],假如你写成 char* str = "good"; 就暗示可以修改其内容:
char* str = "good";
str[0] = "G"; // undefined behavior
这个行为是未定义的[C++03, 2.13.4.2]。 但是诡异的是,大多数编译器都不认为这是一个语法错误 —— 于是,在VC++ 7.1 上,这个操作导致运行时报错。 我觉得这是C++编译器的bug,它本该禁止这么做。
最后:
char buffer1[6]="Hello";
char buffer2[6]="Hello";
cout<<(buffer1==buffer2 ? "" : "not ")<<"equal\n";
你还记得,这两个 "Hello" 的类型都是栈上的串,他们位置可能相同,也可能不同。
但是,这个例子又是另一个故事:
buffer1 和 buffer2 是一个6字节的自动(栈)字符串,他们都是函数内部临时分配的,拥有单独的存储空间。当执行到这一行,编译器使用拷贝指令将静态区的串分别拷贝到两个 buffer。
而:
buffer1==buffer2
仍然是刚才那句话,C/C++中数组是不能比较的, 但是他们可以隐式转换为对应首地质的指针。
而buffer1 和 buffer2 的首地址是不同的,所以本例结果是确定的 —— 表达式求值为 false。
Top
14 楼xiaoxiangfei(蜗牛)回复于 2006-03-05 14:17:25 得分 0
在JAVA中对字符串的==操作符是经过重载了的,是比较他们的值,JAVA中没有指针。结合上述的各点关C++的,我相信你一定也了解了吧!Top
15 楼Helloooooo(每天,我都新的)回复于 2006-03-05 19:31:55 得分 0
1,
char* str1="good";
char* str2="good";
2个指针并没有分配内存空间,都是指向存放“good”的内存区,因此是相等的;
2,
在JAVA中,
System.out.println(("helloworld"=="helloworld")?"等于":"不等于");
System.out.println("helloworld"==h?"等于":"不等于");
其中的“helloworld”其实是JVM生成了一个临时的String对象,并把"helloworld")?"赋植给它。
另外,在JAVA中最好不要用==判断字符串内容,好像有个equal方法吧。
Top




