strstr 返回如何不是一个常数
How strstr return is not a constant
标准函数strstr
用于查找字符串中子字符串的位置。函数的两个参数都是const char *
类型,但返回类型为char *
。
我想知道如何实现违反常量正确性的标准函数。
const char *
告诉你的是,strstr
不会修改你传递给它的字符串。
是否修改返回的字符串取决于您,因为它是您的字符串!
C++,这已通过重载方法并具有两个版本来更改,const
输入版本具有const
输出。
在 C 中,它没有为您内置的安全级别,并假设您自己知道是否应该修改返回的字符串。
C 允许使用 const或 non-const 指针指向内存,无论对象是否使用 const 限定符定义。
6.5 表达式
- 对象的存储值只能由具有以下 以下类型:
— 与对象的有效类型兼容的类型的限定版本,
strstr 在 C 语言中的原型是:
char *strstr(const char *s1, const char *s2);
返回的指针(如果有效)指向字符串 s1。这可以通过石膏实现:
const char safe = 's' ;
char* careful = ( char* )&safe ;
问题是修改该内存。
6.7.3 类型限定符
- 如果尝试通过使用 const 限定类型修改使用定义的对象 对于具有非常量限定类型的左值,行为是未定义的。
既然你创建了字符串,你应该知道你是否可以修改它,因此你可以接受带有指向 const 的指针的返回值,以避免任何问题:
const char* find = strstr( ... ) ;
根据 ISO C++ 21.8(7),strstr
返回const char*
或char*
,具体取决于它是获得const char*
还是char*
。
const char* strstr(const char* s1, const char* s2); char* strstr( char* s1, const char* s2);
这是通过指定签名来完成的,并将实现留给编译器构建器。
请注意,返回指向const char[]
字符串的char*
很危险,但尚未违反任何规则。但是,任何写入该内存的尝试仍然是未定义的行为。
strstr
函数可以追溯到没有const
指针的时代。 如果代码写入由传递给strstr
的第一个指针标识的内存是合法的,那么代码写入由返回的指针标识的内存是合法的,并且在返回值仅以指向只读内存的指针(例如字符串文字)合法的方式使用的情况下, 人们可以合法地将这样的指针传递给strstr
.
如果今天定义了类似于strstr
的功能,则可以使用两种方法实现它 - 一种方法可以接受任何指针并返回接收方无法写入的指针,另一种方法仅接受可写指针,但返回接收方可以使用的指针。 但是,由于某些使用strstr
的代码需要传递只读指针,并且由于某些使用strstr
的代码需要能够写入在给定可写指针时将生成的指针,因此必须让一组指针限定双向工作。 结果是一组指针限定条件,这些限定条件并不真正"安全"[因为它可能会返回指向只读内存区域的可写指针],并且它将允许代码在某些情况下编译它确实"不应该",但它将允许在const
指针之前编写的代码继续按预期工作。
>C++提供了两个版本,一个采用常量参数,一个采用非常量参数。
const char* strstr( const char* str, const char* target );
char* strstr( char* str, const char* target );
由于在 C 中我们不能重载,因此我们有两个不愉快的选择:
- 要么我们将参数视为非常量,但如果我们的来源确实是常量,那么我们需要对非常量进行令人不快的投射。
- 第二种选择是我们所拥有的一种选择,即我们将参数视为常量,但我们返回一个非常量。我们可以返回一个常量字符*,但我们永远无法修改结果。
返回值不是作为参数传递给函数的变量。此函数返回一个指针,指向 haystack 中指定的任何整个字符序列中的第一个匹配项,如果该序列在 haystack 中不存在,则返回一个空指针。
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 运行同一解决方案的另一个项目的项目
- 挂起和取消挂起一个文件DLL
- 用C++中的一个变量定义一个常量
- 函数向量_指针有不同的原型,我可以构建一个吗
- 为什么 g++ 使用 movabs 和一个奇怪的常数来简单还原?
- 在CUDA内核中传递一个常数整数
- 我可以定义一个(键入的)常数,该常数确定不占据可执行文件中的空间
- 为什么一个表达是常数,而不是另一个表达
- 在另一个带有名称空间的标头文件中定义常数
- strstr 返回如何不是一个常数
- 为什么不允许将右值引用绑定到非常数引用,而允许在其中一个上调用非常数成员函数
- 在C++中,我应该在什么时候使一个方法为常数
- 一个数据结构的线性时间构造,如果两个字符串有两个共同的字母,则在常数时间内回答
- 为什么这不是一个常数表达式
- 我无法用我的实际知识解决一个转瞬即逝的常数错误
- 调用一个具有非常数指针的函数会重新解析为一个模板函数,而不是一个具有指向常量指针的函数
- 太阳工作室10有一个奇怪的“太阳”常数