sizeof(字符串)的返回值问题

rickys2080 2012-04-24 01:44:28

#include<stdio.h>
#include<conio.h>
#include<string.h>

/***********************************************************
返回最长字符串
***********************************************************/
#if 1

#define MAX_LEN(a, b) ((sizeof(a) >= sizeof(b)) ? (a):(b))

#else

char *MAX_LEN(char *a, char *b)
{
return (((strlen(a) >= strlen(b)) ? (a):(b)));
}
#endif

int main (void)
{
printf(" sizeof(\"VC\")-> %d\r\n\
sizeof(\"Java\")-> %d\r\n\
sizeof(\"C++\")-> %d\r\n\
sizeof(\"JavaScript\")-> %d\r\n",
sizeof("VC"),
sizeof("Java"),
sizeof("C++"),
sizeof("JavaScript"));

printf(" %s\r\n", MAX_LEN("VC", "Java"));
printf(" %s\r\n", MAX_LEN(MAX_LEN("VC", "Java"), "C++"));
printf(" %s\r\n", MAX_LEN(MAX_LEN(MAX_LEN("VC", "Java"), "C++"), "JavaScript"));

printf(" %s\r\n", MAX_LEN(MAX_LEN("hello", "world"), "www.baidu.com"));
printf(" %s\r\n", MAX_LEN(MAX_LEN(MAX_LEN("hello", "wold"), "www.baidu.com"), "Java"));//这里不是应该返回"www.baidu.com吗?为什么输出是"Java"?

_getch();
return 0;
}
...全文
803 35 打赏 收藏 转发到动态 举报
写回复
用AI写文章
35 条回复
切换为时间正序
请发表友善的回复…
发表回复
unituniverse2 2012-04-25
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 的回复:]

引用 23 楼 的回复:
没什么解释的,运行结果中有超过4的就对了!
.

为什么楼主最好一个printf()输出的不是最长的字符串?
[/Quote]
表达式返回的结果,右值数组会隐式转换成左值指针的。看这个例子:
printf(" %d\r\n", sizeof(sizeof(1 ? "12345678" : "12")));
它的输出不是9而是4(更不会是3)
unituniverse2 2012-04-25
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 的回复:]

引用 23 楼 的回复:
没什么解释的,运行结果中有超过4的就对了!
.

为什么楼主最好一个printf()输出的不是最长的字符串?
[/Quote]

表达式返回的结果,右值数组会隐式转换成左值指针的。看这个例子:
printf(" %d\r\n", sizeof(sizeof(1 ? "123456789" : "12")));
它的输出不是9而是4(更不会是3)
unituniverse2 2012-04-25
  • 打赏
  • 举报
回复
[Quote=引用 30 楼 的回复:]

由于宏定义无法在调试的时候测试,测试代码的时候你需要自己重新写一份函数,可以利用软件开发时候定义宏的#ifdef RELEASE 这样的方式把宏定义的东西测试确定可用再发出来
[/Quote]

测试宏定义的方法:
#define _REPORTMACROCONTEXT(...) #__VA_ARGS__
#define REPORTMACROCONTEXT(...) _REPORTMACROCONTEXT(__VA_ARGS__)

用字符串打印函数(比如printf或std::cout)把你要测试的宏当REPORTMACROCONTEXT的参数输入就可以了(不要直接使用_REPORTMACROCONTEXT)
rickys2080 2012-04-24
  • 打赏
  • 举报
回复
29楼正解!
结贴,分数全给你了!
学习了,谢谢!
rickys2080 2012-04-24
  • 打赏
  • 举报
回复
楼上大牛,我学习一下!
冷月孤城 2012-04-24
  • 打赏
  • 举报
回复
由于宏定义无法在调试的时候测试,测试代码的时候你需要自己重新写一份函数,可以利用软件开发时候定义宏的#ifdef RELEASE 这样的方式把宏定义的东西测试确定可用再发出来
冷月孤城 2012-04-24
  • 打赏
  • 举报
回复
出现输出为“java”而不是“www.baidu.com”的主要原因不在于sizeof()本身怎么样,而是你用#if定义了一个宏MAX_LEN(a, b)执行之后返回的并不是a,b中的某个指针而是一个临时的变量指针,因为临时变量指针不同于字符串常量所以sizeof()这个临时变量的时候返回值为4,其实你不需要弄那么长串的东西来验证,简单一点的说
printf(" %s\r\n", MAX_LEN(MAX_LEN("C", "c"), "C+"));
上条语句的执行结果是C而不是C+,原因是前面的sizeof()结果为4,而"C+"的sizeof结果为3
你执行的程序中有假象蒙蔽了你导致你误以为程序只有一条语句执行出错比如:
printf(" %s\r\n", MAX_LEN(MAX_LEN(MAX_LEN("VC", "Java"), "C++"), "JavaScript"));
这条语句你反汇编或者调试的时候会看到的是前面的返回结果为4然后和sizeof()"JavaScript"比较所以得到的值是"JavaScript"
你执行与你预想不同的那条语句
printf(" %s\r\n", MAX_LEN(MAX_LEN(MAX_LEN("hello", "wold"), "www.baidu.com"), "Java"));
前面的到的sizeof()结果为4后面sizeof()“java”的结果为5所以输出结果为java
写程序不能想当然,遇到问题记得调试单步的看,再不行就看它的汇编代码,多迷信编译器的单步执行,多反汇编看代码生成机理才能对学习有利。
赵4老师 2012-04-24
  • 打赏
  • 举报
