void getname(char name1[0])
formally says you're going to pass a character array of zero size (side note: zero size arrays are not allowed in standard C but compilers sometimes allow them).
What it really says is you're going to pass a character pointer, a char *
. The size is ignored. It's equivalent to the less confusing: void getname(char *name1)
.
In addition, since you're not going to alter the string inside function you can declare it const char *
and be warned if you try to alter it.
#include <stdio.h>
void getname(const char *name1){
printf("Name1 is %s",name1);
return;
}
int main() {
char name[100] = "foo";
getname(name);
}
getname(name1[0]);
gives you garbage because instead of passing in the pointer to the start of the string, you're passing in the first character of the string. If the string is "Yarrow Hock" you're trying to pass in Y
which is really the number 89. C will then try to read what's at memory address 89 which is probably garbage.
You can see this if you print the memory address of name1
using %p
.
void getname(const char *name1){
printf("Name1 points to %p\n",name1);
printf("Name1 is %s\n",name1);
return;
}
You should get a warning like:
incompatible integer to pointer conversion passing 'char' to parameter of
type 'const char *'; take the address with & [-Wint-conversion]
Which leads us to a very important thing: compiler warnings. They are extremely important and by default they are off. Turning them on will save you hours of head scratching. There are a bewildering array of possible warnings and they're slightly different from compiler to compiler. Here's what I use with clang
.
-Wall -Wshadow -Wwrite-strings -Wextra -Wconversion -std=c11 -pedantic
You can read what each of these mean in Diagnostic flags in Clang. And yes, "-Wall" does not mean "all warnings".
A good code editor, I recommend Atom, will also give you warnings as you edit.
getname(&name1[0]);
works because it is equivalent to getname(name1 + 0)
which is equivalent to getname(name1)
. name1[0]
is the first character of the string. &
gets its address, which is the start of the string just like name1
itself. printf
then prints characters until it hits a null byte.
You can see this by trying getname(&name1[1])
, or more directly with pointer arithmetic as getname(name1 + 1)
. This will pass in the address of the second character in name1. If name1 = "Yarrow Hock"
it will print arrow Hock
. This is a valid technique for skipping prefixes without altering the string.