C Programming Pointers and Strings

Last modified by Microchip on 2023/11/09 09:06

A string may be declared using a pointer just like it was with a char array, but now we use a pointer variable (no square brackets) instead of an array variable. The string may be initialized when it is declared, or it may be assigned later. The string itself will be stored in memory, and the pointer will be given the address of the first character of the string.

Graphic showing string declaration with a pointer

Please note that implementation varies depending on the compiler and architecture used.

When initialized, a pointer to a string points to the first character:

Example

Graphic showing a pointer to a string pointing to the first character

You can then increment or add an offset to the pointer to access subsequent characters.

Pointers may also be used to access characters via an offset:

Example

Graphic showing pointers used to access characters via an offset

Back to Top

Pointer versus Array

Initialization at Declaration

Initializing a character string when it is declared is essentially the same for both a pointer and an array:

Example: Pointer Variable

1 char *str = "PIC";

Example: Array Variable

1 char str[] = "PIC";
2
3 OR
4
5 char str[4] = "PIC";

The NULL character '\0' is automatically appended to strings in both cases (array must be large enough).

Back to Top

Assignment in Code

An entire string may be assigned to a pointer and a character array must be assigned character by character.

Example: Pointer Variable

1 char *str;
2
3 str = "PIC";

Example: Array Variable

1 char str[4];
2
3 str[0] = 'P';
4 str[1] = 'I';
5 str[2] = 'C';
6 str[3] = '\0';

Must explicitly add NULL character '\0' to array.

Back to Top

Comparing Strings

If you want to test a string for equivalence, the natural thing to do is: if (str == "Microchip"). However, a string pointer in C is not even close to a string data type. If we do a comparison like if (str == "Microchip"), the compiler will compare the address contained in the pointer str with the address of the string literal "Microchip" (the literal is stored in program memory and accessed via the PSV on the 16-bit devices). This might work if the compiler is smart enough to recognize that the literal in the comparison is the same one used to initialize str and use the same literal in memory. However, the string in the comparison might be allocated as a separate distinct variable that happens to have the same characters by some compilers. If this happens, the address in str will not match the address of the string literal and the comparison will fail.

The correct way to compare strings is to use the standard library function strcmp() which will compare the strings character by character.

Because strings in C are just arrays of characters (or simply a string of characters stored in sequential memory locations) terminated by a null character, the only way to compare them is to do it character by character.

int strcmp (const char *s1, const char *s2);

C makes up for its lack of a string data type by including numerous string handling functions in its standard library. The strcmp() function is used to compare two strings. It takes two pointers as parameters. Note that they are both declared as const, which means the function cannot change the contents of the strings themselves – though it can change the value of the pointers, which it does in order to move from character to character. This is one of the legitimate uses for the const keyword that we discussed on the #define versus const page. Here, we are not creating a constant, but rather restricting the function from changing the value of the parameters passed to it (the strings pointed to by s1 and s2), even though they are passed by reference.

If the strings are equal, it will return 0 (which unfortunately is interpreted as "FALSE" in Boolean type operations – so you must test the function in an expression to see if it is == 0). If the strings are not equal, it will return a non-zero value.
So in summary, the return values are as follows:

  • <0 if s1 is less than s2
  • 0 if s1 is equal to s2
  • >0 if s1 is greater than s2

The strcmp() prototype is in
C:\Program Files\Microchip\XC16\v1.10\include\string.h

We can use strcmp() in a number of different ways. In this example, we compare the string pointer str with a string literal "Microchip". This works because the string literal is stored in program memory and has an address. When used in this fashion, the address of the string literal is what gets passed to the function. When this code is compiled, the string "Microchip" will exist in two distinct locations – one from where it is initially assigned to str, and a second for its use in the strcmp() function. These two strings are two distinct entities with their own addresses. (The compiler might optimize this so that both instances of the string literal point to the same memory location)
The strcmp() function will compare the two strings character by character. Since they are the same, the function will return 0, which makes the expression in the if statement true.

1 #include <string.h>
2
3 char *str = "Microchip";
4
5 int main(void)
6 {
7     if (0 == strcmp(str, "Microchip"))
8         printf("They match!\n");
9
10    while(1);
11 }

Back to Top