回复
sizeof似乎是在编译期而不是在运行时计算的。
sdu_sky 2012-04-24
  • 打赏
  • 举报
回复
sizeof()如果是指针的话 会输出指针长度,要得到字符数组长度可以使用strlen()
冷月孤城 2012-04-24
  • 打赏
  • 举报
回复
sizeof()里面放入字符串常量的出的值是strlen()该字符串+1 编译器把'\0'也算进去了.
rickys2080 2012-04-24
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 的回复:]
没什么解释的,运行结果中有超过4的就对了!
[/Quote].

为什么楼主最好一个printf()输出的不是最长的字符串?
unituniverse2 2012-04-24
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 的回复:]

细节就是"abcdef"到底是个什么数据类型。
[/Quote]
sizeof接受的参数其实是一个类型(不像函数接受的是值)。如果给值,sizeof会先求其类型的。如果分析不出或者有二义性的话,编译通不过。
unituniverse2 2012-04-24
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 的回复:]

引用 20 楼 unituniverse2 的回复:

这问题没什么好讨论的,都是基础的东西。
sizeof对于任何类型返回的都是该类型数据的总字节数。如果是数组,自然是数组的总大小,这个和结构体取sizeof道理相同;如果是一个指针,返回的当然是指针的字节大小。所以这里的问题就变成了编译器到底是把字符串当成什么看待了。如果直接写一个字符串取sizeof,字符串常量是一个右值,不存在什么地……
[/Quote]

没什么解释的,运行结果中有超过4的就对了!
pathuang68 2012-04-24
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 的回复:]

引用 14 楼 的回复:

如果是求字符串的长度,建议用strlen。

因为sizeof的参数是数据类型,那么"abcdef"的数据类型到底是什么呢?char const [8]还是char*?这个可能不同的编译器有不同的处理,如果是前者那么结果就是7,如果是后者那么结果就是4。

如果楼主的本意是用sizeof("abcdef")来求其长度,那么语义上是存在问题的,因此碰到这种……
[/Quote]

细节就是"abcdef"到底是个什么数据类型。
rickys2080 2012-04-24
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 unituniverse2 的回复:]

这问题没什么好讨论的,都是基础的东西。
sizeof对于任何类型返回的都是该类型数据的总字节数。如果是数组,自然是数组的总大小,这个和结构体取sizeof道理相同;如果是一个指针,返回的当然是指针的字节大小。所以这里的问题就变成了编译器到底是把字符串当成什么看待了。如果直接写一个字符串取sizeof,字符串常量是一个右值,不存在什么地址,sizeof返回的自然是这个字符数组的字节大小。另外,s……
[/Quote]

对!!!
专业!
但是你帮忙解释一下楼主程序的问题吧,谢谢
unituniverse2 2012-04-24
  • 打赏
  • 举报
回复
这问题没什么好讨论的,都是基础的东西。
sizeof对于任何类型返回的都是该类型数据的总字节数。如果是数组,自然是数组的总大小,这个和结构体取sizeof道理相同;如果是一个指针,返回的当然是指针的字节大小。所以这里的问题就变成了编译器到底是把字符串当成什么看待了。如果直接写一个字符串取sizeof,字符串常量是一个右值,不存在什么地址,sizeof返回的自然是这个字符数组的字节大小。另外,sizeof()的值包含了最后一个0字符的大小,不像strlen那样。还有就是sizeof的值在编译期就会得以确定,求值不会占用任何运行时间的,而strlen会在运行时求值。除非你觉得字符串的内容会在运行期间变化,否则用strlen不比sizeof好到哪里去的。
rickys2080 2012-04-24
  • 打赏
  • 举报
回复
这里不是简单的sizeof(指针)问题,请运行一下程序
rickys2080 2012-04-24
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 的回复:]

指针就是地址 名字会不同 但内存中只占有4个字节 32位的
[/Quote]

http://blog.sina.com.cn/s/blog_67d069a90100ui4p.html
rickys2080 2012-04-24
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 的回复:]

如果是求字符串的长度,建议用strlen。

因为sizeof的参数是数据类型,那么"abcdef"的数据类型到底是什么呢?char const [8]还是char*?这个可能不同的编译器有不同的处理,如果是前者那么结果就是7,如果是后者那么结果就是4。

如果楼主的本意是用sizeof("abcdef")来求其长度,那么语义上是存在问题的,因此碰到这种情况,建议用strlen
[/Quote]

是推荐用strlen,但我想知道这个sizeof("abcdef")的细节
xuyinglin 2012-04-24
  • 打赏
  • 举报
回复
指针就是地址 名字会不同 但内存中只占有4个字节 32位的
加载更多回复(15)

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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