简体   繁体   English

如何将char数组作为const char * arg传递?

[英]How to pass char array as const char* arg?

How to pass char array[] to function accepting const char* arg type and what is the most proper way of doing that? 如何将char array []传递给接受const char* arg类型的函数,最正确的方法是什么?

Please ignore the fact that I'm using static 100 buffer in this example: 在此示例中,请忽略我使用静态100缓冲区的事实:

char buff[100];
sprintf_s(buff, sizeof(buff), "%s", unrelated);

Then I need to pass the buff to the function accepting const char* 然后我需要将buff传递给接受const char*的函数

MyFunction(const char* path);

I tried passing it directly: MyFunction(buff) and it works, but could someone exaplain why? 我尝试直接传递它: MyFunction(buff) ,它可以工作,但是有人可以解释为什么吗? and if there is better way to achieve the same result? 是否有更好的方法来达到相同的结果?

I tried passing it directly: MyFunction(buff) and it works, but could someone exaplain why? 我尝试直接传递它: MyFunction(buff) ,它可以工作,但是有人可以解释为什么吗? and if there is better way to achieve the same result? 是否有更好的方法来达到相同的结果?

A "better way" is open to lots of interpretation. “更好的方式”有很多解释。 Some here at SO would insist that std::string is the C++ way and therefore always better than a char[] but the truth is that it depends on what you're doing. SO的一些人会坚持说std::string是C ++的方式,因此总是比char[]更好,但事实是,这取决于您在做什么。 If you are trying to avoid dynamic memory allocations then certainly what you have is acceptable and maybe even the "best way". 如果您试图避免动态分配内存,那么您所拥有的当然可以接受,甚至是“最佳方法”。 However, if you are dynamically allocating memory for your buffer array ie const char* buff = new char[BUFF_SIZE]; 但是,如果您正在为缓冲区数组动态分配内存,即const char* buff = new char[BUFF_SIZE]; then I would argue that the "better way" is to use std::string for many reasons not the least of which is that it manages its own memory. 那么我会说“更好的方法”是出于许多原因使用std::string ,其中至少有一个原因是它管理自己的内存。 In your case you could use it like this. 在您的情况下,您可以像这样使用它。

std::string buff;
MyFunction(buff.c_str());

Why does passing a char[] to a const char* work? 为什么将char []传递给const char *起作用?

It works because array names decay into pointers to the first element when used in expressions. 之所以起作用,是因为在表达式中使用数组名称时,它们会分解为指向第一个元素的指针。 In your example, char buff[100] decays to a pointer char* when it's passed into MyFunction . 在您的示例中,当char buff[100]传递给MyFunction时,它会衰减为char*指针。 You are also allowed to pass non-const arguments as const because MyFunction is making the guarantee not to mutate the data. 还允许您将非常量参数作为const传递,因为MyFunction保证不对数据进行突变。 This implicit conversion to const is fine and allowed. 隐式转换为const是可以的并且可以的。

A properly terminated const char* is "special" and will have a \\0 sentinel value at the end so you do not need to specify the size of the buffer being passed into the function as you would with all other types of arrays. 正确终止的const char*是“特殊的”,结尾处将带有\\0 sentinel值 ,因此您不需要像传递所有其他类型的数组那样指定要传递给函数的缓冲区的大小。 The function being called will check for this null terminator and stop at the appropriate length without going out-of-bounds. 被调用的函数将检查此空终止符,并以适当的长度停止,而不会越界。 I am making an assumption that your MyFunction(const char* path); 我假设您的MyFunction(const char* path); checks for a properly null terminated C-string in this way, and if it doesn't then it must be making some potentially dangerous assumptions about path . 以此方式检查是否有一个正确的以null结尾的C字符串,如果没有,则必须对path做出一些潜在的危险假设。

The function signature can be rewriten as: 函数签名可以重写为:

int MyFunction(char const * buff);

Reading the type, from right to left, the function is requiring a pointer to a constant buffer of char (read-only). 从右到左读取类型,该函数需要一个指向char常量缓冲区的指针(只读)。 The function is promising it will not change the content of buff . 该功能很有希望,不会改变buff

You can pass a mutable buffer (non-const) because the function will not modify the buffer. 您可以传递可变缓冲区(非常量),因为该函数不会修改缓冲区。 This is allowed. 这是允许的。

You cannot pass a pointer to a constant (read only) buffer to a function that will modify the buffer. 您不能将指向常量(只读)缓冲区的指针传递给将修改缓冲区的函数。

int MutateBuffer(char * buffer);

The above is a signature of a function that may write to the buffer. 以上是可以写入缓冲区的函数的签名。 So, passing a read-only buffer to this function is not advised and the compiler will warn about it at least. 因此,不建议将只读缓冲区传递给此函数,并且编译器至少会对其进行警告。

The array "decays" into a pointer to the same memory. 数组“衰减”为指向同一内存的指针 So long as the data in the array has a sentinel (NUL-byte) at the end, the callee only needs the pointer and can use the buffer up to the sentinel. 只要数组中的数据末尾有一个标记(NUL字节),被调用方就只需要指针,就可以使用缓冲区直到标记。

Alternatively, if it's not a C-string (ie. there is no sentinel; the sentinel is the convention that makes an array a C-string), then you'd also need to pass the length of the buffer (generally sizeof(buff) ) so the callee knows how long the buffer is — to avoid overrunning it. 或者,如果它不是C字符串(即,没有哨兵;哨兵是使数组成为C字符串的约定),则还需要传递缓冲区的长度(通常为sizeof(buff) ),这样被调用者就知道缓冲区有多长时间-避免溢出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM