c - why print out a char pointer yield the entire array instead of the memory addr of the pointer? -
int aryint[4] = {1,2,3,4}; char *ptr = "1234"; char ch ='a'; char *chptr = &ch; //chptr = 3509449623 (mem addr) printf("chptr = %u, chptr); //aryint = 3509449648 (mem addr) printf("aryint = %u ", aryint); //ptr = 1234 printf("ptr = %s, ptr); why printing out char point “ptr” return entire array of char (the whole string), , printing out char point “chptr” return mem addr of “chptr”?
if because “ptr” pointing array, why printing out array “aryint” return mem addr of aryint (not entire array)? printing out entire array applies string constant? or because of %s?
but when tried replacing %s %u on printf() of ptr, constant (4197008) equivalent entire array/string (1234), , not mem address:
//ptr u = 4197008 (a constant not mem addr), ptr s = 1234, printf("ptr u = %u, ptr s = %s”, ptr, ptr) however, when attempt print out char array “str”, mem address when applied %u on “str” (not entire array in ptr). got entire array printed again when %s applied on “str”, , not mem address in chptr , aryint previously.
char str[5] = "1234"; //str u = 3509449696 (mem addr), str s = 1234 printf("str u = %u, str s =%s”, str, str ); this seems bit strange me. there other weird phenomena should aware of when coding in c? newbie.
any appreciated!
printf expects string called format string containing format specifiers. these parsed printf (and denoted leading '%'). whenever 1 encountered, printf gets next argument number of arguments passed , "applies" meaning of format specifier argument.
example:
printf("%d", 1); in uppper example, format specifier "%d" encountered, has own meaning: expects argument of type int. 1 int, program well-defined , fine.
why printing out char point “ptr” return entire array of char (the whole string) [...]
because that's how "%s" format specifier works. expects char* , prints chars until null byte ('\0') found.
[...] , printing out char point “chptr” return mem addr of “chptr”?
it's undefined behavior because format specifier (expecting unsigned int) , argument type (char*) not match , there's no implicit conversion between both. it's undefined standard.
beware: that's standard says. remember standard describes abstract machine. concrete machine behave within scope of said abstract machine while abstract machine defines set of possible outcomes "undefined," concrete machine manifests real behavior. real behavior depends on stuff beneath standard (os on hosted implementation , hardware) that's happens real in printf("chptr = %u, chptr); on common machines:
- the leading part
"chptr = "printed. - the percentage sign encountered,
"%u"parsed. %umeansunsigned int,unsigned intpopped off argument list.printfdoesn't know exact types of arguments because uses variable argument list. type-unsafe.sizeof(unsigned int)bytes fetched, parsedunsigned int, , printed out. whethersizeof(char*) == sizeof(int)implementation, may happen many/too few bytes popped off , crashes whole program. it's undefined behavior, after all.
in end, keep in mind use appropriate format specifier, not use printf(user_defined_string) or puts(user_defined_string), , read standard find out possible instances of undefined behavior.
Comments
Post a Comment