Basic String Pointer Syntax

A character string is a type of array, each element containing a specific character and terminating with the character. The code

char name[] = Marc";

requires 5 bytes of memory, since a single character in C requires 1 byte.

In Chapter 9, “Working with Pointers,” you saw that an array's name can also act as a pointer to that array's address. The following code works fine, demonstrating two different uses of the same name array (Figure 11.1):

char name[] = "Marc";
printf ("String: %s 
Pointer: %p",
name, name);

Figure 11.1. Character arrays can be printed as strings or as pointers.


The name example adds little benefit to your C programs; however, in a multidimensional character array, using pointers can save lots of space. Take, for example, this code:

char name[2][9] = {
"Marc",
"Liyanage"
};

The name array will require 18 bytes of memory (Figure 11.2), as each subarray (Marc and Liyanage) must be of the same length. By using pointers, you can make ragged arrays: an array of character pointers whose values are strings of varying length. The syntax for rewriting name as a character pointer array is

char *name[2] = {"Marc", "Liyanage"};

Figure 11.2. A multidimensional character array must have subarrays of equal length, possibly requiring blocks of memory to store extra values.


In essence, name is now an array consisting of two character pointers. Each pointer contains the address of a string stored in memory (Figure 11.3).

Figure 11.3. By using character pointers, you can create ragged arrays that use memory more efficiently.


In this first example, you'll use C preprocessor directives to help create a multidimensional character array and an array of character pointers. Although this example won't do anything, we will build on in the next example, which will reveal the memory difference between the two.

To work with string pointers

1.
Create a new file or project in your text editor or IDE.

2.
Type the standard beginning lines of code (Script 11.1):

/* ragged.c - Script 11.1 */
#include <stdio.h>

Script 11.1. Using C preprocessor directives to minimize typing, this program defines two arrays that store the same values in different ways. The memory requirements of each variable are then printed.


3.
Define a constant macro:

#define CHAPTER0 "Introduction"

The arrays we are building in this example will store the titles of the first five chapters of this book, including the introduction. Rather than having to type each of these twice (once for each array), we will use directives.

4.
Define the other chapters:

#define CHAPTER1 "Getting Started
 with C"
#define CHAPTER2 "Introduction to
 Data Types"
#define CHAPTER3 "Working with
 Numbers"

#define CHAPTER4 "Control Structures"

The double quotation marks are required around each title (they are part of the definition itself), but you should not conclude each directive with semicolons, since they're not C code.

Feel free to type the rest of the chapters in from the table of contents if you aren't satisfied with just the five!

5.
Begin the main function:

int main (void) {

6.
Define a multidimensional character array:

char chapters[5][27] = {CHAPTER0,
 CHAPTER1, CHAPTER2, CHAPTER3,
 CHAPTER4};

This is a multidimensional array of five elements, each element containing a string 27 characters long. That number comes from the number of characters in the longest chapter title, plus one for the end-of-string character.

The proper syntax for creating this array will be in place after the C preprocessor does its thing. The C code will then look like this:

char chapters[5][27] = {
 "Introduction", "Getting Started
 with C", "Introduction to Data
 Types", "Working with Numbers",
 "Control Structures" };

7.
Define an array of character pointers:

char *chapters_ptr[5] = {CHAPTER0,
 CHAPTER1, CHAPTER2, CHAPTER3,
 CHAPTER4};

An array of character pointers is defined using different syntax. The number of elements is still defined (5), but each element's value is more flexibly set.

8.
Print the memory usage of both variables:

printf ("The chapters array uses %zu
 bytes of memory.
",
 sizeof(chapters));
printf ("The chapters_ptr array uses
 %zu bytes of memory.
",
 sizeof(chapters_ptr));

The sizeof() function (or operator) is used to print the memory usage of the two different arrays. Each print statement uses the %zu signifier, corresponding to the type of value returned by sizeof() (you'll learn more about this in the next section).

9.
Complete the main function:

   getchar();
   return 0;
}

10.
Save the file as ragged.c, compile, and debug as necessary.

11.
Run the application (Figure 11.4).

Figure 11.4. Two methods for storing several strings are used and their respective memory requirements are indicated. In the next example, however, you'll see why the second memory listing isn't quite accurate.


✓ Tips

  • As Figure 11.4 shows, the chapters variable requires 135 bytes of memory. This number is equal to 5 (the number of array elements) times 27 (the number of characters in each array). By definition, a single character requires 1 byte of memory.

  • In addition to having the potential for unnecessary memory usage, regular arrays are limited to a fixed length. On the other hand, pointer character arrays can adapt to longer strings during the running of the application.

  • The memory usage of the chapters_ptr variable indicated in Figure 11.4 is deceptive. That's not the total usage for the values the pointers refer to, but rather the memory usage of the pointers themselves (4 bytes each times 5 elements). Remember that pointers require some space in memory along with the memory required for the values to which the pointers point.


..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset