A C string is just a bunch of characters right next to each other in memory. The string ends when the character 0x00 is encountered.
Functions that take C strings expect the address of the string’s first character. strlen(), for example, will count the number of characters in a string. Try building a string and using strlen() to count the letters:
#include <stdio.h> // For printf #include <stdlib.h> // For malloc/free #include <string.h> // For strlen int main (int argc, const char * argv[]) { char x = '!'; // The character '!' while (x <= '~') { // The character '~' printf("%x is %cn", x, x); x++; } // Get a pointer to 5 bytes of memory on the heap char *start = malloc(5); // Put 'L' in the first byte *start = 'L'; // Put 'o' in the second byte *(start + 1) = 'o'; // Put 'v' in the third byte *(start + 2) = 'v'; // Put 'e' in the fourth byte *(start + 3) = 'e'; // Put zero in the fifth byte *(start + 4) = '0'; // Print out the string and its length printf("%s has %zu charactersn", start, strlen(start)); // Print out the third letter printf("The third letter is %cn", *(start + 2)); // Free the memory so that it can be reused free(start); start = NULL; return 0; }
Build and run it.
Notice the places where you added a pointer and a number together. start is declared to be a char *. A char is one byte. So start + 1 is a pointer one byte further in memory than start. start + 2 is two bytes further in memory than start.
This adding to a pointer and dereferencing the result is so common that there is a shorthand for it: start[2] is equivalent to *(start + 2). Change your code to use it:
char *start = malloc(5); start[0] = 'L'; start[1] = 'o'; start[2] = 'v'; start[3] = 'e'; start[4] = '0'; printf("%s has %zu charactersn", start, strlen(start)); printf("The third letter is %cn", start[2]); free(start); start = NULL; return 0; }
Build and run it.
It should be mentioned that this works with any data type. Here, for example, I can make a list of my favorite 3 floating point numbers and print them out:
int main (int argc, const char * argv[]) { // Claim a chunk of memory big enough to hold three floats float *favorites = malloc(3 * sizeof(float)); // Push values into the locations in that buffer favorites[0] = 3.14158; favorites[1] = 2.71828; favorites[2] = 1.41421; // Print out each number on the list for (int i = 0; i < 3; i++) { printf("%.4f is favorite %dn", favorites[i], i); } // Free the memory so that it can be reused free(favorites); favorites = NULL; return 0; }
The only interesting difference here is that favorites is typed as a float *. A float is 4 bytes. Thus favorites + 1 is 4 bytes further in memory than favorites.