我有一个在const *中搜索内容的函数。并将这样的const *返回给找到的元素。因此该函数没有改变任何东西,我实际上想要保持“const”的可读性和可重用性。 但我有另一个函数,只用一个*调用该函数,然后使用返回的值。但在这个用例中,应该更改值。但是因为返回的值是const *我不能那样做。 我应该调整我的编程模式以避开这个问题吗?
const void* search_min_vector_element(const void* vector, size_t length, size_t element_size, int(*cmp_fnc) (const void*, const void*));
这是第一个功能。
void* min_element = search_min_vector_element((unsigned char*) vector + (i * element_size), length - i, element_size, cmp_fnc);
这就是第二个电话。在这种情况下,vector
无效*。因此,我想修改它。
谢谢你的帮助。
答案 0 :(得分:2)
您可以根据参数的类型选择要执行的函数。编写_Generic宏来选择允许的类型,然后根据它调用适当的函数。例如:
#include <stdio.h>
char* print_str (char* str)
{
printf("%s\n", str);
return str;
}
const char* print_str_const (const char* str)
{
printf("const %s\n", str);
return str;
}
#define print(str) \
_Generic((str), \
const char*: print_str_const, \
char*: print_str) (str)
int main(void)
{
const char* cstr = "hello";
char* str = "world";
cstr = print(cstr); // ok
str = print(str); // ok
cstr = print(str); // ok
//str = print(cstr); // compiler error, incorrect assignment
//str = print((void*)str); // compiler error, wrong type
}
答案 1 :(得分:0)
在C ++中,你有很多选择来处理这个问题。但由于这是C,创建另一个函数是我目前可以提出的最佳解决方案:
const void* search_min_vector_element_const(const void* vector, size_t length, size_t element_size, int(*cmp_fnc) (const void*, const void*));
void* search_min_vector_element ( void* vector, size_t length, size_t element_size, int(*cmp_fnc) ( void*, void*));
您也可以直接强制转换结果:
void* min_element = (void*)search_min_vector_element((unsigned char*) vector + (i * element_size), length - i, element_size, cmp_fnc);
答案 2 :(得分:0)
我真的建议将返回类型(如果可以)更改为不是常量值。这不是search_min_vector_element的业务,而是另一个函数应该对结果做什么。
如果您无法更改退货类型,则需要:
const void* value = search_min_vector_element(....)
void* second_no_const_value = *value; // copy value of the value pointed by constant pointer.
答案 3 :(得分:0)
因为你知道你持有一个指向vector
的非常量指针的事实,你应该简单地转换你收到的const指针:
void* min_element = (void*)search_min_vector_element(...);
答案 4 :(得分:0)
从技术上讲,您可以通过显式转换从const char*
转换为char*
,而不会产生未定义的行为本身;但是,如果您更改了一个不得更改的值(例如字符串文字),那么您将获得未定义的行为。因此const
- 限定符不会禁止更改基础数据,但是当在函数参数或返回值中用作限定符时,函数原型假装该值不应被更改。
因此,如果你 - 或者一个库 - 在不知道实现的情况下提供了返回类型为const char*
的函数,则不应假设返回的值指向可能被更改的内存。请参阅以下示例说明此内容。除了名称之外,函数validImpl1
和validImpl2
具有相同的签名但不同的实现。如果您传入的参数的内容可能会被更改,则将返回值转换为第一个char*
是正常的,但对于第二个,它会产生UB。因此,除非您知道函数的内部,否则不应该从const char*
转换为char *
:
const char* validImpl1(const char* t) {
return t;
}
const char* validImpl2(const char* t) {
return "Hello!";
}
int main() {
char x[100] = "Herbert";
char* t=(char*) validImpl1(x);
*t = 'a'; // OK
printf("%s\n",t);
char* t2=(char*) validImpl2(x);
*t2 = 'a'; // Undefined behaviour here.
printf("%s\n",t2);
}
在您的情况下,如果您是提供该功能并了解实施细节的人,您可以提供两个功能,一个使用const char*
,另一个使用char*
,后者只需调用前任的。所以使用你的函数的人可以依赖函数原型假装的东西。