字符串字面值让我很纠结啊

时间:2022-10-04 14:46:48

template <typename T>
int compare(const T &v1, const T &v2)
{
cout << v1 << " " << &v1 << " " << v2 << " " << &v2 << endl;
if (v1 < v2) return -1;
if (v1 > v2) return 1;
return 0;
}

int main(int argc, char *argv[])
{
        cout << compare("a", "w") << endl;
//cout << compare("w", "a") << endl;


cout << endl;
system("pause");
return 0;
}

以上代码中,compare返回的是-1.
但如果注释掉第一行的compare(一定要注释掉),打开第二行的compare,返回值还是-1!
纠结了很久,唯一的解释就是操作符'<'或'>'之类的被重载了,如果操作数是char*之类的,进行比较的是地址而不是值!
求大牛更详细的解释或关于这方面的资料!

9 个解决方案

#1



你这个代码,实际传入的是 “W” 和 "A"的地址;而compare这个模板函数,仅仅是对地址的比较。所以出现这种情况,

仅仅是需要特化。 可以看看 C++ primer 中关于 模板特化的章节。



#2


引用 1 楼  的回复:
你这个代码,实际传入的是 “W” 和 "A"的地址;而compare这个模板函数,仅仅是对地址的比较。所以出现这种情况,

仅仅是需要特化。 可以看看 C++ primer 中关于 模板特化的章节。

一点都不赞同!
函数compare很清楚的输出了:cout << v1 << " " << &v1 << " " << v2 << " " << &v2 << endl;
v1,v2都是把值输出来的,但是做为if的条件时,我怀疑比较的是地址,所以我怀疑"<"等被重载了!

#3


cout << "e" << endl;
cout << &"e" << endl;
说明字符串字面值本身可以作为自己的变量名,传地址也是要加&

#4


char (*p)[2] = "e";
编译出错,error C2440: “初始化”: 无法从“const char [2]”转换为“char (*)[2]”
char (*p)[2] = &"e";
编译成功更可以看出"e"是个值!

#5


引用 2 楼  的回复:
引用 1 楼  的回复:
你这个代码,实际传入的是 “W” 和 "A"的地址;而compare这个模板函数,仅仅是对地址的比较。所以出现这种情况,

仅仅是需要特化。 可以看看 C++ primer 中关于 模板特化的章节。

一点都不赞同!
函数compare很清楚的输出了:cout << v1 << " " << &amp;v1 << " " << v2 << " " << &a……


兄弟,先看完模板特化,在深入考虑
然后你再考虑下下边的表达式。

char * p1 = "a" ;
char * p2 = "w";

if(p1 < p2)  // 请问字符串比较是这么比较的么?
{
    //
}

#6


引用 5 楼  的回复:
引用 2 楼  的回复:

引用 1 楼  的回复:
你这个代码,实际传入的是 “W” 和 "A"的地址;而compare这个模板函数,仅仅是对地址的比较。所以出现这种情况,

仅仅是需要特化。 可以看看 C++ primer 中关于 模板特化的章节。

一点都不赞同!
函数compare很清楚的输出了:cout << v1 << " " << &amp;amp;v1 << " ……

这跟模板没关系,compare完全可以改成就接受const char (&)[2]类型!

#7


引用 5 楼  的回复:
引用 2 楼  的回复:

引用 1 楼  的回复:
你这个代码,实际传入的是 “W” 和 "A"的地址;而compare这个模板函数,仅仅是对地址的比较。所以出现这种情况,

仅仅是需要特化。 可以看看 C++ primer 中关于 模板特化的章节。

一点都不赞同!
函数compare很清楚的输出了:cout << v1 << " " << &amp;amp;v1 << " ……

你的例子也能描述我的疑问,cout << p输出了"a",p如果是指针为什么不是输出地址呢?

const char (&ch1)[2] = "a";
const char (&ch2)[2] = "w";

cout << ch1 << endl;
if (ch1 < ch2)
{
}

有两种解释:
1.cout对指向char的指针进行了重载,输出是*ch
2.<操作符对char的引用进行了重载,比较的是&ch
现在就是想办法找到证据证明而已!

#8


楼主,别学C/c++了, 远远超出了你的理解能力。 学C#吧。 

#9


VC调试时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!
指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。”

这辈子不看内存地址和内存值;只画链表、指针示意图,画堆栈示意图,画各种示意图,甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗?本人深表怀疑!
这辈子不种麦不收麦不将麦粒拿去磨面;只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头,压面条,烤面包,……能从本质上理解面粉、理解面食吗?本人深表怀疑!!

