Reputation: 9345
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?
Upvotes: 3
Views: 1615
Reputation: 3744
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.
Upvotes: -1
Reputation: 106012
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.
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.
Upvotes: 1
Reputation: 310980
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 ) );
Upvotes: 3
Reputation: 49289
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.
Upvotes: 4
Reputation: 78653
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.
Upvotes: 2