3

I'm reading K&R and have gotten a bit confused in the character pointers section. K&R provides the following as a version of strcpy with pointers:

void strcpy(char *s, char *t) {
    while ( (*s = *t) != '\0') {
        s++;
        t++;
    }
}

How is this different from using a pointer to a single character? Or is C just trusting that I know what I'm doing and both cases use a pointer to a character? It's just that when I have an array of these characters, it's terminated by \0, whereas if it's just a character, the subsequent spots in memory could be anything... is this right?

4
  • 5
    In C, a pointer to a single char is indeed indistinguishable to a pointer to a properly terminated sequence of chars, aka a string. Tough. Commented Apr 24, 2015 at 20:11
  • 1
    s and t above are indeed pointers to a single character. What else would they be? They're not pointers to strings because C doesn't have strings. Yes, if you happen to have a series of characters in memory ending with a 0, we can do certain string-like things with them. Commented Apr 24, 2015 at 20:27
  • both are same. Programmer should identify if it is a character or a string. If you send a char pointer (not a string) as a argument to a string, the program will not work properly. C will identify a string as set of char memory places which ends with '/0' character.. Commented Apr 24, 2015 at 20:28
  • It's just that people like the popular and the popular says 'C' arrays are actually pointers. Well this is actually not true at all as I show. Check my answer for more. Commented Apr 24, 2015 at 20:41

5 Answers 5

4

Differentiating between the two is entirely your responsibility.

In the case of a pointer to a single char, you could be careful enough to have it as a char * const which will not allow you to increment the pointer or otherwise change what it points to and walk off to somewhere and undefined behavior, but you will still be able to modify the value it points to.

C is very low level and very "bare bone" language. You have to be very responsible when you work with pointers. Naturally this applies to char * as well as to any other "array" - if not null terminated, you should by all means pass the length of the array and use that for a guide.

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

Comments

3

Arrays passed to functions as arguments are implicitly converted to pointers to their first elements. So there is no difference whether a pointer points to a single scalar object or to the first object of an array. Pointers do not possess such piece of information.

As for standard string functions that have names started from str then it is supposed that they deal with strings that is with character arrays that contain data terminated by zero.

So in fact you can make a mistake and pass to a string function a pointer that points to a single character object. But in this case the program behaviour will be undefined.

On the other hand if to follow exactly the title of your post then a pointer to character array differs from a pointer to a single character.

For example consider the following declarations

char *pc = "Hello";
char ( *ps )[6] = &"Hello";

As you can see pc and ps where ps is a pointer to a character array have different declarations.:) And you can also see the difference if you dereference the pointers. For example

printf( "%zu\n", sizeof( *pc ) );
printf( "%zu\n", sizeof( *ps ) );

Comments

2

You're basically correct. It's no different to a pointer to a single character. The function does not know the difference between you passing a single character (bad) and passing a string (good). If you happened to pass the address of a single char (that had non-zero value) then the behavior of this function would be undefined. In this type of scenario C is not typesafe.

Comments

1

How is this different from using a pointer to a single character?

The difference is that when you use a pointer to single character then you should not increment that pointer but only once with a condition that you must not dereference it. In case of pointer to single character of a string, pointer can be incremented till one past the last element.

6.5.6 Additive operators:

If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; [...]

In fact, pointer to a single element behave as a pointer to an array of one element.

char c = 'A';
char *p = &c;  // Pointer to char

is similar to (except c is an array in this case)

char c[1] = {'A'};
char *p = c;   // Pointer to the first element of array c.

Or is C just trusting that I know what I'm doing and both cases use a pointer to a character?

Yes. Its your responsibility that you should take care that pointer should point to an element of an array/string object or one past to it provided no dereferencing in latter case.

4 Comments

Hey! You're absolutely permitted to increment a pointer to a single char. Once. And you can't dereference if afterwards. But you're allowed to increment!
@EOF; Edited that. Late edit. Suffering from "slow internet connection"!
Ehh, I was mostly joking.
I always appreciate a comment before/after downvote.
-1

Pointer to array of unknown bound of characters should be used instead. This is what everyone should do but AFAIK no-one does:

void str_cpy(char (*s)[], char (*t)[]) {{

    char *str_cpy[2] = { *s, *t }, *s = *str_cpy, *t = str_cpy[1];

{
    void str_cpy(char (*s)[], char (*t)[]);


    while ( (*s = *t) != '\0') s++, t++;
}
}}

Note that incrementing pointer to array of unknown size is forbidden and also not desired here so change in function code is required (as I did above).

You can then pass strings like this:

char str[20], str1[20];

strcpy(&str, &str1);

This way you can diagnose accidentally pass pointer to a single character:

char singleChar = 'H';

strcpy(&singleChar, &singleChar); //warning

Life example.

The problem is, however, that using a char * variable is the most practical way to access each individual char from any "array of char" because you can directly increment such a variable to make it refer the next array element (which you can't do using a pointer to array - incrementing such will make it refer to the next array in memory instead of the next char of the array pointed). Additionally the syntax of using a pointer to array is more complex.

4 Comments

Every good compiler made today will optimize your code into the exact same assembly as the code given. What do you think your complication will possibly accomplish? It's not like C checks (or even knows) array boundaries.
Nope it does. This way you won't be able to pass pointer to single character as well as pointer to fixed-size arrays thus preventing you from UB or reminding you that the static information about array-size is lost. This is the best implementation yet so please get you things right.
But I know what world you're living it - the limited one where everything you know is popular. Well as you see popular things are not the only one that exists. If you don't believe me this is a valid 'C' code check the language documentation or try compiling it. For the late - I've provided links with the examples on working online one.
I never said your code wasn't valid C--it's perfectly valid. It's just overly complicated and not useful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.