Infolinks In Text Ads

Invisibility Technology: Coming Soon Share

The race to make invisibility technology is on. Invisibility,may soon become a reality and through some interesting implementations, could actually serve as a useful feature in product design.

HOW TO HACK FACEBOOK ACCOUNT

These are some ways of hacking facebook account. There may be more but this time only these are in my mind.

C Programming Language

is sometimes referred to as a ``high-level assembly language.'' Some people think that's an insult, but it's actually a deliberate and significant aspect of the language.

Business

We are youth and youngsters and in todays time only aggressive, passionable, confidential youths can be better businessmen and we can do something else by which we can prove every body that we can create a new world.

FITNESS FIRST FOR WOMEN

The female-only environment of Fitness First for Women means that you'll be totally comfortable working out with us, no matter what shape or size you are - or think you are!

TRANSPARENT COMPUTER SCREEN

Transparent Computer technology has progressed rapidly, keep reading to learn more about this incredible technology.

PROJECTION KEYBOARD

A projection keyboard is a virtual keyboard that can be projected and touched on any surface. The keyboard watches finger movements and translates them into keystrokes in the device.

PROGRAMMING IN DOTNET

Dot net is advanced suite which is removing the walls between applications and the internet.

INTRODUCING HTML

The general rule with HTML tags is : For every beginning, there is an ending. The tags shown with the forward slash in them / are the ending tags.

Friday 22 July 2011

New Google Search


WOW: Google to Launch a New Version of Google Search



Google has a giant target on its back. Microsoft has been on a spending and deal-making spree to grow Bing, recently signing a huge search deal with Yahoo. And with Bing starting to steal some market share from Google, it’s proving to be a formidable opponent. Oh, and now you can’t count out Facebook either, which just launched a new realtime search engine.
Google’s not taking any of this lying down. Secretly, they’ve been working on a new project: the next generation of Google Search. This isn’t just some minor upgrade, but an entire new infrastructure for the world’s largest search engine. In other words: it’s a new version of Google.

The project’s still under construction, but Google’s now confident enough in the new version of its search engine that it has released the development version for public consumption. While you won’t see too many differences immediately, let us assure you: it’s a completely upgraded Google search.
Google specifically states that its goal for the new version of Google Search is to improve its indexing speed, accuracy, size, and comprehensiveness. Here’s what they wrote:
“For the last several months, a large team of Googlers has been working on a secret project: a next-generation architecture for Google’s web search. It’s the first step in a process that will let us push the envelope on size, indexing speed, accuracy, comprehensiveness and other dimensions. The new infrastructure sits “under the hood” of Google’s search engine, which means that most users won’t notice a difference in search results. But web developers and power searchers might notice a few differences, so we’re opening up a web developer preview to collect feedback.”

Trying Out the New Search

We just tried out the the new version of Google, and we will say this: the results are different. Let’s compare, using the keyword “Nextdoor-nextway” as a reference point.
First, the current version of Google

And the new version of Google Search:


Conclusion: This search is not only faster, but in some instances in our few tests, seems more capable of producing real-time results. It’s still way too early to make any definitive conclusions about this new search, but we will test it out thoroughly and give you a full report soon. In the meantime, try it out for yourself and tell us what you think.

9.3 Conditional Compilation


9.3 Conditional Compilation

[This section corresponds to K&R Sec. 4.11.3]

The last preprocessor directive we're going to look at is #ifdef. If you have the sequence

