关于const字符串数组存储一个奇怪的现象

mcmay 2014-11-01 06:33:43
以下代码的作用是返回数组中最大值(如果是字符串数组则返回数组中最长的那个字符串,如果有几个等长字符串最长,则返回其中第一个的地址)
// ex6, ch 8
#include <iostream>
#include <cstring>

template <typename T>
T ret_max(T [], int);

template <> char * ret_max(char *[], int);

int main()
{
using namespace std;
int ar_int[6] = {3, 7, 2, 5, 6, 4};
double ar_doub[4] = {2.1, 3.4, 1.8, 4.2};
char * str[5] = {
"I really can't understand you.",
"You're my dearest baby.",
"How much do you love me?",
"I really can't understand you.",
"I really can't understand you."
};
char * s;

cout << "Max of the six integers: " << ret_max(ar_int, 6) << endl;;
cout << "Max of the four integers: " << ret_max(ar_doub, 4) << endl;
cout << "The five strings and their addresses:" << endl;
for (int i = 0; i < 5; i++)
{
cout << str[i] << endl;
cout << (unsigned)str[i] << endl;
}
cout << "The largest of the five and its address:" << endl;
s = ret_max(str, 5);
cout << s << endl;
cout << (unsigned)s << endl; // 用unsigned打印指针内容,请还有其他打印法可以显示0x进制的模式吗?

return 0;
}

template <typename T>
T ret_max(T ar[], int n)
{
T max = ar[0];
for(int i = 0; i < n; i++)
if(max < ar[i])
max = ar[i];
return max;
}

template <> char * ret_max(char * str[], int n)
{
int i, max = 0;

for(i = 0; i < n; i++)
if(strlen(str[max]) < strlen(str[i]))
max = i;

return str[max];
}


运行结果:
Max of the six integers: 7
Max of the four integers: 4.2
The five strings and their addresses:
I really can't understand you.
4214892 // 这些长度一致的数组,竟然地址一样!
You're my dearest baby.
4214923
How much do you love me?
4214947
I really can't understand you.
4214892 // 同上
I really can't understand you.
4214892 // 同上
The largest of the five and its address:
I really can't understand you.
4214892
...全文
141 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
FancyMouse 2014-11-02
  • 打赏
  • 举报
回复
编译器都有选项可以开关的。gcc是-fmerge-constants -fno-merge-constants,vc是/GF /GF-
brookmill 2014-11-01
  • 打赏
  • 举报
回复
引用 3 楼 mcmay 的回复:
谢谢!原来如此!我实验过了,果然换一个字符就会导致地址变化。看来这也许是编译器的某种优化,让程序尽量少占空间。不过,如果程序真的需要将相同的字符串存放在不同地址,那就麻烦了。
常量区的字符串,只能读不能修改,好像没什么必要存放多个拷贝或者放到不同地址。 如果你想把字符串存放到其它地方,自己复制过去就行了。比如: char *p = "hello, world"; char str[128]; strcpy(str, p);
mcmay 2014-11-01
  • 打赏
  • 举报
回复
引用 2 楼 brookmill 的回复:
char * str[5] = { "I really can't understand you.", "You're my dearest baby.", "How much do you love me?", "I really can't understand you.", "I really can't understand you." }; 这是一个数组,数组的每个元素都是char *。如果看一下sizeof(str),应该是20,也就是5个指针的大小。 编译器实际上是在常量区保存了这些字符串,然后把他们的地址保存到str数组里面。 对于完全相同的字符串,大多数编译器会只保存一次。 简化一下: char *p1 = "abcd"; char *p2 = "abcd"; cout << (unsigned long)p1 << endl << (unsigned long)p2 << endl; // 看看是不是输出两个一样的值
谢谢!原来如此!我实验过了,果然换一个字符就会导致地址变化。看来这也许是编译器的某种优化,让程序尽量少占空间。不过,如果程序真的需要将相同的字符串存放在不同地址,那就麻烦了。
brookmill 2014-11-01
  • 打赏
  • 举报
回复
char * str[5] = { "I really can't understand you.", "You're my dearest baby.", "How much do you love me?", "I really can't understand you.", "I really can't understand you." }; 这是一个数组,数组的每个元素都是char *。如果看一下sizeof(str),应该是20,也就是5个指针的大小。 编译器实际上是在常量区保存了这些字符串,然后把他们的地址保存到str数组里面。 对于完全相同的字符串,大多数编译器会只保存一次。 简化一下: char *p1 = "abcd"; char *p2 = "abcd"; cout << (unsigned long)p1 << endl << (unsigned long)p2 << endl; // 看看是不是输出两个一样的值
brookmill 2014-11-01
  • 打赏
  • 举报
回复
引用 楼主 mcmay 的回复:
4214892 // 这些长度一致的数组,竟然地址一样!
第一,这些不是数组,而是指针。 第二,他们不只是长度一致,而是完全一模一样。如果改动其中一个而保持长度不变,你会看到地址就不一样了。

64,653

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