Explain String Literal Operations Using Pointers in C Programming

«
»
This Tutorial Explains Different Operations Performed on String Literals Using Pointers in C Programming

A string literal is a sequence of characters terminated by null byte ‘0’. For example,

/* strlit_op.c -- program shows operations on string literals */
#include <stdio.h>
#define NAME "What is your name?"
 
int main(void)
{
    char name[25] = "xyz";
    char * const p2name = "abc";
 
    "abc" += 1;
    "abc" + 1;
    "abc"[0];
    "abc"[1];
    "abc"[10];
    *("abc" + 2);
    *"abc";
 
    return 0;
}

If you compile the above program, compiler saves copy of #define sting some where in the memory and set a pointer to it. Compiler also terminates the string with null terminator. What about name character array? It’s a pointer constant. And p2name? It’s also a pointer constant. Let’s try to figure out how expressions in above program evaluate to,

advertisement
    "abc" += 1;

It seems as if we add 1 to string literal “abc” and assigns it the result. What do you think, if you can figure it out. This statement is an error. Because value of string literal is a pointer constant. Like, for ex., exp.,

    5 += 5; /* 5 is constant */

can’t be evaluated. Therefore, statement

    "abc" += 1;

is invalid. Consider the following statement,

    "abc" + 1;

Again we are trying to add 1 to the string literal “abc”. Sure, you can, this time, easily unravel this. Since, string literal “abc” is a pointer constant pointing to first character ‘a’. Type of “abc” is a pointer to char. Therefore, when you add 1 to “abc”, 1 is adjusted to type char * and added to pointer constant. This moves pointer to character ‘b’.

advertisement

Take another exp.,

    "abc"[0];

As we know that array name is a pointer constant pointing to first element of the array. Therefore, exp. “abc”[0] can be rewritten as

    *("abc" + 0);

or even as

    *"abc";

which results first character ‘a’ in the string “abc”. Let’s explore exp.

advertisement
    "abc"[10];

Let’s take an analogy to evaluate the above exp.,

    int white[5]; /* white is an array of 5 integers */

What will happen if you attempt to access

    white[10];

Surely, subscript value 10 takes you off the end of the array white. Hence, an undefined result. Similarly, in exp.,

    "abc"[10];

you go out of bounds and therefore undefined result.

/* strlit_op.c -- program shows operations on string literals */
#include <stdio.h>
 
#define NAME "What is your name?"
 
int main(void)
{
    char name[25] = "xyz";
    char * const p2name = "abc";
 
    //"abc" += 1;
    printf("Result of \"abc\" + 1 is %c\n", "abc" + 1);
    printf("Result of *(\"abc\" + 1) is %c\n", *("abc" + 1));
    printf("Result of \"abc\"[0] is %c\n", "abc"[0]);
    printf("Result of \"abc\"[1] is %c\n", "abc"[1]);
    printf("Result of \"abc\"[10] is %c\n", "abc"[10]);
    printf("Result of *(\"abc\" + 2) is %c\n", *("abc" + 2));
    printf("Result of *\"abc\" is %c\n", *"abc");
 
    return 0;
}
 
Output of the above program is as follows,
 
<pre lang="C" cssfile="hk1_style">
Result of "abc" + 1 is
Result of *("abc" + 1) is b
Result of "abc"[0] is a
Result of "abc"[1] is b
Result of "abc"[10] is
Result of *("abc" + 2) is c
Result of *"abc" is a

Let’s see an application of string literal in a C program that converts an unsigned integer into equivalent hexadecimal representation,

/*
 * strlit_app.c -- program converts unsigned values into hexadecimal 
 * number
 */
#include <stdio.h>
 
#define MINUS1 4294967295 /* unsigned representation of -1 */
 
/* uint_to_hex() is a recursive function */
void uint_to_hex(unsigned);
 
int main(void)
{
    unsigned value;
 
    puts("\n**Program converts Unsigned int to Hexadecimal No.**\n");
    printf("User, enter an unsigned integer value or -1 to quit: ");
    while (scanf("%u", &value) == 1 && value != MINUS1) {
        /* call to uint_to_hex() */
        uint_to_hex(value);
        puts("");
        printf("more conversions, enter unsigned integer or -1 to quit:");
    }
    puts("Thank You!");
    return 0;
}
 
void uint_to_hex(unsigned value)
{
    unsigned quotient;
 
    quotient = value / 16;
    if (quotient != 0)
        uint_to_hex(quotient);
 
    putchar("0123456789ABCDEF"[value % 16]);
}

Output of the program as follows,

 
**Program converts Unsigned int to Hexadecimal No.**
 
User, enter an unsigned integer value or -1 to quit: 54
36
more conversions, enter unsigned integer or -1 to quit: 12
C
more conversions, enter unsigned integer or -1 to quit: 8667
21DB
more conversions, enter unsigned integer or -1 to quit: 12
C
more conversions, enter unsigned integer or -1 to quit: 3232
CA0
more conversions, enter unsigned integer or -1 to quit: -1
Thank You!

Notice how easy it has become to convert unsigned values to hex exploiting string literal. Exp.

    [value % 16]

in square parenthesis evaluates subscript in the exp.

    "0123456789ABCDEF"[value % 16]

and then selected the corresponding character from the string before printed that.

Sanfoundry Global Education & Learning Series – 1000 C Tutorials.

If you wish to look at all C Tutorials, go to C Tutorials.

advertisement
Manish Bhojasia, a technology veteran with 20+ years @ Cisco & Wipro, is Founder and CTO at Sanfoundry. He is Linux Kernel Developer & SAN Architect and is passionate about competency developments in these areas. He lives in Bangalore and delivers focused training sessions to IT professionals in Linux Kernel, Linux Debugging, Linux Device Drivers, Linux Networking, Linux Storage, Advanced C Programming, SAN Storage Technologies, SCSI Internals & Storage Protocols such as iSCSI & Fiber Channel. Stay connected with him @ LinkedIn