简体   繁体   中英

c - why does it make sense that indexing a character pointer is an int?

char *a = "apple";
printf("%s\n", a);  // fine
printf("%s\n", a[1]);  // compiler complains an int is being passed

Why does indexing a string pointer give me an int? I was expecting it to just print the string starting at position one (which is actually what happens when i use &a[1] instead). why do i need to get the address?

That's just how the [] operator is defined - a[1] , when a is a char * , fetches the next char after the one pointed to by a ( a[0] is the first one).

The second part of the puzzle is that char values are always promoted to int (or rarely, unsigned int ) when passed as part of a function's variable-length argument list.

a is equivalent to &a[0] , and it prints from the first character - so it makes sense that &a[1] would print starting from the second character. You can also just use a + 1 - that's completely equivalent.

If you use the %c conversion specifier, which prints a single character, you can use a[1] to print just the second character:

printf("%c\n", a[1]);

The expression a[1] yields a single char , and in expressions that is widened to an int .
You can print a char with %c :

char *a = "apple";
printf("%c\n", a[1]);   // prints 'p'

You can achieve what you want by using a+1 , like

printf("%s\n", a+1);    // prints 'pple'

An other way to explain this:

char *a2 = a+1;   // a2 points to 'pple'   
a[1] ≡ *(a+1)  ≡ *a2 

%s expects a char* pointer. Char alone is interpreted as an integer. Moreover, a[1] gives you the second element, not the first!

Characters (ie the kind of thing that a[1] evaluates to) are integers, but the "%s" formatter for printf() expects a pointer. Note that the fact that this error was detected at all is an extended feature offered by some compilers - it's not part of Standard C. Other compilers would simply fail at run-time, probably with a core dump.

char *a = "bla"

a : is a char* , and you should use %s for printf(...) ;

a[1] is equivalent to *(a+1) , then a[1] is a char , and you should use %c for printf(...) ;

&a[1] is equivalent to &(*(a+1)) , then &a[1] is a char* , and you should use %s for printf(...) ;

This is more like a pointer question. To better understand how pointers work, think this way:

char *j;

j is a char*
*j is a char , and equivalent with j[0]
*(j+1) is a char , and equivalent with j[1]
&(*j) is a char* , and equivalent with &j[0] , equivalent with j
&j is a char**

Another example:

char j**

j is a char**
*j is a char*
**j is a char , and equivalent with *(*(j+0)+0) , and equivalent with j[0][0]
&j is a char***

and so on...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM