[quote]//Why does “*question” have to be a pointer and not just a variable?
const char *question = readline ("Where should I start counting? ");
NSString *questionInObjCString = [NSString stringWithUTF8String: question];
The readline function returns a value, which is the address of the first byte of a buffer in memory containing the characters read from the input. You can assign that value only to a variable of type either char * or void *. That’s why the variable question has to be a pointer to char.
The readline function reads a sequence of characters from the input, stores them in a buffer in memory, and returns not the sequence of characters but the address of that buffer. The reason it returns the address of the buffer, not the characters, is that the number of characters read from the input can exceed the storage capacity associated with a variable of primitive type, such as char, int, long, etc.
Similarly, the method call [questionInObjCString integerValue] returns a value, which is stored in a memory buffer consisting of a fixed, small number of bytes. That value can fit in the buffer represented by the variable answerFromQuestion of type NSInteger. That’s why the variable answerFromQuestion is not a pointer.
As implied above, all variable names are actually names of buffers in memory. For example:
char * string;
The variable names result, offset, key, and string are names of buffers in memory. The size of a buffer is determined by the type of the corresponding variable. For example, on my machine’s architecture, both result and offset each takes 8 bytes in memory; key takes 1 byte, and string takes 8 bytes. Note that unlike the other buffers, the string buffer is used to store the address of a sequence of characters.