1

Let's say I have 2 functions:

void function1(int *ptr) {
     printf("%d", *ptr);
}

and

void function2(char *str) {
     printf("%s", str);
}

Why does function2 work, when there is no deference operator before str? In str there is only the address where it points to not the value as I thought.

MortalMan
  • 2,582
  • 3
  • 23
  • 47
  • As seen [here](http://en.cppreference.com/w/c/io/fprintf), it expects a `char *`. Dereferencing it gives you just a char anyway. – chris Jul 25 '12 at 15:45

5 Answers5

8

Why does function2 work, when there is no deference operator before str

Because %s, as defined by the standard, expects a char *, i.e. an address.

7.21.6.1

If no l length modifier is present, the argument shall be a pointer to the initial element of an array of character type. Characters from the array are written up to (but not including) the terminating null character. If the precision is specified, no more than that many bytes are written. If the precision is not specified or is greater than the size of the array, the array shall contain a null character.

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
cnicutar
  • 178,505
  • 25
  • 365
  • 392
  • Technically correct, but I'm not sure this helps the OP's understanding much. If I ask "Why do we have to pay tax?", I probably want to hear "It pays for education, police, roads etc.", not "Because the government makes us". – j_random_hacker Jul 25 '12 at 15:52
  • @cnicutar I think the following two sentences from that clause should be included for completeness. (The last one is the one I find important here.) – Daniel Fischer Jul 25 '12 at 15:58
  • @DanielFischer Please feel free to edit the answer as you see fit :-) – cnicutar Jul 25 '12 at 15:58
6

Because a pointer to a char is special when using printf. Instead of treating it as a pointer to a single char, it treats it as a pointer to the first element in a NUL delimited array of chars, printing a string instead of a just a pointer.

Richard J. Ross III
  • 55,009
  • 24
  • 135
  • 201
1

The way you refer to a string in C is by the address of its first character. Functions that read strings will read the byte at this address, do something with it (e.g. print it, in the case of printf()), and then move to the next character. This continues until a zero byte is found, indicating the end of the string.

This is basically a way of saving memory. Other basic data types, like int, are small enough that their values can be copied cheaply, so there is no need to refer to the address of the object.

j_random_hacker
  • 50,331
  • 10
  • 105
  • 169
1

Because when we write

char *s="hello";

s by default takes the address of first address of first element i.e address of 'h' and %s in the printf prints the whole string instead of element @ first location. due to which it never requires deference operator. It might have confused the C compiler whether to print the first element or all the elements.

ChrisF
  • 134,786
  • 31
  • 255
  • 325
1

The reason for this is because the printf() function has been written to understand different types of arguments passed to it. The format specifier in the string tells printf() what to expect each argument to be. Then the documentation tells you what to pass to it.

ie. basically it works because printf() follows a defined specification, and you're following it.

So in your first example, you use the %d format. printf() takes this to mean the argument should be an integer value. Not a pointer to an integer, but an integer. Which is why this works:

void function1(int *ptr) {
     printf("%d", *ptr);
}

and this doesn't:

void function1(int *ptr) {
     printf("%d", ptr);
}

Your second example is a string and there is some possibility of confusion here as strings in C are not really a direct data types (as such). They are a pointer to a character which is followed by other characters and then terminates with a NULL \0.

void function2(char *str) {
     printf("%s", str);
}

Now, if strings were a data type in C, then you would probably pass them in the same way you do other values (this is purely hypothetical):

void function2(string str) {
     printf("%s", str);
}

So in summary:

%d -> int
%s -> char *
ChrisH
  • 904
  • 6
  • 13