char *a = "hello world";
char a = "hello world";
Both are valid. In first case, programmer is not supposed to modify the contents being pointed to by a as "hello world" is a string literal. In second case, "hello world" is copied to an array a, in the function call space and hence can be modified by the programmer. For printf case, both works the same.
PS: The first argument to printf must be a character pointer and all its characters are printed with format specifiers taken care of separately. So, we do not need %s if we want to just print a string. Avoiding it is actually better for performance reason.