I'm confused about the way C handles strings and char *
vs char[]
.
char name[10] = "asd";
printf("%p\n%p", &name, &name[0]); //0x7ffed617acd
//0x7ffed617acd
If this code gives the same addresses for both arguments, does it mean that the C compiler takes char arrays (strings) as a pointer to the first char in the array and moves in the memory till it gets the null terminator? Why wouldn't the same happen if we changed the char name[]
to char *name
? (I know they differ but what makes C take both in a different way?)
I know that arrays can't be assigned after declaration (unless you used something like strcpy, strcat) which is also confusing. Why wouldn't C take them as any other data type? (Something tells me the compiler has a specific addr for it while you can assign char*
to whatever location in the mem since its a pointer).
I know that char *
have fixed size unlike char[]
which makes char *
not usable for first argument of strcat
.
CodePudding user response:
in C a "string" is an array of type "char" (terminated with \0
).
When you are referring to an array in C, you are using a pointer to the first element. In this case (char *
).
According to the ANSI-C standard the name of an array is a pointer to the first element.
Being able to write name
instead of &name[0]
is syntactical sugar.
In the same way accessing an array element writing name[i]
is analogue to writing *(name i)
.
CodePudding user response:
does it mean that the c compiler takes char arrays (strings) as a pointer to the first char in the array
An array is not a pointer. But an array will implicitly convert to a pointer to first element. Such conversion is called "decaying".
... and moves in the memory till it gets the null terminator???
You can write such loop if you know the pointer is to an element of null terminated string. If you write that loop, then the compiler will produce a program that does such thing.
Why wouldn't the same happen if we changed the char name[] to char *name?
Your premise is faulty. You can iterate an array directly, as well as using a pointer.
If this code gives the same addresses for both arguments, does it mean
The address of an object is the first byte of the object. What this "same address" means is that the first byte of the first element of the array is in the same address as the first byte of the array as a whole.
I know that arrays can't be assigned after declaration (unless you used something like strcpy, strcat) which is also confusing.
Neither strcpy
nor strcat
assign an array. They assign elements of the array which you can also do without calling those functions.
Why wouldn't C take them as any other data type?
This question is unclear. What do you mean by "C taking them"? Why do you think C should take another data type? Which data type do you think it should take?
char name[10] = "asd"; printf("%p\n%p", &name, &name[0]);
The arguments are of type char(*)[10]
and char*
respectively. The %p
format specifier requires that the argument is of type similar to void*
which isn't similar to those arguments. Passing an argument of a type other than required by the format specifier results in undefined behaviour. You should cast other pointer types to void*
when using %p
.