Objective-C Programming_ The Big Nerd Ranch Guide - Aaron Hillegass [84]
int main (int argc, const char * argv[])
{
char x = '!'; // The character '!'
while (x <= '~') { // The character '~'
printf("%x is %c\n", x, x);
x++;
}
return 0;
}
Build it and run it.
The non-printable characters can be expressed using escape sequences that start with \. You’ve already used \n for the newline character. Here are some common ones:
Table 34.1 Common escape sequences
\n new line
\t tab
\' single-quote
\" double-quote
\0 null byte (0x00)
\\ backslash
char *
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.
Figure 34.1 The word “Love” as a C string
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 #include #include int main (int argc, const char * argv[]) { char x = '!'; // The character '!' while (x <= '~') { // The character '~' printf("%x is %c\n", 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 characters\n", start, strlen(start)); // Print out the third letter printf("The third letter is %c\n", *(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. Figure 34.2 The address of each character 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 characters\n", start, strlen(start)); printf("The third letter is %c\n", 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 %d\n", 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. String literals int main (int argc, const char * argv[]) { char x = '!'; // The character '!' while (x <= '~') { // The character '~' printf("%x is %c\n", x, x); x++; } char *start = "Love"; printf("%s has %zu characters\n", start, strlen(start)); printf("The third letter
If you were dealing with C strings a lot, malloc’ing the memory and stuffing the characters in one-by-one would be a real pain. Instead, you can create a pointer to a string of characters (terminated with the zero character) by putting the string in quotes. Change your code to use a string literal: