问题
I'm wondering why printf()
when provided an array and no formatting options, successfully prints character arrays but while using integer arrays the compiler throws a warning and a garbage value is printed.
Here's my code:
#include <stdio.h>
int main()
{
char cr[3] = { 'a', 'b' };
int ar[3] = { 1, 2 };
printf("character array output using printf() : ");
printf(cr);
printf("\n\nInteger array output using printf() : ");
printf(ar);
printf("\n");
return 0;
}
and here's my output:
../main.c: In function ‘main’:
../main.c:12:4: warning: passing argument 1 of ‘printf’ from incompatible pointer type [enabled by default]
printf(ar);
^
In file included from ../main.c:1:0:
/usr/include/stdio.h:362:12: note: expected ‘const char * restrict’ but argument is of type ‘int *’
extern int printf (const char *__restrict __format, ...);
^
Finished building: ../main.c
回答1:
To answer what exactly happens I want firstly show what your array initializations do. Your array initializer lists are incomplete, there are missing elements as the size is greater than the list. That will result in zero initialization for the missing elements.
1. char cr[3]
array:
char cr[3] = { 'a', 'b' };
will lead to:
character represantation == decimal representation
-+----+----+----+----+----+----+- -+----+----+----+----+----+----+-
| | a | b | \0 | | | | | 97 | 98 | 0 | | |
-+----+----+----+----+----+----+- -+----+----+----+----+----+----+-
^~~~ ^~~~
| char | char
cr cr
The printf()
function is defined as: int printf( const char* format, ... );.
That means it takes a char
pointer and doesn't change the elements that are pointed to.
If you now pass the cr
array to the printf()
function the array name will decay to a pointer. The printf()
function interprets the format
parameter as null terminated character array which is called a C-string. Your cr
array is a null terminated C-string as it consists of { 'a', 'b', '\0' }
. That means the printf()
function can successfully print the string "ab"
to stdout.
2. int ar[3]
array:
int ar[3] = { 1, 2 };
will lead to:
-+----+----+----+----+----+----+-
| | 1 | 2 | 0 | | |
-+----+----+----+----+----+----+-
^~~~
| int
ar
For now you see no great difference (just type and content) in contrast to the 1st case. But now you're passing the ar
array to the printf()
function. The array name will decay to an int*
and is implicitly casted to const char*
(this will bring you the compiler warning you've got). If the printf()
function now dereferences the memory it looks like the following (assuming that an int
consists of 4 bytes and your machine uses little endian memory representation):
-+----+----+----+----+----+----+----+----+----+----+----+----+----+-
| | 1 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
-+----+----+----+----+----+----+----+----+----+----+----+----+----+-
^~~~~~~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~
| int int int
^~~~ ^~~~ ^~~~ ^~~~ ^~~~ ^~~~ ^~~~ ^~~~ ^~~~ ^~~~ ^~~~ ^~~~
| char char char char char char char char char char char char
ar
Instead of getting a string like "12"
printed it will consume the both left characters that are the decimal value 1 and 0 (null terminator), see diagram above. The remaining decimal values after 1 and 0 are not recognized as they are after the null terminator. Assuming your machine uses the ASCII table the decimal 1 is not a printable character leading to a garbage value printed.
Proof of concept:
To prove what I write before you can use the following function which takes the same 1st argument as printf()
, namely const char*
:
void printhexchars(const char* str)
{
while(*str)
{
printf("%03d ", *(str++));
}
/* print last character after while loop: '\0' */
printf("%03d ", *str);
}
This functions prints the integer representation of a null terminated C-string. See example with your arrays char cr[3] and int ar[3] on ideone.com. Of course passing the integer array to the function above will generate the same compiler warning as you already get before.
Output:
character array output using printf() : 097 098 000 Integer array output using printf() : 001 000
As you can see you get 097 098 000
which is "ab"
for your character array.
Your integer array leads to 001 000
which leads to the non printable character with a decimal value of 1.
回答2:
The C language standard declares printf as follows:
int printf(const char *format, ...);
It returns an integer and takes a first parameter of a pointer to a constant character and an arbitrary number of subsequent parameters of arbitrary type.
回答3:
Because the both array as display as character and the chars are keep as ascii code and integers are kept as integer (thanks cpt. obvious). Printf interprets the input as code ascii so in case of integers you have control character which are not very understandable.
来源:https://stackoverflow.com/questions/46110952/printf-no-format-string-printing-character-and-integer-arrays-garbage