CSC161 2011S Imperative Problem Solving

Reading: Strings

Reading: K&R 5.5, B3

Please submit a question by 9 p.m. on Tuesday, 5 April 2011.


What does strings.h contain?

Primarily declarations for the string functions. But you can find out for yourself:
more /usr/include/strings.h

It seems like you can do the same thing with both arrays and pointers. What's the reason of using one over the other? From the reading, it seems to prefer pointers because of more concise code.

Is there some way to determine whether to use a character array or a character pointer?

As you may recall, arrays and pointers are very similar. I generally prefer to use pointers for strings. However, arrays can be useful if you want to specify the amount of space available or make an array that is bigger than the initial string it contains. If you want the string to be mutable and you're assigning a string constant during declaration, you should use an array.

How does string concatenation work? If you're concatenating the strings s and t together (and strings are arrays of characters) are the contents of t copied into memory directly after s, making s longer? I didn't think it was possible to change the lengths of arrays. What am I missing?

When you use strcat to concatenate strings, the new string is appended to the end of the first string. This changes the length of the string. If you've allocated enough space (e.g., by declaring an array), the appending is safe. If you haven't allocated enough space, you'll end up munging something else.

K&R mention that pointers can be pointed elsewhere after initial assignment, but that if the string contents are modified, the result is undefined. Could you elaborate on what "result is undefined" means in this context?

It means that the compiler writer can do whatever she wants. Allow the change. Crash the program. Change something else. Whatever.

Where does the prefix "mem" come from in the string functions?

It's short for Memory. To the C programmer, memory is just an array of bytes. And a C char is the same size as a byte.

What's the difference between the str... functions and the mem... functions?

The string functions treat the memory as strings, and therefore look for the null terminator. The mem functions do not, which means that you can copy and otherwise use the zero byte.

Is memory allocated for string constants? For example, in the code:

char *foo = "hello";

what part of this allocates memory?

Memory is allocated for the string constant (often called static memory, since it's a constant). Memory is also allocated to hold the pointer.

If a string constant is enough to allocate memory, then would a hello world program allocate memory for the string?

Yes.

Can you explain size_t strspn(cs, ct)?

Suppose we have a string that may contain both characters we care about (e.g., the digits) and characters we don't care about (e.g., anything else). Then strspn finds the length of the largest prefix that contains only characters we care about. cs is the string we search, ct is the set of characters we care about. For example,


  leading_spaces = strspn (str, " ");

tells us how many spaces appear at the beginning of a string.

At the end of 5.5, K&R made reference to using pointers and increments/decrements in stacks.

*p++ = val; /* push val onto stack */ 
val = *--p; /* pop top of stack into val */

While this isn't super relevant to this section, is there a difference in precedence between --p and p--?

Most certainly. Both decrement the pointer, but --p returns the new pointer (after decrementing) while p-- returns the old pointer (before decrementing).

Could you go over why there is a separate version of strcpy for an array and for a pointer? (pg 105)

I see four versions of strcpy. The first one uses an array for clarity. But arrays and strings are relatively interchangable, so the next three use pointers for concision.

In strcpy, how come you can increment pointers s and t? How does that work? I thought a pointer points to the whole string.

When you increment to a pointer, you must make it point to the next thing. So if str is initially "hello", ++str is now "ello".

"It said: 1) There is an important difference between these definitions: char amessage[] = ""now is the time""; /* an array */ char *pmessage = ""now is the time""; /* a pointer */

Is it because pmessage has the * for pmessage so it is a pointer whereas the amessage is an array because its structure [ie: name[] ]? so pmessage is not a proc like ""if"" or ""when""?

I do not understand how the code would work if its changed from:

/* strcpy: copy t to s; pointer version */
void strcpy(char *s, char *t)
{
  int i;
  i = 0;
  while ((*s = *t) != '\0') {
    s++;
    t++;
  }
}

to:

/* strcpy: copy t to s; pointer version 2 */
void strcpy(char *s, char *t)
{
  while ((*s++ = *t++) != '\0')
    ;
}

What does it mean when things are split into tokens?"

In B.3, there is mention of tokens...What is a token?

Often, we think of different parts of text serving different purposes. For example, in trying to compile C code, we want to identify keywords (e.g., if), names (e.g., fun), strings (e.g., "Hello"), numbers (e.g., 3.1415), and so on and so forth. We call those different things tokens.

A string constant is accessed by a pointer to its first element. I am confused about how a pointer only points to the first element of a string. Does this mean that the pointer points to the first character in the string, and when the pointer is referenced the pointer reads from memory all characters following the first character until \0 is reached, and then the pointer gives all of those characters to whatever is referencing it?

Strings are located somewhere in memory. Hence, to talk about them, we normally talk about the address of the first character (a pointer to that first character). The functions that process strings then read from that starting point until they hit the null terminator. So, the pointer doesn't do the reading, the functions do the reading.

Does this mean strings can be any size, since the end of a string is not after a certain number of characters but is when \0 is reached?

Yes. The length of strings is limited only by the length of memory.

When they say something about a string, are they talking about the pointer to the string, the string itself, or the characters that make up the string?

Probably all of the above. In general, a string is a null-terminated sequence of characters.

I am still kinda confused how the incrementing the pointers works.

When you increment a pointer, you make the pointer point to the next thing. For a pointer to a character, it points to the next character (one byte later). For a pointer to an integer, it points to the next integer (typically four bytes later).

The book has a version of strcpy with pointers. It says, Because arguments are passed by value, strcpy can use the parameters s and t in any way it pleases. What does that mean?

You may recall that, in most cases, changes to parameters within a function do not affect the values passed in. We term that strategy pass by value. Because of this characteristic, it is safe to make s and t point anywhere we want without affecting the underlying strings.

You can pass array arguments into functions with pointer parameters, right?

Yes.

Can you do it the other way around, passing a pointer (which points to an array) into a function with array parameters?

Yes, as long as the function does not specify a particular size of the array.

Is it always better to use idioms to make your code more concise? It seems like it could make some code much more difficult to read.

An idiom should be common enough that it does not affect readability. Experienced C programmers would not have difficulty with any of the K&R examples.


Things I May Cover in Class

Can you show more examples of strcmp please? =)

Yes.

How does the first code on page 106 know where to end? [This is the code for the most concise strcpy.]

When you hit the end of the string, *s is the character '\0', which is the same as the integer 0, which C treats as false.

I understand both readings. However I don't know some of the differences in outputs of similar functions such as strchr(ch,c) and strrchr(cs,c). Can we go through some of these in class?

Yes.


Questions I Could Not (or Chose Not To) Answer

When would it be useful to either use pointers or strings? Are there specific circumstances that warrant the use of one over the other?

I don't understand the question.


Questions I Have Not Yet Answered


Extra

The first five people to tell me that they've read this will earn credit for one missed reading (or a bit of extra credit if they've missed no readings). Please do not tell your colleagues about this.

Disclaimer: I usually create these pages on the fly, which means that I rarely proofread them and they may contain bad grammar and incorrect details. It also means that I tend to update them regularly (see the history for more details). Feel free to contact me with any suggestions for changes.

This document was generated by Siteweaver on Wed Apr 6 10:53:40 2011.
The source to the document was last modified on Wed Apr 6 10:53:37 2011.
This document may be found at http://www.cs.grinnell.edu/~rebelsky/Courses/CSC161/2011S/Readings/strings.html.

Samuel A. Rebelsky, rebelsky@grinnell.edu