2

I'm going through K&R and it says array name is not a variable and it cannot be used in constructions like a=pa or a++.

Isn't s an array name here?

    #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;
    }
2
  • 2
    Arrays decay to pointers when passed to a function. Commented Sep 15, 2012 at 6:33
  • You aren't even declaring n. Commented Sep 15, 2012 at 6:34

4 Answers 4

3

No, in this context it's a pointer to a char. Your function declaration is completely equivalent to:

int strlen(char *s)

As you'll see, it's actually impossible to pass an array to a function: a pointer to the first element is what is actually passed.

Thus, since s is actually a pointer and not an array, you're free to modify it as you please.

Sign up to request clarification or add additional context in comments.

11 Comments

Then why is there a restriction on modifying array names, even though char s[] is equivalent to char *s? If I write char s[10], why can't I say s++?
@ben because char s[10] is not decaying to a pointer because it's no a function parameter...?
If it's a local array variable, then you can't modify it.
Everything about arrays in C is somewhat arbitrary. Most other types are first-class -- you can assign them and they copy the entire value. Arrays automatically decay to pointers when used in a value context, but they decided to treat them as names in variable declarations, for consistency with other types.
@ben: there's some stuff about it in cm.bell-labs.com/who/dmr/chist.html. Basically it's because C arrays evolved from a previous construct in which the name of the array actually was a pointer, and the array itself was a separate chunk of memory from the variable that referred to it.
|
3

From the horse's mouth:

6.3.2.1 Lvalues, arrays, and function designators

...
3 Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.

The expression "test" is a string literal, which has type "5-element array of char". When you pass "test" as a parameter of strlen, by the rule above, what actually gets passed is a pointer whose value is the address of the first character in "test".

Which brings us to...

6.7.6.3 Function declarators (including prototypes)

...
7 A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to type’’, where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation. If the keyword static also appears within the [ and ] of the array type derivation, then for each call to the function, the value of the corresponding actual argument shall provide access to the first element of an array with at least as many elements as specified by the size expression.

So in the prototype for strlen, char s[] is equivalent to char *s; s is declared as a pointer to char, not an array of char.

C's treatment of arrays is a bit baroque compared to other languages. That's due in part to the BCPL and B heritage. If you're curious as to why, you can read dmr's The Development of the C Language for some insights.

2 Comments

From the first reference, if in the above said cases "array of type" is converted to "pointer of type" then why is the statement a++; invalid? Where a is declared like int a[10];. Here, we are not using sizeof , _Alignof or & operator. So, shouldn't it be converted to "pointer of type"?
@hatter: The operand of the ++ and -- operators (both prefix and postfix) must be a modifiable lvalue (6.5.2.4/1 and 6.5.3.1/1); however, an array expression is not a modifiable lvalue (6.3.2.1/1). You cannot change the value of a, because there's no storage set aside for a variable a independent of the array elements themselves.
1

No, acctually s is a pointer name. The declaration int strlen(char s[]) is same as int strlen(char *s)

Comments

1

When Char s[]={...} is declared address is attached to s, which never changes (like constant pointer) and anything try to change this property becomes an illegal operation such as s++.

But In function call int strlen(char s[]) , array is passed as pointer.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.