How do we get the whole string by pointer in C?

Viewed 3192

I'm new to the C language and I'm getting aquanted with pointers. So, I don't get how we get the WHOLE string by pointer. If the pointer contains the address of just the first character in the string, how does it return the whole string?

Let's say we have something like this char *s = "Test";

And because it's just an array of chars it lies somewhere in memory like this:

The string: T e s t \0

The addresses: 100 101 102 103 104

So, *s would hold 100 (the address of the first character T), if I get it right.

Then why when we do printf(s); do we get the whole string Test in our output?

Does it scan addresses until it meets \0, or does it do something else?

3 Answers

How do we get the whole string by pointer

Yes, OP does well understand in comment that to print the string contents, the output starts at s[0] and continues until s[i] is zero. The last element of the string, the null character is not printed.


Note: printf(s) is bad code as printf() expects the first argument to not only be a pointer to a string, but will interpret as a format. If a '%' occurs, following characters will be interpreted as a specifier @M.M. Instead:

printf("%s", s);
// or
fputs(s, stdout);

  • Impact

Functions like strlen(), strcpy(), strcat() also spend a fair amount of time walking down the length of a string to determine its length. For long strings, this can take considerable time.

This tedious running the length of the string can have severe impacts. Consider s points to a string of length n.

for (i=0; i<strlen(s); i++) {
  s[i] = 'x';
}

versus

for (i=0; s[i] != '\0'; i++) {
  s[i] = 'x';
}

The first code snippet compilation may not see that the length of the string does not change (as the string is changed) per iteration and then call strlen(n) n times, each call taking n operations or total O(n*n) time. The 2nd code will only take order of n operations O(n) time.

Efficient C code recognizes this and avoids repeated length calculations.

There is no other way just to go through the whole string until zero is reached:

size_t strlen(const char *str)
{
    size_t len = 0;
    while(*str++)
    {
        len++;
    }
    return len;
}

or

size_t strlen(const char *str)
{
    const char *start = str;
    while(*str++);
    return str - start;
}

char *strcpy(char *dest, const char *src)
{
    char *saveddest = dest;

    while(*src)
    {
        *dest++ = *src++;
    }
    *dest = 0;
    return saveddest;
}

void puts(const char *s)
{
    char c;
    while((c = *s++))
        putc(c);
}

Note that a string is array of characters and the name of the array corresponds to the pointer referencing the address of the first element.

so when you do printf("%s",s) this means that you are passing the pointer of the very first element of the char array to the printf function.

The printf function would traverse through the array starting from the address passed until it finds '\0'

#include<stdio.h>
int main(){
  char *s= "abcdef ghij";
  char *s2;
  s2 = &s[3];
  printf("%s",s2);
  return 0;
}

Notice how I passed the pointer referencing the 4 element of the array to the printf function. And here is the output.

Output:

def ghij

Related