#ifdef name
program text
#else
more program text
#endif
in your program, the code that gets compiled depends on whether a preprocessor macro by that name is defined or not. If it is (that is, if there has been a #define line for a macro called name), then ``program text'' is compiled and ``more program text'' is ignored. If the macro is not defined, ``more program text'' is compiled and ``program text'' is ignored. This looks a lot like an if statement, but it behaves completely differently: an if statement controls which statements of your program are executed at run time, but #ifdef controls which parts of your program actually get compiled.
Just as for the if statement, the #else in an #ifdef is optional. There is a companion directive #ifndef, which compiles code if the macro is not defined (although the ``#else clause'' of an #ifndef directive will then be compiled if the macro is defined). There is also an #if directive which compiles code depending on whether a compile-time expression is true or false. (The expressions which are allowed in an #if directive are somewhat restricted, however, so we won't talk much about #if here.)

Conditional compilation is useful in two general classes of situations:

You are trying to write a portable program, but the way you do something is different depending on what compiler, operating system, or computer you're using. You place different versions of your code, one for each situation, between suitable #ifdef directives, and when you compile the progam in a particular environment, you arrange to have the macro names defined which select the variants you need in that environment. (For this reason, compilers usually have ways of letting you define macros from the invocation command line or in a configuration file, and many also predefine certain macro names related to the operating system, processor, or compiler in use. That way, you don't have to change the code to change the #define lines each time you compile it in a different environment.)

For example, in ANSI C, the function to delete a file is remove. On older Unix systems, however, the function was called unlink. So if filename is a variable containing the name of a file you want to delete, and if you want to be able to compile the program under these older Unix systems, you might write
#ifdef unix
unlink(filename);
#else
remove(filename);
#endif
Then, you could place the line
#define unix
at the top of the file when compiling under an old Unix system. (Since all you're using the macro unix for is to control the #ifdef, you don't need to give it any replacement text at all. Any definition for a macro, even if the replacement text is empty, causes an #ifdef to succeed.)

(In fact, in this example, you wouldn't even need to define the macro unix at all, because C compilers on old Unix systems tend to predefine it for you, precisely so you can make tests like these.)
You want to compile several different versions of your program, with different features present in the different versions. You bracket the code for each feature with #ifdef directives, and (as for the previous case) arrange to have the right macros defined or not to build the version you want to build at any given time. This way, you can build the several different versions from the same source code. (One common example is whether you turn debugging statements on or off. You can bracket each debugging printout with #ifdef DEBUG and #endif, and then turn on debugging only when you need it.)

For example, you might use lines like this:
#ifdef DEBUG
printf("x is %d\n", x);
#endif
to print out the value of the variable x at some point in your program to see if it's what you expect. To enable debugging printouts, you insert the line
#define DEBUG
at the top of the file, and to turn them off, you delete that line, but the debugging printouts quietly remain in your code, temporarily deactivated, but ready to reactivate if you find yourself needing them again later. (Also, instead of inserting and deleting the #define line, you might use a compiler flag such as -DDEBUG to define the macro DEBUG from the compiler invocatin line.)
Conditional compilation can be very handy, but it can also get out of hand. When large chunks of the program are completely different depending on, say, what operating system the program is being compiled for, it's often better to place the different versions in separate source files, and then only use one of the files (corresponding to one of the versions) to build the program on any given system. Also, if you are using an ANSI Standard compiler and you are writing ANSI-compatible code, you usually won't need so much conditional compilation, because the Standard specifies exactly how the compiler must do certain things, and exactly which library functions it much provide, so you don't have to work so hard to accommodate the old variations among compilers and libraries.

9.2 Macro Definition and Substitution


9.2 Macro Definition and Substitution

[This section corresponds to K&R Sec. 4.11.2]

A preprocessor line of the form

#define name text
defines a macro with the given name, having as its value the given replacement text. After that (for the rest of the current source file), wherever the preprocessor sees that name, it will replace it with the replacement text. The name follows the same rules as ordinary identifiers (it can contain only letters, digits, and underscores, and may not begin with a digit). Since macros behave quite differently from normal variables (or functions), it is customary to give them names which are all capital letters (or at least which begin with a capital letter). The replacement text can be absolutely anything--it's not restricted to numbers, or simple strings, or anything.
The most common use for macros is to propagate various constants around and to make them more self-documenting. We've been saying things like

char line[100];
...
getline(line, 100);
but this is neither readable nor reliable; it's not necessarily obvious what all those 100's scattered around the program are, and if we ever decide that 100 is too small for the size of the array to hold lines, we'll have to remember to change the number in two (or more) places. A much better solution is to use a macro:
#define MAXLINE 100
char line[MAXLINE];
...
getline(line, MAXLINE);
Now, if we ever want to change the size, we only have to do it in one place, and it's more obvious what the words MAXLINE sprinkled through the program mean than the magic numbers 100 did.
Since the replacement text of a preprocessor macro can be anything, it can also be an expression, although you have to realize that, as always, the text is substituted (and perhaps evaluated) later. No evaluation is performed when the macro is defined. For example, suppose that you write something like

#define A 2
#define B 3
#define C A + B
(this is a pretty meaningless example, but the situation does come up in practice). Then, later, suppose that you write
int x = C * 2;
If A, B, and C were ordinary variables, you'd expect x to end up with the value 10. But let's see what happens.
The preprocessor always substitutes text for macros exactly as you have written it. So it first substitites the replacement text for the macro C, resulting in

int x = A + B * 2;
Then it substitutes the macros A and B, resulting in
int x = 2 + 3 * 2;
Only when the preprocessor is done doing all this substituting does the compiler get into the act. But when it evaluates that expression (using the normal precedence of multiplication over addition), it ends up initializing x with the value 8!
To guard against this sort of problem, it is always a good idea to include explicit parentheses in the definitions of macros which contain expressions. If we were to define the macro C as

#define C (A + B)
then the declaration of x would ultimately expand to
int x = (2 + 3) * 2;
and x would be initialized to 10, as we probably expected.
Notice that there does not have to be (and in fact there usually is not) a semicolon at the end of a #define line. (This is just one of the ways that the syntax of the preprocessor is different from the rest of C.) If you accidentally type

#define MAXLINE 100; /* WRONG */
then when you later declare
char line[MAXLINE];
the preprocessor will expand it to
char line[100;]; /* WRONG */
which is a syntax error. This is what we mean when we say that the preprocessor doesn't know much of anything about the syntax of C--in this last example, the value or replacement text for the macro MAXLINE was the 4 characters 1 0 0 ; , and that's exactly what the preprocessor substituted (even though it didn't make any sense).
Simple macros like MAXLINE act sort of like little variables, whose values are constant (or constant expressions). It's also possible to have macros which look like little functions (that is, you invoke them with what looks like function call syntax, and they expand to replacement text which is a function of the actual arguments they are invoked with) but we won't be looking at these yet.

9.1 File Inclusion


9.1 File Inclusion

[This section corresponds to K&R Sec. 4.11.1]

A line of the form

#include <filename.h>
or
#include "filename.h"
causes the contents of the file filename.h to be read, parsed, and compiled at that point. (After filename.h is processed, compilation continues on the line following the #include line.) For example, suppose you got tired of retyping external function prototypes such as
extern int getline(char [], int);
at the top of each source file. You could instead place the prototype in a header file, perhaps getline.h, and then simply place
#include "getline.h"
at the top of each source file where you called getline. (You might not find it worthwhile to create an entire header file for a single function, but if you had a package of several related function, it might be very useful to place all of their declarations in one header file.) As we may have mentioned, that's exactly what the Standard header files such as stdio.h are--collections of declarations (including external function prototype declarations) having to do with various sets of Standard library functions. When you use #include to read in a header file, you automatically get the prototypes and other declarations it contains, and you should use header files, precisely so that you will get the prototypes and other declarations they contain.
The difference between the <> and "" forms is where the preprocessor searches for filename.h. As a general rule, it searches for files enclosed in <> in central, standard directories, and it searches for files enclosed in "" in the ``current directory,'' or the directory containing the source file that's doing the including. Therefore, "" is usually used for header files you've written, and <> is usually used for headers which are provided for you (which someone else has written).

The extension ``.h'', by the way, simply stands for ``header,'' and reflects the fact that #include directives usually sit at the top (head) of your source files, and contain global declarations and definitions which you would otherwise put there. (That extension is not mandatory--you can theoretically name your own header files anything you wish--but .h is traditional, and recommended.)

As we've already begun to see, the reason for putting something in a header file, and then using #include to pull that header file into several different source files, is when the something (whatever it is) must be declared or defined consistently in all of the source files. If, instead of using a header file, you typed the something in to each of the source files directly, and the something ever changed, you'd have to edit all those source files, and if you missed one, your program could fail in subtle (or serious) ways due to the mismatched declarations (i.e. due to the incompatibility between the new declaration in one source file and the old one in a source file you forgot to change). Placing common declarations and definitions into header files means that if they ever change, they only have to be changed in one place, which is a much more workable system.

What should you put in header files?

External declarations of global variables and functions. We said that a global variable must have exactly one defining instance, but that it can have external declarations in many places. We said that it was a grave error to issue an external declaration in one place saying that a variable or function has one type, when the defining instance in some other place actually defines it with another type. (If the two places are two source files, separately compiled, the compiler will probably not even catch the discrepancy.) If you put the external declarations in a header file, however, and include the header wherever it's needed, the declarations are virtually guaranteed to be consistent. It's a good idea to include the header in the source file where the defining instance appears, too, so that the compiler can check that the declaration and definition match. (That is, if you ever change the type, you do still have to change it in two places: in the source file where the defining instance occurs, and in the header file where the external declaration appears. But at least you don't have to change it in an arbitrary number of places, and, if you've set things up correctly, the compiler can catch any remaining mistakes.)
Preprocessor macro definitions (which we'll meet in the next section).
Structure definitions (which we haven't seen yet).
Typedef declarations (which we haven't seen yet).
However, there are a few things not to put in header files:
Defining instances of global variables. If you put these in a header file, and include the header file in more than one source file, the variable will end up multiply defined.
Function bodies (which are also defining instances). You don't want to put these in headers for the same reason--it's likely that you'll end up with multiple copies of the function and hence ``multiply defined'' errors. People sometimes put commonly-used functions in header files and then use #include to bring them (once) into each program where they use that function, or use #include to bring together the several source files making up a program, but both of these are poor ideas. It's much better to learn how to use your compiler or linker to combine together separately-compiled object files.
Since header files typically contain only external declarations, and should not contain function bodies, you have to understand just what does and doesn't happen when you #include a header file. The header file may provide the declarations for some functions, so that the compiler can generate correct code when you call them (and so that it can make sure that you're calling them correctly), but the header file does not give the compiler the functions themselves. The actual functions will be combined into your program at the end of compilation, by the part of the compiler called the linker. The linker may have to get the functions out of libraries, or you may have to tell the compiler/linker where to find them. In particular, if you are trying to use a third-party library containing some useful functions, the library will often come with a header file describing those functions. Using the library is therefore a two-step process: you must #include the header in the files where you call the library functions, and you must tell the linker to read in the functions from the library itself.

Chapter 9: The C Preprocessor


Chapter 9: The C Preprocessor

Conceptually, the ``preprocessor'' is a translation phase that is applied to your source code before the compiler proper gets its hands on it. (Once upon a time, the preprocessor was a separate program, much as the compiler and linker may still be separate programs today.) Generally, the preprocessor performs textual substitutions on your source code, in three sorts of ways:

File inclusion: inserting the contents of another file into your source file, as if you had typed it all in there.
Macro substitution: replacing instances of one piece of text with another.
Conditional compilation: Arranging that, depending on various circumstances, certain parts of your source code are seen or not seen by the compiler at all.
The next three sections will introduce these three preprocessing functions.
The syntax of the preprocessor is different from the syntax of the rest of C in several respects. First of all, the preprocessor is ``line based.'' Each of the preprocessor directives we're going to learn about (all of which begin with the # character) must begin at the beginning of a line, and each ends at the end of the line. (The rest of C treats line ends as just another whitespace character, and doesn't care how your program text is arranged into lines.) Secondly, the preprocessor does not know about the structure of C--about functions, statements, or expressions. It is possible to play strange tricks with the preprocessor to turn something which does not look like C into C (or vice versa). It's also possible to run into problems when a preprocessor substitution does not do what you expected it to, because the preprocessor does not respect the structure of C statements and expressions (but you expected it to). For the simple uses of the preprocessor we'll be discussing, you shouldn't have any of these problems, but you'll want to be careful before doing anything tricky or outrageous with the preprocessor. (As it happens, playing tricky and outrageous games with the preprocessor is considered sporting in some circles, but it rapidly gets out of hand, and can lead to bewilderingly impenetrable programs.)

9.1 File Inclusion

9.2 Macro Definition and Substitution

9.3 Conditional Compilation

Chapter 8: Strings


Chapter 8: Strings

Strings in C are represented by arrays of characters. The end of the string is marked with a special character, the null character, which is simply the character with the value 0. (The null character has no relation except in name to the null pointer. In the ASCII character set, the null character is named NUL.) The null or string-terminating character is represented by another character escape sequence, \0. (We've seen it once already, in the getline function of chapter 6.)

Because C has no built-in facilities for manipulating entire arrays (copying them, comparing them, etc.), it also has very few built-in facilities for manipulating strings.

In fact, C's only truly built-in string-handling is that it allows us to use string constants (also called string literals) in our code. Whenever we write a string, enclosed in double quotes, C automatically creates an array of characters for us, containing that string, terminated by the \0 character. For example, we can declare and define an array of characters, and initialize it with a string constant:

char string[] = "Hello, world!";
In this case, we can leave out the dimension of the array, since the compiler can compute it for us based on the size of the initializer (14, including the terminating \0). This is the only case where the compiler sizes a string array for us, however; in other cases, it will be necessary that we decide how big the arrays and other data structures we use to hold strings are.
To do anything else with strings, we must typically call functions. The C library contains a few basic string manipulation functions, and to learn more about strings, we'll be looking at how these functions might be implemented.

Since C never lets us assign entire arrays, we use the strcpy function to copy one string to another:

#include <string.h>

char string1[] = "Hello, world!";
char string2[20];

strcpy(string2, string1);
The destination string is strcpy's first argument, so that a call to strcpy mimics an assignment expression (with the destination on the left-hand side). Notice that we had to allocate string2 big enough to hold the string that would be copied to it. Also, at the top of any source file where we're using the standard library's string-handling functions (such as strcpy) we must include the line
#include <string.h>
which contains external declarations for these functions.
Since C won't let us compare entire arrays, either, we must call a function to do that, too. The standard library's strcmp function compares two strings, and returns 0 if they are identical, or a negative number if the first string is alphabetically ``less than'' the second string, or a positive number if the first string is ``greater.'' (Roughly speaking, what it means for one string to be ``less than'' another is that it would come first in a dictionary or telephone book, although there are a few anomalies.) Here is an example:

char string3[] = "this is";
char string4[] = "a test";

if(strcmp(string3, string4) == 0)
printf("strings are equal\n");
else printf("strings are different\n");
This code fragment will print ``strings are different''. Notice that strcmp does not return a Boolean, true/false, zero/nonzero answer, so it's not a good idea to write something like
if(strcmp(string3, string4))
...
because it will behave backwards from what you might reasonably expect. (Nevertheless, if you start reading other people's code, you're likely to come across conditionals like if(strcmp(a, b)) or even if(!strcmp(a, b)). The first does something if the strings are unequal; the second does something if they're equal. You can read these more easily if you pretend for a moment that strcmp's name were strdiff, instead.)
Another standard library function is strcat, which concatenates strings. It does not concatenate two strings together and give you a third, new string; what it really does is append one string onto the end of another. (If it gave you a new string, it would have to allocate memory for it somewhere, and the standard library string functions generally never do that for you automatically.) Here's an example:

char string5[20] = "Hello, ";
char string6[] = "world!";

printf("%s\n", string5);

strcat(string5, string6);

printf("%s\n", string5);
The first call to printf prints ``Hello, '', and the second one prints ``Hello, world!'', indicating that the contents of string6 have been tacked on to the end of string5. Notice that we declared string5 with extra space, to make room for the appended characters.
If you have a string and you want to know its length (perhaps so that you can check whether it will fit in some other array you've allocated for it), you can call strlen, which returns the length of the string (i.e. the number of characters in it), not including the \0:

char string7[] = "abc";
int len = strlen(string7);
printf("%d\n", len);
Finally, you can print strings out with printf using the %s format specifier, as we've been doing in these examples already (e.g. printf("%s\n", string5);).

Since a string is just an array of characters, all of the string-handling functions we've just seen can be written quite simply, using no techniques more complicated than the ones we already know. In fact, it's quite instructive to look at how these functions might be implemented. Here is a version of strcpy:

mystrcpy(char dest[], char src[])
{
int i = 0;

while(src[i] != '\0')
{
dest[i] = src[i];
i++;
}

dest[i] = '\0';
}
We've called it mystrcpy instead of strcpy so that it won't clash with the version that's already in the standard library. Its operation is simple: it looks at characters in the src string one at a time, and as long as they're not \0, assigns them, one by one, to the corresponding positions in the dest string. When it's done, it terminates the dest string by appending a \0. (After exiting the while loop, i is guaranteed to have a value one greater than the subscript of the last character in src.) For comparison, here's a way of writing the same code, using a for loop:
for(i = 0; src[i] != '\0'; i++)
dest[i] = src[i];

dest[i] = '\0';
Yet a third possibility is to move the test for the terminating \0 character out of the for loop header and into the body of the loop, using an explicit if and break statement, so that we can perform the test after the assignment and therefore use the assignment inside the loop to copy the \0 to dest, too:
for(i = 0; ; i++)
{
dest[i] = src[i];
if(src[i] == '\0')
break;
}
(There are in fact many, many ways to write strcpy. Many programmers like to combine the assignment and test, using an expression like (dest[i] = src[i]) != '\0'. This is actually the same sort of combined operation as we used in our getchar loop in chapter 6.)

Here is a version of strcmp:

mystrcmp(char str1[], char str2[])
{
int i = 0;

while(1)
{
if(str1[i] != str2[i])
return str1[i] - str2[i];
if(str1[i] == '\0' || str2[i] == '\0')
return 0;
i++;
}
}
Characters are compared one at a time. If two characters in one position differ, the strings are different, and we are supposed to return a value less than zero if the first string (str1) is alphabetically less than the second string. Since characters in C are represented by their numeric character set values, and since most reasonable character sets assign values to characters in alphabetical order, we can simply subtract the two differing characters from each other: the expression str1[i] - str2[i] will yield a negative result if the i'th character of str1 is less than the corresponding character in str2. (As it turns out, this will behave a bit strangely when comparing upper- and lower-case letters, but it's the traditional approach, which the standard versions of strcmp tend to use.) If the characters are the same, we continue around the loop, unless the characters we just compared were (both) \0, in which case we've reached the end of both strings, and they were both equal. Notice that we used what may at first appear to be an infinite loop--the controlling expression is the constant 1, which is always true. What actually happens is that the loop runs until one of the two return statements breaks out of it (and the entire function). Note also that when one string is longer than the other, the first test will notice this (because one string will contain a real character at the [i] location, while the other will contain \0, and these are not equal) and the return value will be computed by subtracting the real character's value from 0, or vice versa. (Thus the shorter string will be treated as ``less than'' the longer.)
Finally, here is a version of strlen:

int mystrlen(char str[])
{
int i;

for(i = 0; str[i] != '\0'; i++)
{}

return i;
}
In this case, all we have to do is find the \0 that terminates the string, and it turns out that the three control expressions of the for loop do all the work; there's nothing left to do in the body. Therefore, we use an empty pair of braces {} as the loop body. Equivalently, we could use a null statement, which is simply a semicolon:
for(i = 0; str[i] != '\0'; i++)
;
Empty loop bodies can be a bit startling at first, but they're not unheard of.
Everything we've looked at so far has come out of C's standard libraries. As one last example, let's write a substr function, for extracting a substring out of a larger string. We might call it like this:

char string8[] = "this is a test";
char string9[10];
substr(string9, string8, 5, 4);
printf("%s\n", string9);
The idea is that we'll extract a substring of length 4, starting at character 5 (0-based) of string8, and copy the substring to string9. Just as with strcpy, it's our responsibility to declare the destination string (string9) big enough. Here is an implementation of substr. Not surprisingly, it's quite similar to strcpy:
substr(char dest[], char src[], int offset, int len)
{
int i;
for(i = 0; i < len && src[offset + i] != '\0'; i++)
dest[i] = src[i + offset];
dest[i] = '\0';
}
If you compare this code to the code for mystrcpy, you'll see that the only differences are that characters are fetched from src[offset + i] instead of src[i], and that the loop stops when len characters have been copied (or when the src string runs out of characters, whichever comes first).
In this chapter, we've been careless about declaring the return types of the string functions, and (with the exception of mystrlen) they haven't returned values. The real string functions do return values, but they're of type ``pointer to character,'' which we haven't discussed yet.

When working with strings, it's important to keep firmly in mind the differences between characters and strings. We must also occasionally remember the way characters are represented, and about the relation between character values and integers.

As we have had several occasions to mention, a character is represented internally as a small integer, with a value depending on the character set in use. For example, we might find that 'A' had the value 65, that 'a' had the value 97, and that '+' had the value 43. (These are, in fact, the values in the ASCII character set, which most computers use. However, you don't need to learn these values, because the vast majority of the time, you use character constants to refer to characters, and the compiler worries about the values for you. Using character constants in preference to raw numeric values also makes your programs more portable.)

As we may also have mentioned, there is a big difference between a character and a string, even a string which contains only one character (other than the \0). For example, 'A' is not the same as "A". To drive home this point, let's illustrate it with a few examples.

If you have a string:

char string[] = "hello, world!";
you can modify its first character by saying
string[0] = 'H';
(Of course, there's nothing magic about the first character; you can modify any character in the string in this way. Be aware, though, that it is not always safe to modify strings in-place like this; we'll say more about the modifiability of strings in a later chapter on pointers.) Since you're replacing a character, you want a character constant, 'H'. It would not be right to write
string[0] = "H"; /* WRONG */
because "H" is a string (an array of characters), not a single character. (The destination of the assignment, string[0], is a char, but the right-hand side is a string; these types don't match.)
On the other hand, when you need a string, you must use a string. To print a single newline, you could call

printf("\n");
It would not be correct to call
printf('\n'); /* WRONG */
printf always wants a string as its first argument. (As one final example, putchar wants a single character, so putchar('\n') would be correct, and putchar("\n") would be incorrect.)
We must also remember the difference between strings and integers. If we treat the character '1' as an integer, perhaps by saying

int i = '1';
we will probably not get the value 1 in i; we'll get the value of the character '1' in the machine's character set. (In ASCII, it's 49.) When we do need to find the numeric value of a digit character (or to go the other way, to get the digit character with a particular value) we can make use of the fact that, in any character set used by C, the values for the digit characters, whatever they are, are contiguous. In other words, no matter what values '0' and '1' have, '1' - '0' will be 1 (and, obviously, '0' - '0' will be 0). So, for a variable c holding some digit character, the expression
c - '0'
gives us its value. (Similarly, for an integer value i, i + '0' gives us the corresponding digit character, as long as 0 <= i <= 9.)
Just as the character '1' is not the integer 1, the string "123" is not the integer 123. When we have a string of digits, we can convert it to the corresponding integer by calling the standard function atoi:

char string[] = "123";
int i = atoi(string);
int j = atoi("456");
Later we'll learn how to go in the other direction, to convert an integer into a string. (One way, as long as what you want to do is print the number out, is to call printf, using %d in the format string.)

7.3 Order of Evaluation


7.3 Order of Evaluation

[This section corresponds to K&R Sec. 2.12]

When you start using the ++ and -- operators in larger expressions, you end up with expressions which do several things at once, i.e., they modify several different variables at more or less the same time. When you write such an expression, you must be careful not to have the expression ``pull the rug out from under itself'' by assigning two different values to the same variable, or by assigning a new value to a variable at the same time that another part of the expression is trying to use the value of that variable.

Actually, we had already started writing expressions which did several things at once even before we met the ++ and -- operators. The expression

(c = getchar()) != EOF
assigns getchar's return value to c, and compares it to EOF. The ++ and -- operators make it much easier to cram a lot into a small expression: the example
line[nch++] = c;
from the previous section assigned c to line[nch], and incremented nch. We'll eventually meet expressions which do three things at once, such as
a[i++] = b[j++];
which assigns b[j] to a[i], and increments i, and increments j.
If you're not careful, though, it's easy for this sort of thing to get out of hand. Can you figure out exactly what the expression

a[i++] = b[i++]; /* WRONG */
should do? I can't, and here's the important part: neither can the compiler. We know that the definition of postfix ++ is that the former value, before the increment, is what goes on to participate in the rest of the expression, but the expression a[i++] = b[i++] contains two ++ operators. Which of them happens first? Does this expression assign the old ith element of b to the new ith element of a, or vice versa? No one knows.
When the order of evaluation matters but is not well-defined (that is, when we can't say for sure which order the compiler will evaluate the various dependent parts in) we say that the meaning of the expression is undefined, and if we're smart we won't write the expression in the first place. (Why would anyone ever write an ``undefined'' expression? Because sometimes, the compiler happens to evaluate it in the order a programmer wanted, and the programmer assumes that since it works, it must be okay.)

For example, suppose we carelessly wrote this loop:

int i, a[10];
i = 0;
while(i < 10)
a[i] = i++; /* WRONG */
It looks like we're trying to set a[0] to 0, a[1] to 1, etc. But what if the increment i++ happens before the compiler decides which cell of the array a to store the (unincremented) result in? We might end up setting a[1] to 0, a[2] to 1, etc., instead. Since, in this case, we can't be sure which order things would happen in, we simply shouldn't write code like this. In this case, what we're doing matches the pattern of a for loop, anyway, which would be a better choice:
for(i = 0; i < 10; i++)
a[i] = i;
Now that the increment i++ isn't crammed into the same expression that's setting a[i], the code is perfectly well-defined, and is guaranteed to do what we want.
In general, you should be wary of ever trying to second-guess the order an expression will be evaluated in, with two exceptions:

You can obviously assume that precedence will dictate the order in which binary operators are applied. This typically says more than just what order things happens in, but also what the expression actually means. (In other words, the precedence of * over + says more than that the multiplication ``happens first'' in 1 + 2 * 3; it says that the answer is 7, not 9.)
Although we haven't mentioned it yet, it is guaranteed that the logical operators && and || are evaluated left-to-right, and that the right-hand side is not evaluated at all if the left-hand side determines the outcome.
To look at one more example, it might seem that the code

int i = 7;
printf("%d\n", i++ * i++);
would have to print 56, because no matter which order the increments happen in, 7*8 is 8*7 is 56. But ++ just says that the increment happens later, not that it happens immediately, so this code could print 49 (if the compiler chose to perform the multiplication first, and both increments later). And, it turns out that ambiguous expressions like this are such a bad idea that the ANSI C Standard does not require compilers to do anything reasonable with them at all. Theoretically, the above code could end up printing 42, or 8923409342, or 0, or crashing your computer.
Programmers sometimes mistakenly imagine that they can write an expression which tries to do too much at once and then predict exactly how it will behave based on ``order of evaluation.'' For example, we know that multiplication has higher precedence than addition, which means that in the expression

i + j * k
j will be multiplied by k, and then i will be added to the result. Informally, we often say that the multiplication happens ``before'' the addition. That's true in this case, but it doesn't say as much as we might think about a more complicated expression, such as
i++ + j++ * k++
In this case, besides the addition and multiplication, i, j, and k are all being incremented. We can not say which of them will be incremented first; it's the compiler's choice. (In particular, it is not necessarily the case that j++ or k++ will happen first; the compiler might choose to save i's value somewhere and increment i first, even though it will have to keep the old value around until after it has done the multiplication.)
In the preceding example, it probably doesn't matter which variable is incremented first. It's not too hard, though, to write an expression where it does matter. In fact, we've seen one already: the ambiguous assignment a[i++] = b[i++]. We still don't know which i++ happens first. (We can not assume, based on the right-to-left behavior of the = operator, that the right-hand i++ will happen first.) But if we had to know what a[i++] = b[i++] really did, we'd have to know which i++ happened first.

Finally, note that parentheses don't dictate overall evaluation order any more than precedence does. Parentheses override precedence and say which operands go with which operators, and they therefore affect the overall meaning of an expression, but they don't say anything about the order of subexpressions or side effects. We could not ``fix'' the evaluation order of any of the expressions we've been discussing by adding parentheses. If we wrote

i++ + (j++ * k++)
we still wouldn't know which of the increments would happen first. (The parentheses would force the multiplication to happen before the addition, but precedence already would have forced that, anyway.) If we wrote
(i++) * (i++)
the parentheses wouldn't force the increments to happen before the multiplication or in any well-defined order; this parenthesized version would be just as undefined as i++ * i++ was.
There's a line from Kernighan & Ritchie, which I am fond of quoting when discussing these issues [Sec. 2.12, p. 54]:

The moral is that writing code that depends on order of evaluation is a bad programming practice in any language. Naturally, it is necessary to know what things to avoid, but if you don't know how they are done on various machines, you won't be tempted to take advantage of a particular implementation.
The first edition of K&R said

...if you don't know how they are done on various machines, that innocence may help to protect you.
I actually prefer the first edition wording. Many textbooks encourage you to write small programs to find out how your compiler implements some of these ambiguous expressions, but it's just one step from writing a small program to find out, to writing a real program which makes use of what you've just learned. But you don't want to write programs that work only under one particular compiler, that take advantage of the way that one compiler (but perhaps no other) happens to implement the undefined expressions. It's fine to be curious about what goes on ``under the hood,'' and many of you will be curious enough about what's going on with these ``forbidden'' expressions that you'll want to investigate them, but please keep very firmly in mind that, for real programs, the very easiest way of dealing with ambiguous, undefined expressions (which one compiler interprets one way and another interprets another way and a third crashes on) is not to write them in the first place.

7.2 Increment and Decrement Operators


7.2 Increment and Decrement Operators

[This section corresponds to K&R Sec. 2.8]

The assignment operators of the previous section let us replace v = v op e with v op= e, so that we didn't have to mention v twice. In the most common cases, namely when we're adding or subtracting the constant 1 (that is, when op is + or - and e is 1), C provides another set of shortcuts: the autoincrement and autodecrement operators. In their simplest forms, they look like this:

++i add 1 to i
--j subtract 1 from j
These correspond to the slightly longer i += 1 and j -= 1, respectively, and also to the fully ``longhand'' forms i = i + 1 and j = j - 1.
The ++ and -- operators apply to one operand (they're unary operators). The expression ++i adds 1 to i, and stores the incremented result back in i. This means that these operators don't just compute new values; they also modify the value of some variable. (They share this property--modifying some variable--with the assignment operators; we can say that these operators all have side effects. That is, they have some effect, on the side, other than just computing a new value.)

The incremented (or decremented) result is also made available to the rest of the expression, so an expression like

k = 2 * ++i
means ``add one to i, store the result back in i, multiply it by 2, and store that result in k.'' (This is a pretty meaningless expression; our actual uses of ++ later will make more sense.)
Both the ++ and -- operators have an unusual property: they can be used in two ways, depending on whether they are written to the left or the right of the variable they're operating on. In either case, they increment or decrement the variable they're operating on; the difference concerns whether it's the old or the new value that's ``returned'' to the surrounding expression. The prefix form ++i increments i and returns the incremented value. The postfix form i++ increments i, but returns the prior, non-incremented value. Rewriting our previous example slightly, the expression

k = 2 * i++
means ``take i's old value and multiply it by 2, increment i, store the result of the multiplication in k.''
The distinction between the prefix and postfix forms of ++ and -- will probably seem strained at first, but it will make more sense once we begin using these operators in more realistic situations.

For example, our getline function of the previous chapter used the statements

line[nch] = c;
nch = nch + 1;
as the body of its inner loop. Using the ++ operator, we could simplify this to
line[nch++] = c;
We wanted to increment nch after deciding which element of the line array to store into, so the postfix form nch++ is appropriate.
Notice that it only makes sense to apply the ++ and -- operators to variables (or to other ``containers,'' such as a[i]). It would be meaningless to say something like

1++
or
(2+3)++
The ++ operator doesn't just mean ``add one''; it means ``add one to a variable'' or ``make a variable's value one more than it was before.'' But (1+2) is not a variable, it's an expression; so there's no place for ++ to store the incremented result.
Another unfortunate example is

i = i++;
which some confused programmers sometimes write, presumably because they want to be extra sure that i is incremented by 1. But i++ all by itself is sufficient to increment i by 1; the extra (explicit) assignment to i is unnecessary and in fact counterproductive, meaningless, and incorrect. If you want to increment i (that is, add one to it, and store the result back in i), either use
i = i + 1;
or
i += 1;
or
++i;
or
i++;
Don't try to use some bizarre combination.
Did it matter whether we used ++i or i++ in this last example? Remember, the difference between the two forms is what value (either the old or the new) is passed on to the surrounding expression. If there is no surrounding expression, if the ++i or i++ appears all by itself, to increment i and do nothing else, you can use either form; it makes no difference. (Two ways that an expression can appear ``all by itself,'' with ``no surrounding expression,'' are when it is an expression statement terminated by a semicolon, as above, or when it is one of the controlling expressions of a for loop.) For example, both the loops

for(i = 0; i < 10; ++i)
printf("%d\n", i);
and
for(i = 0; i < 10; i++)
printf("%d\n", i);
will behave exactly the same way and produce exactly the same results. (In real code, postfix increment is probably more common, though prefix definitely has its uses, too.)
In the preceding section, we simplified the expression

a[d1 + d2] = a[d1 + d2] + 1;
from a previous chapter down to
a[d1 + d2] += 1;
Using ++, we could simplify it still further to
a[d1 + d2]++;
or
++a[d1 + d2];
(Again, in this case, both are equivalent.)
We'll see more examples of these operators in the next section and in the next chapter.

7.1 Assignment Operators


7.1 Assignment Operators

[This section corresponds to K&R Sec. 2.10]

The first and more general way is that any time you have the pattern

v = v op e
where v is any variable (or anything like a[i]), op is any of the binary arithmetic operators we've seen so far, and e is any expression, you can replace it with the simplified
v op= e
For example, you can replace the expressions
i = i + 1
j = j - 10
k = k * (n + 1)
a[i] = a[i] / b
with
i += 1
j -= 10
k *= n + 1
a[i] /= b
In an example in a previous chapter, we used the assignment

a[d1 + d2] = a[d1 + d2] + 1;
to count the rolls of a pair of dice. Using +=, we could simplify this expression to
a[d1 + d2] += 1;
As these examples show, you can use the ``op='' form with any of the arithmetic operators (and with several other operators that we haven't seen yet). The expression, e, does not have to be the constant 1; it can be any expression. You don't always need as many explicit parentheses when using the op= operators: the expression

k *= n + 1
is interpreted as
k = k * (n + 1)

Chapter 7: More Operators


Chapter 7: More Operators

In this chapter we'll meet some (though still not all) of C's more advanced arithmetic operators. The ones we'll meet here have to do with making common patterns of operations easier.

It's extremely common in programming to have to increment a variable by 1, that is, to add 1 to it. (For example, if you're processing each element of an array, you'll typically write a loop with an index or pointer variable stepping through the elements of the array, and you'll increment the variable each time through the loop.) The classic way to increment a variable is with an assignment like

i = i + 1
Such an assignment is perfectly common and acceptable, but it has a few slight problems:
As we've mentioned, it looks a little odd, especially from an algebraic perspective.
If the object being incremented is not a simple variable, the idiom can become cumbersome to type, and correspondingly more error-prone. For example, the expression
a[i+j+2*k] = a[i+j+2*k] + 1
is a bit of a mess, and you may have to look closely to see that the similar-looking expression
a[i+j+2*k] = a[i+j+2+k] + 1
probably has a mistake in it.
Since incrementing things is so common, it might be nice to have an easier way of doing it.
In fact, C provides not one but two other, simpler ways of incrementing variables and performing other similar operations.

7.1 Assignment Operators

7.2 Increment and Decrement Operators

7.3 Order of Evaluation

6.4 Reading Numbers


6.4 Reading Numbers

The getline function of the previous section reads one line from the user, as a string. What if we want to read a number? One straightforward way is to read a string as before, and then immediately convert the string to a number. The standard C library contains a number of functions for doing this. The simplest to use are atoi(), which converts a string to an integer, and atof(), which converts a string to a floating-point number. (Both of these functions are declared in the header <stdlib.h>, so you should #include that header at the top of any file using these functions.) You could read an integer from the user like this:

#include <stdlib.h>

char line[256];
int n;
printf("Type an integer:\n");
getline(line, 256);
n = atoi(line);
Now the variable n contains the number typed by the user. (This assumes that the user did type a valid number, and that getline did not return EOF.)
Reading a floating-point number is similar:

#include <stdlib.h>

char line[256];
double x;
printf("Type a floating-point number:\n");
getline(line, 256);
x = atof(line);
(atof is actually declared as returning type double, but you could also use it with a variable of type float, because in general, C automatically converts between float and double as needed.)
Another way of reading in numbers, which you're likely to see in other books on C, involves the scanf function, but it has several problems, so we won't discuss it for now. (Superficially, scanf seems simple enough, which is why it's often used, especially in textbooks. The trouble is that to perform input reliably using scanf is not nearly as easy as it looks, especially when you're not sure what the user is going to type.)

6.3 Reading Lines


6.3 Reading Lines

It's often convenient for a program to process its input not a character at a time but rather a line at a time, that is, to read an entire line of input and then act on it all at once. The standard C library has a couple of functions for reading lines, but they have a few awkward features, so we're going to learn more about character input (and about writing functions in general) by writing our own function to read one line. Here it is:

#include <stdio.h>

/* Read one line from standard input, */
/* copying it to line array (but no more than max chars). */
/* Does not place terminating \n in line array. */
/* Returns line length, or 0 for empty line, or EOF for end-of-file. */

int getline(char line[], int max)
{
int nch = 0;
int c;
max = max - 1; /* leave room for '\0' */

while((c = getchar()) != EOF)
{
if(c == '\n')
break;

if(nch < max)
{
line[nch] = c;
nch = nch + 1;
}
}

if(c == EOF && nch == 0)
return EOF;

line[nch] = '\0';
return nch;
}
As the comment indicates, this function will read one line of input from the standard input, placing it into the line array. The size of the line array is given by the max argument; the function will never write more than max characters into line.

The main body of the function is a getchar loop, much as we used in the character-copying program. In the body of this loop, however, we're storing the characters in an array (rather than immediately printing them out). Also, we're only reading one line of characters, then stopping and returning.

There are several new things to notice here.

First of all, the getline function accepts an array as a parameter. As we've said, array parameters are an exception to the rule that functions receive copies of their arguments--in the case of arrays, the function does have access to the actual array passed by the caller, and can modify it. Since the function is accessing the caller's array, not creating a new one to hold a copy, the function does not have to declare the argument array's size; it's set by the caller. (Thus, the brackets in ``char line[]'' are empty.) However, so that we won't overflow the caller's array by reading too long a line into it, we allow the caller to pass along the size of the array, which we promise not to exceed.

Second, we see an example of the break statement. The top of the loop looks like our earlier character-copying loop--it stops when it reaches EOF--but we only want this loop to read one line, so we also stop (that is, break out of the loop) when we see the \n character signifying end-of-line. An equivalent loop, without the break statement, would be

while((c = getchar()) != EOF && c != '\n')
{
if(nch < max)
{
line[nch] = c;
nch = nch + 1;
}
}
We haven't learned about the internal representation of strings yet, but it turns out that strings in C are simply arrays of characters, which is why we are reading the line into an array of characters. The end of a string is marked by the special character, '\0'. To make sure that there's always room for that character, on our way in we subtract 1 from max, the argument that tells us how many characters we may place in the line array. When we're done reading the line, we store the end-of-string character '\0' at the end of the string we've just built in the line array.

Finally, there's one subtlety in the code which isn't too important for our purposes now but which you may wonder about: it's arranged to handle the possibility that a few characters (i.e. the apparent beginning of a line) are read, followed immediately by an EOF, without the usual \n end-of-line character. (That's why we return EOF only if we received EOF and we hadn't read any characters first.)

In any case, the function returns the length (number of characters) of the line it read, not including the \n. (Therefore, it returns 0 for an empty line.) Like getchar, it returns EOF when there are no more lines to read. (It happens that EOF is a negative number, so it will never match the length of a line that getline has read.)

Here is an example of a test program which calls getline, reading the input a line at a time and then printing each line back out:

#include <stdio.h>

extern int getline(char [], int);

main()
{
char line[256];

while(getline(line, 256) != EOF)
printf("you typed \"%s\"\n", line);

return 0;
}
The notation char [] in the function prototype for getline says that getline accepts as its first argument an array of char. When the program calls getline, it is careful to pass along the actual size of the array. (You might notice a potential problem: since the number 256 appears in two places, if we ever decide that 256 is too small, and that we want to be able to read longer lines, we could easily change one of the instances of 256, and forget to change the other one. Later we'll learn ways of solving--that is, avoiding--this sort of problem.)

6.2 Character Input and Output


6.2 Character Input and Output

[This section corresponds to K&R Sec. 1.5]

Unless a program can read some input, it's hard to keep it from doing exactly the same thing every time it's run, and thus being rather boring after a while.

The most basic way of reading input is by calling the function getchar. getchar reads one character from the ``standard input,'' which is usually the user's keyboard, but which can sometimes be redirected by the operating system. getchar returns (rather obviously) the character it reads, or, if there are no more characters available, the special value EOF (``end of file'').

A companion function is putchar, which writes one character to the ``standard output.'' (The standard output is, again not surprisingly, usually the user's screen, although it, too, can be redirected. printf, like putchar, prints to the standard output; in fact, you can imagine that printf calls putchar to actually print each of the characters it formats.)

Using these two functions, we can write a very basic program to copy the input, a character at a time, to the output:

#include <stdio.h>

/* copy input to output */

main()
{
int c;

c = getchar();

while(c != EOF)
{
putchar(c);
c = getchar();
}

return 0;
}
This code is straightforward, and I encourage you to type it in and try it out. It reads one character, and if it is not the EOF code, enters a while loop, printing one character and reading another, as long as the character read is not EOF. This is a straightforward loop, although there's one mystery surrounding the declaration of the variable c: if it holds characters, why is it an int?

We said that a char variable could hold integers corresponding to character set values, and that an int could hold integers of more arbitrary values (up to +-32767). Since most character sets contain a few hundred characters (nowhere near 32767), an int variable can in general comfortably hold all char values, and then some. Therefore, there's nothing wrong with declaring c as an int. But in fact, it's important to do so, because getchar can return every character value, plus that special, non-character value EOF, indicating that there are no more characters. Type char is only guaranteed to be able to hold all the character values; it is not guaranteed to be able to hold this ``no more characters'' value without possibly mixing it up with some actual character value. (It's like trying to cram five pounds of books into a four-pound box, or 13 eggs into a carton that holds a dozen.) Therefore, you should always remember to use an int for anything you assign getchar's return value to.

When you run the character copying program, and it begins copying its input (your typing) to its output (your screen), you may find yourself wondering how to stop it. It stops when it receives end-of-file (EOF), but how do you send EOF? The answer depends on what kind of computer you're using. On Unix and Unix-related systems, it's almost always control-D. On MS-DOS machines, it's control-Z followed by the RETURN key. Under Think C on the Macintosh, it's control-D, just like Unix. On other systems, you may have to do some research to learn how to send EOF.

(Note, too, that the character you type to generate an end-of-file condition from the keyboard is not the same as the special EOF value returned by getchar. The EOF value returned by getchar is a code indicating that the input system has detected an end-of-file condition, whether it's reading the keyboard or a file or a magnetic tape or a network connection or anything else. In a disk file, at least, there is not likely to be any character in the file corresponding to EOF; as far as your program is concerned, EOF indicates the absence of any more characters to read.)

Another excellent thing to know when doing any kind of programming is how to terminate a runaway program. If a program is running forever waiting for input, you can usually stop it by sending it an end-of-file, as above, but if it's running forever not waiting for something, you'll have to take more drastic measures. Under Unix, control-C (or, occasionally, the DELETE key) will terminate the current program, almost no matter what. Under MS-DOS, control-C or control-BREAK will sometimes terminate the current program, but by default MS-DOS only checks for control-C when it's looking for input, so an infinite loop can be unkillable. There's a DOS command,

break on
which tells DOS to look for control-C more often, and I recommend using this command if you're doing any programming. (If a program is in a really tight infinite loop under MS-DOS, there can be no way of killing it short of rebooting.) On the Mac, try command-period or command-option-ESCAPE.
Finally, don't be disappointed (as I was) the first time you run the character copying program. You'll type a character, and see it on the screen right away, and assume it's your program working, but it's only your computer echoing every key you type, as it always does. When you hit RETURN, a full line of characters is made available to your program. It then zips several times through its loop, reading and printing all the characters in the line in quick succession. In other words, when you run this program, it will probably seem to copy the input a line at a time, rather than a character at a time. You may wonder how a program could instead read a character right away, without waiting for the user to hit RETURN. That's an excellent question, but unfortunately the answer is rather complicated, and beyond the scope of our discussion here. (Among other things, how to read a character right away is one of the things that's not defined by the C language, and it's not defined by any of the standard library functions, either. How to do it depends on which operating system you're using.)

Stylistically, the character-copying program above can be said to have one minor flaw: it contains two calls to getchar, one which reads the first character and one which reads (by virtue of the fact that it's in the body of the loop) all the other characters. This seems inelegant and perhaps unnecessary, and it can also be risky: if there were more things going on within the loop, and if we ever changed the way we read characters, it would be easy to change one of the getchar calls but forget to change the other one. Is there a way to rewrite the loop so that there is only one call to getchar, responsible for reading all the characters? Is there a way to read a character, test it for EOF, and assign it to the variable c, all at the same time?

There is. It relies on the fact that the assignment operator, =, is just another operator in C. An assignment is not (necessarily) a standalone statement; it is an expression, and it has a value (the value that's assigned to the variable on the left-hand side), and it can therefore participate in a larger, surrounding expression. Therefore, most C programmers would write the character-copying loop like this:

while((c = getchar()) != EOF)
putchar(c);
What does this mean? The function getchar is called, as before, and its return value is assigned to the variable c. Then the value is immediately compared against the value EOF. Finally, the true/false value of the comparison controls the while loop: as long as the value is not EOF, the loop continues executing, but as soon as an EOF is received, no more trips through the loop are taken, and it exits. The net result is that the call to getchar happens inside the test at the top of the while loop, and doesn't have to be repeated before the loop and within the loop (more on this in a bit).
Stated another way, the syntax of a while loop is always

while( expression ) ...
A comparison (using the != operator) is of course an expression; the syntax is
expression != expression
And an assignment is an expression; the syntax is
expression = expression
What we're seeing is just another example of the fact that expressions can be combined with essentially limitless generality and therefore infinite variety. The left-hand side of the != operator (its first expression) is the (sub)expression c = getchar(), and the combined expression is the expression needed by the while loop.
The extra parentheses around

(c = getchar())
are important, and are there because because the precedence of the != operator is higher than that of the = operator. If we (incorrectly) wrote
while(c = getchar() != EOF) /* WRONG */
the compiler would interpret it as
while(c = (getchar() != EOF))
That is, it would assign the result of the != operator to the variable c, which is not what we want.
(``Precedence'' refers to the rules for which operators are applied to their operands in which order, that is, to the rules controlling the default grouping of expressions and subexpressions. For example, the multiplication operator * has higher precedence than the addition operator +, which means that the expression a + b * c is parsed as a + (b * c). We'll have more to say about precedence later.)

The line

while((c = getchar()) != EOF)
epitomizes the cryptic brevity which C is notorious for. You may find this terseness infuriating (and you're not alone!), and it can certainly be carried too far, but bear with me for a moment while I defend it.
The simple example we've been discussing illustrates the tradeoffs well. We have four things to do:

call getchar,
assign its return value to a variable,
test the return value against EOF, and
process the character (in this case, print it out again).
We can't eliminate any of these steps. We have to assign getchar's value to a variable (we can't just use it directly) because we have to do two different things with it (test, and print). Therefore, compressing the assignment and test into the same line is the only good way of avoiding two distinct calls to getchar. You may not agree that the compressed idiom is better for being more compact or easier to read, but the fact that there is now only one call to getchar is a real virtue.
Don't think that you'll have to write compressed lines like

while((c = getchar()) != EOF)
right away, or in order to be an ``expert C programmer.'' But, for better or worse, most experienced C programmers do like to use these idioms (whether they're justified or not), so you'll need to be able to at least recognize and understand them when you're reading other peoples' code.

Twitter Delicious Facebook Digg Stumbleupon Favorites More