Passing Strings to a Function

Despite teaching the C language, I still find myself at odds with pointers. Specifically, it’s the double pointers that remind me of my mortality. I found myself getting into the double pointer polka recently when I tried to work with an array of strings, passing each one individually to a function. O! The pain!

As it turns out, my frustration was misplaced. Still, I’d like to impart my journey of woe and teach a bit more about double pointers.

My desire is to process a series of strings in a function. Each string is stored in an array, which makes it a pointer-pointer thing. Anyhoo. The first step is to write a smaller version of the program that passes a single string without manipulating that string. To keep things simple, I use array notation:

2021_08_21-Lesson-a.c

#include <stdio.h>

void output(char a[])
{
    int x = 0;

    while( a[x] )
    {
        putchar( a[x]);
        x++;
    }
    putchar('\n');
}

int main()
{
    char string[] = "Hello, world!";

    output(string);

    return(0);
}

Line 17 declares string[] and assigns it text. This string is passed directly to the output() function at Line 19.

The output() function specifies array notation in its argument list. This notation is used throughout the function, which should be easy to understand for all C programmers.

Here is the same code, but using pointers:

2021_08_21-Lesson-b.c

#include <stdio.h>

void output(char *a)
{
    int x = 0;

    while( *(a+x) )
    {
        putchar(*(a+x));
        x++;
    }
    putchar('\n');
}

int main()
{
    char string[] = "Hello, world!";

    output(string);

    return(0);
}

The main() function is the same for both versions of the program; you can pass a pointer to a string or a char array to the function. My focus was on the function — which might have been my first mistake.

The output() function’s argument is a pointer, char *a. In the function, I’ve translated array notation into pointer notation: a[x] is similar to *(a+x), a topic I cover in my books. Otherwise the two versions of the function operate the same and generate identical output.

After these programs worked, my next step is to update the code so that multiple strings are processed from an array. The output() function need not change, so the following update reflects updates in the main() function:

2021_08_21-Lesson-c.c

#include <stdio.h>

void output(char *a)
{
    int x = 0;

    while( *(a+x) )
    {
        putchar(*(a+x));
        x++;
    }
    putchar('\n');
}

int main()
{
    char *string[3] = {
        "Hello, world!",
        "This is a string test",
        "Once upon a time, there was a string"
    };
    int x;

    for( x=0; x<3; x++ )
    {
        output(string[x]);
    }

    return(0);
}

In this code, three strings are declared at Line 17. Technically, what’s declared is an array of char pointers, each of which references a string stored in memory. This note is important to remember, something that I eventually forgot.

A for loop passes each string to the output() function, which uses pointer notation as shown earlier. Everything works; the three strings are output properly.

At this point, I proved my code worked. But my goal is to modify the strings. This update is where I encountered my frustration with pointers. An array of strings *string[] is really **string. This relationship plays out in how a function can access and manipulate characters in the strings. Do things wrong and . . . BOOM!

You might be able to see my problem right away. I can now, and it’s painful to me. Still, in next week’s Lesson, I explore how the manipulation process works in an updated version of the code, and how I screwed up.

Leave a Reply