提醒:
“学习用汇编语言写程序”

“VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习C和汇编的对应关系。”
不是一回事!

不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!

有人说一套做一套,你相信他说的还是相信他做的?
其实严格来说这个世界上古往今来所有人都是说一套做一套,不是吗?

不要写连自己也预测不了结果的代码!

#1



你这个代码,实际传入的是 “W” 和 "A"的地址;而compare这个模板函数,仅仅是对地址的比较。所以出现这种情况,

仅仅是需要特化。 可以看看 C++ primer 中关于 模板特化的章节。



#2


引用 1 楼  的回复:
你这个代码,实际传入的是 “W” 和 "A"的地址;而compare这个模板函数,仅仅是对地址的比较。所以出现这种情况,

仅仅是需要特化。 可以看看 C++ primer 中关于 模板特化的章节。

一点都不赞同!
函数compare很清楚的输出了:cout << v1 << " " << &v1 << " " << v2 << " " << &v2 << endl;
v1,v2都是把值输出来的,但是做为if的条件时,我怀疑比较的是地址,所以我怀疑"<"等被重载了!

#3


cout << "e" << endl;
cout << &"e" << endl;
说明字符串字面值本身可以作为自己的变量名,传地址也是要加&

#4


char (*p)[2] = "e";
编译出错,error C2440: “初始化”: 无法从“const char [2]”转换为“char (*)[2]”
char (*p)[2] = &"e";
编译成功更可以看出"e"是个值!

#5


引用 2 楼  的回复:
引用 1 楼  的回复:
你这个代码,实际传入的是 “W” 和 "A"的地址;而compare这个模板函数,仅仅是对地址的比较。所以出现这种情况,

仅仅是需要特化。 可以看看 C++ primer 中关于 模板特化的章节。

一点都不赞同!
函数compare很清楚的输出了:cout << v1 << " " << &amp;v1 << " " << v2 << " " << &a……


兄弟,先看完模板特化,在深入考虑
然后你再考虑下下边的表达式。

char * p1 = "a" ;
char * p2 = "w";

if(p1 < p2)  // 请问字符串比较是这么比较的么?
{
    //
}

#6


引用 5 楼  的回复:
引用 2 楼  的回复:

引用 1 楼  的回复:
你这个代码,实际传入的是 “W” 和 "A"的地址;而compare这个模板函数,仅仅是对地址的比较。所以出现这种情况,

仅仅是需要特化。 可以看看 C++ primer 中关于 模板特化的章节。

一点都不赞同!
函数compare很清楚的输出了:cout << v1 << " " << &amp;amp;v1 << " ……

这跟模板没关系,compare完全可以改成就接受const char (&)[2]类型!

#7


引用 5 楼  的回复:
引用 2 楼  的回复:

引用 1 楼  的回复:
你这个代码,实际传入的是 “W” 和 "A"的地址;而compare这个模板函数,仅仅是对地址的比较。所以出现这种情况,

仅仅是需要特化。 可以看看 C++ primer 中关于 模板特化的章节。

一点都不赞同!
函数compare很清楚的输出了:cout << v1 << " " << &amp;amp;v1 << " ……

你的例子也能描述我的疑问,cout << p输出了"a",p如果是指针为什么不是输出地址呢?

const char (&ch1)[2] = "a";
const char (&ch2)[2] = "w";

cout << ch1 << endl;
if (ch1 < ch2)
{
}

有两种解释:
1.cout对指向char的指针进行了重载,输出是*ch
2.<操作符对char的引用进行了重载,比较的是&ch
现在就是想办法找到证据证明而已!

#8


楼主,别学C/c++了, 远远超出了你的理解能力。 学C#吧。 

#9


VC调试时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!
指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。”

这辈子不看内存地址和内存值;只画链表、指针示意图,画堆栈示意图,画各种示意图,甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗?本人深表怀疑!
这辈子不种麦不收麦不将麦粒拿去磨面;只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头,压面条,烤面包,……能从本质上理解面粉、理解面食吗?本人深表怀疑!!

提醒:
“学习用汇编语言写程序”

“VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习C和汇编的对应关系。”
不是一回事!

不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!

有人说一套做一套,你相信他说的还是相信他做的?
其实严格来说这个世界上古往今来所有人都是说一套做一套,不是吗?

不要写连自己也预测不了结果的代码!