Quote:
|
Originally Posted by aznluvsmc
If both are essentially equivalent.
|
They are only equivalent
in some contexts.
To understand what I mean with the underlined bit, consider the "strcpy(strings2[3], "Hello");" from my previous post.
The line "strcpy(strings2[3], "Hello");" actually passes two pointers to strcpy. Now, what does strcpy() do?
Two (notional) implementations are;
char *strcpy(char *x, const char *y)
{
char *temp = x;
while (*y)
{
*x = *y;
++x;
++y;
}
return temp;
} or
char *strcpy(char *x, const char *y)
{
size_t index = 0;
while (y[index])
{
x[index] = y[index];
++index;
}
return x;
} Apart from any errors I've inserted in the process of typing, these two versions given the same end result. However, the first version takes the pointers given, manipulates the characters being pointed to, and increments the pointers. In this way, the first version implicitly assumes that the pointers correspond to arrays. The second version explicitly treats the arguments as if they are arrays.
A hybrid version (which is also equivalent) is;
char *strcpy(char *x, const char *y)
{
size_t index = 0;
while (*(y + index))
{
*(x + index) = (y + index);
++index;
}
return x;
}
Quote:
|
Originally Posted by aznluvsmc
Isn't there still a limitation on strings2[5][21] where each one dimensional array should only be 20 characters long since the max element is 21?
|
That is a side effect of declaring strings2 as a two-dimensional array as you have. The basic principle is that an n-dimensional array is an array of (n-1)-dimensional arrays. The so-called equivalence of arrays and pointers means that the
name of an array can be used in some contexts where a pointer is expected, and that pointer notation can be used to access elements of an array. An equivalent (if backward) statement of this is that a pointer can often be treated as if it is an array.
strings2[i] is, according to your declaration, an array of char. "Hello" is also a (const) array of char. strcpy() accepts a pointer to char as first argument, and a const pointer to char as second argument. When you use strings2[i] in code after the declaration (eg in my previous example, a call to strcpy) those arrays may be implicitly manipulated as if they are pointers.
Quote:
|
Originally Posted by aznluvsmc
However *strings1[5] imposes no limitation on the length of the string since it's a point to another memory location.
|
The declaration of string1 does not even require that the elements of string1 are strings at all. A pointer is allowed to point at
anything. There is nothing preventing strings1[i] from pointing at a single char (which may not even be part of a string), and nothing preventing it pointing at the first element of a string of arbitrary size.
Quote:
|
Originally Posted by aznluvsmc
Also is the following code correct?
int main(void)
{
char *strings1[5];
char strings2[5][21];
strings1[0] = "Hello"; //this will assign the beginning address of the Hello string to the first element?
strings2[0] = "Hello"; //invalid because strings2[0] is an array?
}
|
That depends on what you mean by "correct". The first assignment is valid but also dubious as "Hello" is actually a const string (which is why some compilers will issue a warning in this case). The second assignment will not compile, as the compiler has enough information to know strings2[0] is an array, and arrays cannot be reassigned.
Things get more interesting if you subsequently try to manipulate strings1[0], as "Hello" is implicitly const (i.e. it should not be modified).
As an exercise, try to explain why this code yields undefined behaviour;
int main()
{
char *strings1[5];
strings1[0] = "Hello";
strcpy(strings1, "Junk");
}