2

我正在查看 K&R,它说数组名称不是变量,它不能用于 a=pa 或 a++ 等结构。

这里不是s数组名吗?

    #include<stdio.h>
    main(){
        printf("%d", strlen("test"));
    }

    int strlen(char s[])
    {
        int n;
        for (n = 0; *s!= '\0';s++) // why is s++ valid even though it is declared as an array
            n++;
        return n;
    }
4

4 回答 4

3

马口中

6.3.2.1 左值、数组和函数指示符

...
3 除非它是运算sizeof符、运算符_Alignof或一元&运算符的操作数,或者是用于初始化数组的字符串文字,否则类型为 ''array of type '' 的表达式将转换为表达式类型 ''pointer to type '' 指向数组对象的初始元素并且不是左值。如果数组对象具有 register存储类,则行为未定义。

该表达式"test"是一个字符串字面量,其类型为“5 元素数组char”。当您"test"作为 的参数传递时strlen,根据上面的规则,实际传递的是一个指针,其值是 中第一个字符的地址"test"

这让我们...

6.7.6.3 函数声明器(包括原型)

...
7 将参数声明为“类型数组”应调整为“指向 类型的限定指针”,其中类型限定符(如果有)是[在数组类型派生的 and ] 中指定的那些. 如果关键字static也出现在数组类型派生的[and]中,那么对于函数的每次调用,对应的实际参数的值应提供对数组的第一个元素的访问,该数组的元素至少与大小指定的一样多表达。

所以在原型中strlenchar s[]等价于char *ss被声明为指向 的指针char,而不是 的数组char

与其他语言相比,C 对数组的处理有点巴洛克式的。这部分是由于 BCPL 和 B 遗产。如果您对原因感到好奇,可以阅读 dmr 的The Development of the C Language以获得一些见解。

于 2012-09-15T13:52:44.247 回答
3

不,在这种情况下,它是指向 a 的指针char。您的函数声明完全等同于:

int strlen(char *s)

正如您将看到的,实际上不可能将数组传递给函数:指向第一个元素的指针是实际传递的内容。

因此,因为s它实际上是一个指针而不是一个数组,所以您可以随意修改它。

于 2012-09-15T06:32:22.443 回答
1

不,s实际上是一个指针名称。声明int strlen(char s[])int strlen(char *s)

于 2012-09-15T06:34:36.540 回答
1

当 Char s[]={...} 被声明时,地址被附加到 s,它永远不会改变(如常量指针),任何试图改变这个属性的东西都会变成非法操作,比如 s++。

但是在函数调用int strlen(char s[])中,数组作为指针传递。

于 2012-09-15T06:58:48.847 回答