strstr 返回如何不是一个常数

How strstr return is not a constant

本文关键字:一个 常数 返回 何不 strstr      更新时间:2023-10-16

标准函数strstr用于查找字符串中子字符串的位置。函数的两个参数都是const char *类型,但返回类型为char *

我想知道如何实现违反常量正确性的标准函数。

const char *告诉你的是,strstr不会修改你传递给它的字符串。

是否修改返回的字符串取决于您,因为它是您的字符串!

C++,这已通过重载方法并具有两个版本来更改,const输入版本具有const输出。

在 C 中,它没有为您内置的安全级别,并假设您自己知道是否应该修改返回的字符串。

C 允许使用 const或 non-const 指针指向内存,无论对象是否使用 const 限定符定义。

6.5 表达式

  1. 对象的存储值只能由具有以下 以下类型:

— 与对象的有效类型兼容的类型的限定版本,

strstr 在 C 语言中的原型是:

char *strstr(const char *s1, const char *s2);

返回的指针(如果有效)指向字符串 s1。这可以通过石膏实现:

const char safe = 's' ;
char* careful = ( char* )&safe ;

问题是修改该内存。

6.7.3 类型限定符

  1. 如果尝试通过使用 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 中不存在,则返回一个空指针。