问题描述
这是我的测试代码.
string str=string("def");
const char* c_str=str.c_str();
char* charString=(char*)"abc";
char* target;
cout << "str : "<< str<< endl;
cout << "c_str : "<< c_str << endl;
cout << "charString : " << charString << endl << endl;
cout << "string length : " << str.length() << endl;
cout << "c_str length : " << strlen(c_str) << endl;
cout << "c_str array length : " << (sizeof(c_str)/sizeof(*c_str)) << endl;
cout << "charString length : " << strlen(charString) << endl;
cout << "charString array length " << (sizeof(charString)/sizeof(*charString)) << endl<< endl;
target = (char*) malloc(sizeof(char)*2);
target = (char*)"ab";
cout << "target : " << target << endl;
cout << "target strlen : " << strlen(target) << endl;
cout << "target arr length : " << (sizeof(target)/sizeof(char)) << endl;
这是上述代码的结果.
str : def
c_str : def
charString : abc
string length : 3
c_str length : 3
c_str array length : 8
charString length : 3
charString array length 8
target : ab
target strlen : 2
target arr length : 8
在str,c_str,charString的情况下,strlen为3,数组长度为8.8包括编码和最后的'\ 0'字符.对吧?
In str, c_str, charString case, strlen is 3 and array length is 8.8 includes encoding and '\0' character at last. Right?
所以,我真的不了解目标案例.
So, I really don't understand target case.
我分配了2个字节的内存.并分配2个字符.strlen是正确的.
I allocate memory 2 byte.And allocate 2 characters.strlen is right.
-
但是为什么目标数组长度是8,就像c_str和charString的数组长度?为什么目标的数组长度不小于c_str和charString?
But why target array length is 8 like array length of c_str and charString? Why target's array length isn't less than c_str and charString ?
最后一个问题,我在消息头中发送消息char *,包括消息长度.如果我想从string.c_str()计算消息长度,是否需要像(sizeof(target)/sizeof(* target))那样进行计算?
Last question, I send message char* including message length in message header. If I want to calculate the message length from string.c_str(), do I have to calculate like (sizeof(target)/sizeof(*target)) ?
推荐答案
sizeof(x)/(sizeof(*x)
基本上是一个错误.这种基本构造唯一有意义的方法是x
是数组-但是在这种情况下,*x
仅通过将数组的名称转换为指向其第一个元素的指针才有意义(是的,确实会发生隐式),然后除以该项目的大小.
sizeof(x)/(sizeof(*x)
is basically a mistake. The only way this basic construct makes sense is if x
is an array--but in this case, *x
only makes sense by converting the name of the array to a pointer to its first element (which, yes, does happen implicitly), then dividing by the size of that item.
至少在理论上,sizeof(x)/sizeof(x[0])
更好一些.实际使用中没有可观察到的差异,但是至少对于观察它的人来说,使用[0]
可能会提供一些指示,表明它确实打算(仅)应用于数组,而不是指针.
At least theoretically, sizeof(x)/sizeof(x[0])
is a little better. There's no observable difference in actual use, but at least to somebody looking at it, the use of [0]
might provide some indication that this is really intended to be applied (only) to an array, not a pointer.
假设将它们应用于数组,它们仍然具有与strlen
根本不同的效果. strlen
假定其参数为NUL终止的字节序列.这意味着它将从您传递的地址开始计数字节,直到遇到包含值'\0'
的字节为止.它可能比阵列更短,或者(如果阵列不包含NTBS)可能更长.简而言之,strlen
试图告诉您字符串的当前长度,而sizeof(x)/sizeof(x[0])
试图告诉您特定数组可能具有的最大字符串大小.当应用于初始化数组,例如char foo[] = "Something";
.
Assuming they are applied to arrays, they still have an effect that's fundamentally different from strlen
. strlen
assumes its argument is a NUL-terminated byte sequence. That means it counts bytes starting from the address you pass, until it encounters a byte containing the value '\0'
. That might be shorter than the array, or (if the array doesn't contain an NTBS) potentially much longer. In short, strlen
tries to tell you the current length of a string, whereas the sizeof(x)/sizeof(x[0])
attempts to tell you the maximum string size a particular array could potentially hold. These will coincide primarily when applied to an initialized array, like: char foo[] = "Something";
.
还有一个小的区别:strlen
仅包含终止NUL之前 的字符数,其中sizeof(x)/sizeof(x[0])
包含数组的所有存储,大于最大长度您可以将NUL终止的字符串存储在此处.
One other minor difference as well: strlen
only includes the number of characters before the terminating NUL, where sizeof(x)/sizeof(x[0])
includes all the storage of the array, one larger than the maximum length of NUL-terminated string you can store there.
如果将其中任何一个应用于指针而不是数组,则可以计划通常会得到不好的结果(通常"的狡猾的措辞是为了掩盖极端情况:如果碰巧数组的大小完全相同作为指针,它可以正常工作,就像破碎的时钟每天提供两次正确的时间一样.
If you apply either of these to a pointer instead of an array, you can plan on normally getting bad results (the "normally" weasel wording being to cover the corner case: if you happen to have an array exactly the same size as a pointer, it'll work, much like a broken clock giving the right time twice a day).
在C ++中,通常使用以下方法会更好:
In C++, you're usually better off with something like this:
template <class T, size_t N>
constexpr size_t elements(T (&array)[N]) {
return N;
}
这要求您通过引用将其传递给数组.如果尝试传递指针而不是数组,则会得到编译器错误,而不是错误的答案.
This requires that you pass it an array by reference. If you attempt to pass a pointer instead of an array, you'll get a compiler error instead of an incorrect answer.
当然,在C ++中,您通常也希望避免使用strlen
-您通常可以使用std::string
(或std::string_view
)并使用其length()
或size()
成员.
Of course, in C++ you generally want to avoid using strlen
as well--you can normally use std::string
(or std::string_view
) and use its length()
or size()
member.
这篇关于如何获得char *的真实长度? strlen和sizeof(target)/sizeof(target *)之间有区别吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!