理解 strlen 函数 - 将 const char *s 赋值给 const char *sc

4
以下是根据《标准C库》实现的strlen.c:
```c #include size_t strlen(const char *s) { const char *p = s; while (*p) ++p; return p - s; } ```
size_t strlen(const char *s){
   const char *sc;
   for(sc = s; *sc != '\0'; ++sc)

   return (sc-s);  }

我对sc=s的合法性理解正确吗?

sc=s是一个合法的赋值语句,因为两个变量都被声明为const,都保护了指向s所指向的对象。在这种情况下,改变sc或s指向的位置是合法的,但任何对*ssc的赋值(或引用)都是非法的。


3
scs不是常量,它们指向可能是常量的东西。 - M.M
3个回答

5
我认为您正在询问的是“const”关键字的含义。如果不是,请澄清您的问题。
我喜欢将其想象成任何const变量都可以存储在ROM(只读存储器)中,而未声明为const的变量则可以存储在RAM(随机访问存储器)中。这在某种程度上取决于您使用的计算机,因此const数据实际上可能不会存储在ROM中,但它确实可以这样做。
因此,您可以随意处理指针本身,但不能更改它所指向的内存中的数据。
这意味着您可以引用指针并传递它,就像您喜欢的那样。还可以为指针分配不同的值。
比如说你有这段代码:
const char* foo = "hello";
const char* bar = "world";

这是完全合法的。

foo = bar;

现在两个点都指向“world”

这也是合法的操作

const char *myPtr = bar;
myPtr = foo;

你不允许更改实际的数据存储器,因此你不能这样做。

foo[0] = 'J';

2
您说得对。 const char * sc声明了一个指向const char类型的指针。实质上,这意味着sc指向一个char类型的变量(或在该情况下,指向一组连续的char),而且您不能使用sc修改所指的变量。可以在此处查看演示。
请注意,sc本身并不是一个const变量。 const适用于被指向的变量,而不适用于指针本身。因此,您可以更改指针的值,即它所指向的变量。
请参考此答案以深入了解const和指针的不同用法:const int*、const int * const 和 int const *之间的区别是什么?

“const”适用于指向的变量,因此在sc=s的情况下,const char sc中的“const”是应用于s还是s的值?在我的回答中,我假设两个“const”声明都适用于指针的最终值,但现在我不太确定了。也就是说,如果它适用于s,那么在声明sc=s之后,更改s所指向的内容将变为非法。 - M.A.A
@M.O. 这个赋值语句不应该改变任何东西。两个变量都声明为指向常量字符的指针,因此它们所指向的值是常量,而指针本身则不是。由于赋值操作只是将指针赋值给了另一个指针,而没有改变它们所指向的内存,所以这段代码是合法的。如果要使指针成为常量,可以在 * 后面加上 const - eesiraed

2
“sc = s”的合法性理解是否正确?
是的,只需要对最后一部分进行一些详细说明。
但是对于任何对*s或sc的赋值(或引用?),都是非法的。(我怀疑OP指的是“...或*sc是非法的。”)
像char ch = *sc;这样引用s或sc指向的内容是可以的。
试图更改*s或*sc的值是未定义行为(UB),而不是“非法的”,例如*sc='x';(请参见@rici的好补充细节
使用UB,作业可能能够运行,也可能在周二不能运行,代码可能会崩溃等。C语言没有定义会发生什么。确保代码不应该尝试这样做。

1
无论 sc 指向什么,*sc = 'x'; 都是一个约束违规(6.5.16/2)。必须产生一条诊断消息。如果 sc 所指向的任何内容最初都带有 const 修饰符,则 *(char *)sc = 'x'; 就是未定义行为;否则它是合法的。(6.7.3/6)(我知道你知道这一点。也许在这个问题上区分没有必要,但这并不会有害。) - rici

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接