C programing
编译器是把高级语言程序翻译成计算机能理
解的机器语言指令集的程序。
不同CPU制造商使用的指令系统和编
码格式不同。
使用合适的编译器或编译器集,便可把一种高级
语言程序转换成供各种不同类型 CPU 使用的机器语言程序。
ANSI/ISO标准的最终版本通常叫作C89(因为ANSI于1989年批准该标
准)或C90(因为ISO于1990年批准该标准)
ISO C和ANSI C是完全相同的
标准。
1994年,ANSI/ISO联合委员会(C9X委员会)开始修订C标准,最终发
布了C99标准。
2011年终于发布了C11标准
本书使用术语ANSI C、ISO C或ANSI/ISO C讲解C89/90和较新标准共有
的特性,用C99或C11介绍新的特性。
编译器是把源代码转换成可执行代码的程序。可执行代码
是用计算机的机器语言表示的代码。这种语言由数字码表示的指令组成。如
前所述,不同的计算机使用不同的机器语言方案。C 编译器负责把C代码翻
译成特定的机器语言。此外,C编译器还将源代码与C库(库中包含大量的
标准函数供用户使用,如printf()和scanf())的代码合并成最终的程序(更精
确地说,应该是由一个被称为链接器的程序来链接库函数,但是在大多数系
统中,编译器运行链接器)。其结果是,生成一个用户可以运行的可执行文
件,其中包含着计算机能理解的代码。
用C语言编写程序时,编写的内容被储存在文本文件中,该文件被称为
源代码文件(source code file)。大部分C系统,包括之前提到的,都要求文
件名以.c结尾(如,wordcount.c和budget.c)。
编译器把源代码转换成中间代码,链接器把中间代码和其他
代码合并,生成可执行文件。C 使用这种分而治之的方法方便对程序进行模
块化,可以独立编译单独的模块,稍后再用链接器合并已编译的模块。通过
这种方式,如果只更改某个模块,不必因此重新编译其他模块。另外,链接
器还将你编写的程序和预编译的库代码合并。
中间文件有多种形式。把源
代码转换为机器语言代码,并把结果放在目标代码文件(或简称目标文件)
目标代码文件缺失启动代码(startup code)。启动代码充当着程序和操
作系统之间的接口。例如,可以在MS Windows或Linux系统下运行IBM PC兼
容机。这两种情况所使用的硬件相同,所以目标代码相同,但是Windows和
Linux所需的启动代码不同,因为这些系统处理程序的方式不同。
目标代码还缺少库函数。
printf()函数真正的代码储存
在另一个被称为库的文件中。库文件中有许多函数的目标代码。
链接器的作用是,把你编写的目标代码、系统的标准启动代码和库代码
这 3 部分合并成一个文件,即可执行文件。
GNU项目始于1987年,是一个开发大量免费UNIX软件的集合
GNU编译器集合(也被称
为GCC,其中包含GCC C编译器)是该项目的产品之一
GCC有
各种版本以适应不同的硬件平台和操作系统,包括UNIX、Linux和
Windows。
用gcc命令便可调用GCC C编译器。许多使用gcc的系统都用cc作
为gcc的别名。
下载Cygwin和MinGW,这样便可在PC上通
过命令行使用GCC编译器。Cygwin在自己的视窗运行,模仿Linux命令行环
境,有一行命令提示。MinGW在Windows的命令提示模式中运行。
源代码文件应该是文本文件
Microsoft Visual Studio
在新建
项目时,选择C++选项,然后选择【Win32控制台应用程序】,在应用设置
中选择【空项目】。
introducing C
a simple example of C
1 |
|
getchar();
This code causes the program to wait for a keystroke, so the window remains open until you
press a key.
the example explained
The effect of #include <stdio.h>
is the same as
if you had typed the entire contents of the stdio.h file into your file at the point where the
#include
line appears
The #include statement is an example of a C preprocessor directive. In general, C compilers
perform some preparatory work on source code before compiling; this is termed preprocessing .
The stdio.h file is supplied as part of all C compiler packages. It contains information about
input and output functions, such as printf(), for the compiler to use. The name stands for
standard input/output header
define constants or indicate the names of functions
and how they should be used. But the actual code for a function is in a library file of precompiled code, not in a header file
A C program always begins execution with the function called main().
functions are the basic modules of a C program
The parts of the program enclosed in the /**/ symbols are comments.
C99 added a second style of comments, one popularized by C++ and Java. The new style uses
the symbols // to create comments that are confined to a single line:
// Here is a comment confined to one line.
int rigue; // Such comments can go here, too.
int num;
This line from the program is termed a declaration statement.
This particular example declares two things. First, somewhere in
the function, you have a variable called num. Second, the int proclaims num as an integer
The semicolon at the end of the line identifies the line as a C statement or instruction. The
semicolon is part of the statement
int
Keywords are the words
used to express a language, and you can’t use them for other purposes. For instance, you can’t
use int as the name of a function or a variable.
The word num in this example is an identifier—that is, a name you select for a variable, a function, or some other entity.
the declaration connects a particular identifier with a particular
location in computer memory, and it also establishes the type of information, or data type, to
be stored at that location.
all variables must be declared before they are used. This means that you have to provide
lists of all the variables you use in a program and that you have to show which data type each
variable is.
C99 and C11, following the practice of C++, let you place declarations about anywhere in
a block. However, you still must declare a variable before its first use.
Declaring a variable to be an integer or a character type makes it possible for the
computer to store, fetch, and interpret the data properly
name choice
The characters at your disposal are lowercase letters, uppercase letters, digits, and the underscore ( _). The first character must be a letter or an underscore.
Operating systems and the C library often use identifiers with one or two initial underscore
characters, such as in _kcab, so it is better to avoid that usage yourself.
C names are case sensitive, meaning an uppercase letter is considered distinct from the corresponding lowercase letter. Therefore, stars is different from Stars and STARS .
Four Good Reasons to Declare Variables
Declaring variables helps prevent one of programming’s more subtle and hard-to-find
bugs—that of the misspelled variable name.
RADIUS1 = 20.4;
and that elsewhere in the program you mistyped
CIRCUM = 6.28 * RADIUSl;
the compiler will
complain when the undeclared RADIUSl shows up.
C
prior to C99 required that the declarations go at the beginning of a block.
Assignment
num = 1;
You can assign num a different value later, if you want; that is why num is termed a
variable.
The printf() Function
actual argument
of a function
C uses the terms actual argument and formal
argument to distinguish between a specific value sent to a function and a variable in the function used to hold the value
The \n symbol means to start a new line
when you press the Enter key, the editor quits the current line on
which you are working and starts a new one. The newline character, however, affects how the
output of the program is displayed.
an escape sequence. An escape sequence is used to
represent difficult- or impossible-to-type characters.
e \t for Tab and \b
for Backspace
The %d is a placeholder to show where the value of num is to be
printed. This line is similar to the following BASIC statement:
PRINT “My favorite number is “; num; “ because it is first.”
the d tells it to print the variable as a decimal (base 10)
integer.
the f in
printf() is a reminder that this is a formatting print function.
Each type of data has its own
specifier
the structure of a simple program
A program consists of a collection of one or more functions, one of which must be
called main().
The description of a function consists of a header and a body. The function header
contains the function name along with information about the type of information passed to
the function and returned by the function.
The body is enclosed by braces ( {}) and consists of a series of
statements, each terminated by a semicolon
a simple standard C program should use the following format:
1 |
|
tips on making programs readable
Choose meaningful variable
names and use comments.
using blank lines to separate one conceptual section of a function from another.
use one line per statement
1 | int main(void) /* converts 2 fathoms to feet */ /* use comments */ |
taking another step in using C
1 | // fathm_ft.c -- converts 2 fathoms to feet |
declares two variables instead of just one in a single declaration statement.
int feet, fathoms;
and
int feet;
int fathoms;
are equivalent
feet = 6 * fathoms;
means “look up the value of the variable fathoms, multiply it by 6, and assign the result of this
calculation to the variable feet .”
printing ultiple values
printf("There are %d feet in %d fathoms!\n", feet, fathoms);
printf("Yes, I said %d feet!\n", 6 * fathoms);
the value printed doesn’t have to be a variable; it
just has to be something, such as 6 * fathoms, that reduces to a value of the right type.
multiple functions
1 | //* two_func.c -- a program using two functions in one file */ |
I will summon the butler function.
You rang, sir?
Yes. Bring me some tea and writeable DVDs.
The C90 standard added prototypes, and older compilers might not recognize them
A prototype declares to the compiler
that you are using a particular function, so it’s called a function declaration.
It also specifies
properties of the function.
The C standard recommends that you provide function prototypes for all functions you
use.
The standard include files take care of this task for the standard library functions. For
example, under standard C, the stdio.h file has a function prototype for printf().
void is used to mean “empty,” not “invalid.”
Older C supported a more limited form of function declaration in which you just specified the
return type but omitted describing the arguments:
void butler();
all C programs begin execution with
main(), no matter where main() is located in the program files.
the usual C practice
is to list main() first because it normally provides the basic framework for a program.
introducing debugging
1 | /* nogood.c -- a program with errors */ |
syntax errors
C syntax errors use
valid C symbols in the wrong places.
the compiler can get confused. A true syntax error in one location might cause the
compiler to mistakenly think it has found other errors.
Another common compiler trick is reporting the error a line late.
semantic errors
Semantic errors are errors in meaning.
g. In C, you commit a semantic error
when you follow the rules of C correctly but to an incorrect end.
One method
is to pretend you are the computer and to follow the program steps one by one.
program state
The program state is simply the set of values of all the variables at a given point
in program execution. It is a snapshot of the current state of computation.
Another approach to locating semantic problems is to sprinkle extra printf() statements
throughout to monitor the values of selected variables at key points in the program.
A debugger is a program
that enables you to run another program step-by-step and examine the value of that program’s
variables.
reserved identifiers, that you shouldn’t use
They
don’t cause syntax errors because they are valid names. However, the language already uses
them or reserves the right to use them, so it could cause problems if you use these identifiers to
mean something else. Reserved identifiers include those beginning with an underscore character and the names of the standard library functions, such as printf() .
data
1 |
|
scanf_s(“%f”, &weight);
Pressing Enter informs the computer that you have finished typing your response.
The scanf() function uses the &
notation to indicate where it can find the weight variable.
The scanf() and
printf() functions make this interactivity possible. The scanf() function reads data
from the keyboard and delivers that data to the program, and printf() reads data from
a program and delivers that data to your screen.
use that function call twice:
getchar();
getchar();
The getchar() function reads the next input character, so the program has to wait for input.
In this case, we provided input by typing 156 and then pressing the Enter (or Return) key, which
transmits a newline character. So scanf() reads the number, the first getchar() reads the
newline character, and the second getchar() causes the program to pause, awaiting further
input.
use the %f specifier in the printf() code to handle a
floating-point value. The .2 modifier to the %f specifier fine-tunes the appearance of the
output so that it displays two places to the right of the decimal.
data varialbes and constants
constants of various data types.
data, the numbers
and characters that bear the information you use
Some types of data are preset before a
program is used and keep their values unchanged throughout the life of the program. These are
constants.
Other types of data may change or be assigned values as the program runs; these are
variables.
The difference between a variable and a constant is that a variable can have its value
assigned or changed while the program is running, and a constant can’t.
14.5833
is a constant.1700.0
? True, the price of platinum isn’t a constant in real life, but this program treats it as a constant
data type keywords
Original K&R Keywords | C90 K&R Keywords | C99 Keywords |
---|---|---|
int | signed | _Bool |
long | void | _Complex |
short | _Imaginary | |
unsigned | ||
char | ||
float | ||
double |
If a datum is a constant, the compiler can usually tell its type
just by the way it looks: 42 is an integer, and 42.100 is floating point.
A variable, however,
needs to have its type announced in a declaration statement.
The int keyword provides the basic class of integers used in C. The next three keywords ( long ,
short, and unsigned) and the C90 addition signed are used to provide variations of the
basic type, for example, unsigned short int and long long int.
the char keyword designates the type used for letters of the alphabet and for other characters, such as #, $, %, and
*. The char type also can be used to represent small integers.
float, double, and the
combination long double are used to represent numbers with decimal points.
The _Bool type
is for Boolean values ( true and false)
_Complex and _Imaginary represent complex and imaginary numbers, respectively.
two families on the basis of how
they are stored in the computer: integer types and floating-point types.
For a computer, the difference is reflected in the way they are stored.
The smallest unit of memory is called a bit. It can hold one of two values: 0 or 1.
The bit is the basic building block of computer memory.
The byte is the usual unit of computer memory. For nearly all machines, a byte is 8 bits, and that is the standard definition, at least when used to measure storage.
Because each bit can be either 0 or 1, there are 256 (that’s 2 times
itself 8 times) possible bit patterns
. These patterns
can be used, for example, to represent the integers from 0 to 255 or to represent a set of
characters.
A word is the natural unit of memory for a given computer design.
For 8-bit microcomputers,
such as the original Apples, a word is just 8 bits. personal computers moved up to
16-bit words, 32-bit words, and, at the present, 64-bit words. Larger word sizes enable faster
transfer of data and allow more memory to be accessed.
integer
Integers are stored as binary numbers.
The integer 7, for example, is written 111 in binary.
Therefore, to store this number in an 8-bit byte, just set the first 5 bits to 0 and the last 3 bits
to 1
floating point number
adding a decimal point makes a value a floating-point
value
7 is an integer type but 7.00 is a floating-point type.
e-notation3.16E7
means to multiply 3.16 by 10 to the 7th power
Floating-point representation involves breaking up a number
into a fractional part and an exponent part and storing the parts separately.
7.00
The decimal analogy would be to write 7.0 as 0.7E1. Here, 0.7 is the fractional part, and the 1 is the exponent part.
A computer, of course, would use binary numbers and powers of two instead of powers
of 10 for internal storage.
Floating-point numbers can represent a much larger range of values than integers can
Because there is an infinite number of real numbers in any range—for example, in the
range between 1.0 and 2.0—computer floating-point numbers can’t represent all the
values in the range. Instead, floating-point values are often approximations of a true
value. For example, 7.0 might be stored as a 6.99999 float value
Floating-point operations were once much slower than integer operations
basic c data types
represent a constant with a literal value
the int type
C gives the programmer the option of matching a type to a particular use.
C integer types vary in the range of values offered and in whether negative numbers can be
used.
The int type is a signed integer. That means it must be an integer and it can be positive, negative, or zero.
Typically, systems represent signed integers by using the value of a particular bit to indicate the
sign.
The range in possible values depends on the computer system. Typically, an int
uses one machine word for storage.
16 bits to store an int. This allows a range in values from –32768 to 32767.
ISO C specifies that the minimum range for type int should be from –32767 to 32767 .
Declaring an int Variable
int erns;
int hogs, cows, goats;
Initializing a Variable
To initialize a variable means to assign it a starting, or initial, value.
this can be done as
part of the declaration. Just follow the variable name with the assignment operator ( =) and the
value you want the variable to have
1 | int hogs = 21; |
type int cosntans
The various integers ( 21, 32, 14, and 94) in the last example are integer constants, also called
integer literals. When you write a number without a decimal point and without an exponent, C
recognizes it as an integer
C treats most integer constants as type int. Very large integers can be treated differently;
Printing int Values
The %d is called a format
specifier because it indicates the form that printf() uses to display a value.
Each %d in the
format string must be matched by a corresponding int value in the list of items to be printed.
That value can be an int variable, an int constant, or any other expression having an int
value.
check to see that the number of format specifiers you give to printf() matches the number of
values to be displayed.
1 |
|
10 minus 2 is 8
10 minus -641 is -470812528
Most functions take a specific number of arguments, and the
compiler can check to see whether you’ve used the correct number
printf() can
have one, two, three, or more arguments, and that keeps the compiler from using its usual
methods for error checking
Octal and Hexadecimal
C assumes that integer constants are decimal, or base 10, numbers. However, octal
(base 8) and hexadecimal (base 16) numbers are popular with many programmers.
Because 8
and 16 are powers of 2, and 10 is not, these number systems occasionally offer a more convenient way for expressing computer-related values. For example, the number 65536, which often
pops up in 16-bit machines, is just 10000 in hexadecimal
Also, each digit in a hexadecimal
number corresponds to exactly 4 bits. For example, the hexadecimal digit 3 is 0011 and the
hexadecimal digit 5 is 0101. So the hexadecimal value 35 is the bit pattern 0011 0101, and the
hexadecimal value 53 is 0101 0011. This correspondence makes it easy to go back and forth
between hexadecimal and binary (base 2) notation
In C, special prefixes indicate
which number base you are using. A prefix of 0x or 0X (zero-ex) means that you are specifying
a hexadecimal value, so 16 is written as 0x10, or 0X10, in hexadecimal. Similarly, a 0 (zero)
prefix means that you are writing in octal. For example, the decimal value 16 is written as 020
in octal.
Be aware that this option of using different number systems is provided as a service for your
convenience. It doesn’t affect how the number is stored
Displaying Octal and Hexadecimal
To display an integer in octal notation
instead of decimal, use %o instead of %d. To display an integer in hexadecimal, use %x
If you
want to display the C prefixes, you can use specifiers %#o, %#x, and %#X to generate the 0, 0x ,
and 0X prefixes respectively.
1 |
|
dec = 100; octal = 144; hex = 64
dec = 100; octal = 0144; hex = 0X64
other integer types
The type short int
or, more briefly, short may use less storage than int, thus saving
space when only small numbers are needed. Like int, short is a signed type.
The type long int
, or long, may use more storage than int, thus enabling you to
express larger integer values. Like int, long is a signed type.
The type long long int
, or long long (introduced in the C99 standard), may use
more storage than long. At the minimum, it must use at least 64 bits. Like int, long
long is a signed type.
The type unsigned int, or unsigned, is used for variables that have only nonnegative
values.
The bit used to indicate the sign of signed numbers now becomes another binary digit,
allowing the larger number.This type shifts the range of numbers that can be stored. For example, a 16-bit
unsigned int allows a range from 0 to 65535 in value instead of from –32768 to 32767
The types unsigned long int, or unsigned long, and unsigned short int, or
unsigned short, are recognized as valid by the C90 standard. To this list, C99 adds
unsigned long long int, or unsigned long long .
The keyword signed can be used with any of the signed types to make your intent
explicit. For example, short, short int, signed short, and signed short int are all
names for the same type.
Declaring Other Integer Types
1 | long int estine; |
why multiple integer types
C guarantees only that short is no longer than int and that long is no shorter than int.
The
idea is to fit the types to the machine. For example, in the days of Windows 3, an int and a
short were both 16 bits, and a long was 32 bits. Later, Windows and Apple systems moved to
using 16 bits for short and 32 bits for int and long. Using 32 bits allows integers in excess of
2 billion. Now that 64-bit processors are common, there’s a need for 64-bit integers, and that’s
the motivation for the long long type.
The most common practice today on personal computers is to set up long long as 64 bits,
long as 32 bits, short as 16 bits, and int as either 16 bits or 32 bits, depending on the
machine’s natural word size.
The C standard provides guidelines specifying the minimum allowable size for each basic data
type.
The minimum range for both short and int is –32,767 to 32,767, corresponding to a
16-bit unit,
and the minimum range for long is –2,147,483,647 to 2,147,483,647, corresponding to a 32-bit unit.
For unsigned short and unsigned int, the minimum range is 0 to 65,535, and for
unsigned long, the minimum range is 0 to 4,294,967,295.
The long long type is intended
to support 64-bit needs. Its minimum range is a substantial –9,223,372,036,854,775,807
to 9,223,372,036,854,775,807,
and the minimum range for unsigned long long is 0 to
18,446,744,073,709,551,615.
: If you are writing code on
a machine for which int and long are the same size, and you do need 32-bit integers, you
should use long instead of int so that the program will function correctly if transferred to a
16-bit machine.
long constats and long long constants
Normally, when you use a number such as 2345 in your program code, it is stored as an int
type. What if you use a number such as 1000000 on a system in which int will not hold such
a large number? Then the compiler treats it as a long int, assuming that type is large enough.
If the number is larger than the long maximum, C treats it as unsigned long. If that is still
insufficient, C treats the value as long long or unsigned long long, if those types are
available.
To cause a small
constant to be treated as type long, you can append an l (lowercase L) or L as a suffix. The
second form is better because it looks less like the digit 1.
Therefore, a system with a 16-bit
int and a 32-bit long treats the integer 7 as 16 bits and the integer 7L as 32 bits
Similarly, on those systems supporting the long long type, you can use an ll or LL suffix to
indicate a long long value, as in 3LL. Add a u or U to the suffix for unsigned long long, as
in 5ull or 10LLU or 6LLU or 9Ull
Printing short, long, long long, and unsigned Types
Note
that although C allows both uppercase and lowercase letters for constant suffixes, these format
specifiers use just lowercase.
To print an unsigned int number, use the %u notation.
To print a long value, use the %ld
format specifier.
C has several additional printf() formats. First, you can use an h prefix for short types.
Therefore, %hd displays a short integer in decimal form,
Both the h and l prefixes can be used with u for unsigned types. For instance,
you would use the %lu notation for printing unsigned long types.
Systems supporting the long long types use %lld and %llu for the signed and
unsigned versions
1 |
|
un = 3000000000 and not -1294967296
end = 200 and 200
big = 65537 and not 1
verybig = 12345678908642 and not 1942899938