0

I am looking to learn C and having a really hard time grasping the concepts of string pointers (and just pointers in general).

I have the following program:

#include<stdio.h>
#include<string.h>

int main()  
{   

    // char test[6] = "hello";
    char *test = "hello"; // test is a pointer to 'h'

    int size_of_test_pt = sizeof(test); // this is the size of a pointer? which is 8 bytes.
    int size_of_test = sizeof(*test); // this is the size of h, which is 1.

    printf("\nSize of pointer to test: %d\n", size_of_test_pt);  // prints 8
    printf("\nSize of test: %d\n", size_of_test);   // prints 1

    printf("\nPrint %s\n", test); // why does this print 'hello', I thought test was a pointer?
    printf("\nPrint %c\n", *test); // this is printing the first character of hello, I thought this would print hello.
    printf("\nPrint %i\n", *test); // this prints 104...is this ASCII for h

    return 0;
}

Everything makes sense until the last 3 print statements. If test is a pointer variable. Why does printf print out the word "hello" rather than an address?

For the printf("\nPrint %c\n", *test) call is it the right understanding that I am dereferencing test, which is an address and accessing the first element, then printing it to the screen?

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • 2
    *"If test is a pointer variable. Why does printf print out the word "hello" rather than an address?"* - because by using `%s` specifier you tell `printf` that it should take the pointer and print the string it points to. – Eugene Sh. Jan 28 '22 at 17:56
  • The `%s` needs a pointer to dereference, which you give it. The `%c` needs one `char`, which you give it (automatically promoted to `int`), and the `%d` needs `int`, which is what the `char` is promoted to. – Weather Vane Jan 28 '22 at 17:59
  • 1
    About *"the size of h, which is 1"*. It is the `sizeof(char)` which is 1, not `'h'`. The `sizeof('h')` is the same as `sizeof(int)`. – Weather Vane Jan 28 '22 at 18:02
  • Thanks all for the comments. Not sure if I follow the last point. Why is sizeof('h') not equal to sizeof(char) when h is a char? – Dan the Man Jan 29 '22 at 04:33

3 Answers3

2

The conversion specifier %s is designed to output strings and it expects as an argument a pointer expression of the type char * or const char * that points to the first character of a string that to be outputted.

In this case the function outputs all characters starting from the address pointed to by the supplied pointer until the terminating zero character '\0' is encountered.

If you want to output the value of such a pointer you need to write

printf("\nPrint %p\n", ( void * )test);

The conversion specifier %c is designed to output a single object of the type char.

Pay attention to that the pointer test points to the first character of the string literal "hello". So dereferencing the pointer you will get the first character of the string literal.

Here is a demonstration program.

#include <stdio.h>

int main( void )
{
    char *test = "hello";

    for ( ; *test != '\0'; ++test )
    {
        printf( "%c ", *test );
    }

    putchar( '\n' );
}

The program output is

h e l l o

The string literal is stored in memory as a character array containing the following elements

{ 'h', 'e', 'l', 'l', 'o', '\0' }
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

If test is a pointer variable. Why does printf print out the word "hello" rather than an address?

In short, it's because the %s expects its parameter to be of type char *.

For the printf("\nPrint %c\n", *test) call is it the right understanding that I am dereferencing test, which is an address and accessing the first element, then printing it to the screen?

Yes. The %c format specifier expects its parameter to be a char, and that's exactly what you get when you dereference a pointer to char. Furthermore, it knows to print that value as a character. In the following line, the %i parameter expects value of type int, and since char is a kind of int, it accepts that and prints the numeric value of the character (h) that you provided.

Caleb
  • 124,013
  • 19
  • 183
  • 272
0

In C a "string" is a sequence of characters, e.g. h, e, l, l, o. To indicate that the sequence is ending, the special value 0 is appended to the sequence.

If there were no such things as pointers, passing a string to a function would involve copying the entire sequence of characters. This is normally not practical, so instead we just pass on a reference (i.e. a pointer) telling where to find the first character of the string.

This is so commonly used that the pointer itself is sometimes referred to as a string even though it is really a pointer to a string. The string itself is the sequence of characters.

Think of a pointer like a bibliographic reference identifying a particular book. Including such a reference in a text is much more practical than inserting a copy of the entire book.

nielsen
  • 5,641
  • 10
  • 27