Chinaunix首页 | 论坛 | 博客
  • 博客访问: 271042
  • 博文数量: 101
  • 博客积分: 4245
  • 博客等级: 上校
  • 技术积分: 1085
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-24 00:28
文章分类

全部博文(101)

文章存档

2012年(1)

2011年(16)

2010年(34)

2009年(50)

我的朋友

分类: LINUX

2010-02-14 14:21:12

  1. 在Programming Mechanics章节中的Object Code Files, Executable Files, and Libraries
The first element missing from the object code file is something called startup code, which is code that acts as an interface between your program and the operating system. For example, you can run an IBM PC compatible under DOS or under Linux. The hardware is the same in either case, so the same object code would work with both, but you would need different startup code for DOS than you would for Linux because these systems handle programs differently from one another.这里的startup code理解不是很清楚,并且是第一次被提醒道!

  1. 最早的K&R C只定义了语言,而没有库函数的实现,称为Classic C, 到了ANSI/ISO C(也作C89/C90)不但update原来的K&R C,并且增加了standard C Library。1994年,制定了C99,update主要在于internationalization, correction of deficiencies, and improvement of computational usefulness。
  2. The stdio.h file is supplied as part of all C compiler packages.头文件一般来说是作为编译器包里面的组成部分。For the most part, header files contain information used by the compiler to build the final executable program. For example, they may 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. The linker component of the compiler takes care of finding the library code you need. In short, header files help guide the compiler in putting your program together correctly.
  3. ISO/ANSI C has standardized which header files must be supplied. Some programs need to include stdio.h, and some don't. The documentation for a particular C implementation should include a description of the functions in the C library. These function descriptions identify which header files are needed. For example, the description for printf() says to use stdio.h. Omitting the proper header file might not affect a particular program, but it is best not to rely on that. Each time this book uses library functions, it will use the include files specified by the ISO/ANSI standard for those functions.

  4. 关于主函数的写法: C90 standard grudgingly(极不情愿地) tolerated this form main( ),but the C99 
    standard doesn't. So even if your current compiler lets you do this, don't.
也就是说养成含习惯用main(void)这种形式。总结说来,
对于主函数的最好形式是:  
int main (void)

{

   ...................
    return 0;
}
  1. 关于注释:  /*             */  是通用的;而//这种形式在C99和C++里适用
  2. 几个容易混淆的词汇:braces { }parentheses ( )brackets [ ]semicolon;
backslash  \  comma是逗号 , decimal 10进制, octal 8进制, hexadecimal 16进制
punctuation 标点符号
  1. 变量名只能由字母,数字,下划线组成,并且开头只能是下划线或则是字母
  2. 关于变量名的字符长度:C99可以达到63个字符,但是如果是external identifiers 则只能是31字符.
C90则分别是31个字符和6个字符,对于那些老的C编译器,则只认前8个字符。
Actually, you can use more than the maximum number of characters, but the compiler won't pay
 attention to the extra characters.
  1. Therefore, on a system with an eight-character limit, shakespeare and
    shakespencil would be considered the same name because they have the
    same first eight characters. (If you want an example based on the 63-character limit, you'll have to concoct it yourself.)
  2. 操作系统和C库函数里面的变量名常常是以一个或者是两个下划线开头,所以在我们自己定义变量的时候最好就不要以下划线开头,以免在没意识到的情况下定义了和操作系统或者是C库函数相同名字的变量名。

  3. To make C more international, C99 makes an extensive set of characters available for use by the Universal Character Names (or UCN) mechanism. Reference , "," in discusses this addition.

  4. 在C99之前,变量声明必须在语句块的开始支出声明. 但是C99开始,就容许在仅仅马上需要使用变量之前声明它。但是现在部分编译器还是不支持C99这种新特性。
  5. 关于不同C版本对函数的规定:函数原型prototype是C90新增的,以前版本不认识,当函数不需要参数的时候,C90版本必须要用void作为参数,而老版本就不需要要void这个关键字,而是空起。
  6. 习惯上把主函数定义放在其它函数的定义之前,因为这样可以方便地了解这个程序的主要功能和框架。
  7. C语言中的关键字和保留字:黑体是C90加入的,斜体是C99加入的

ISO/ANSI C Keywords

auto

enum

restrict

unsigned

break

extern

return

void

case

float

short

volatile

char

for

signed

while

const

goto

sizeof

_Bool

continue

if

static

_Complex

default

inline

struct

_Imaginary

do

int

switch

 

double

long

typedef

 

else

register

union

 

1.K&C C有7个和数据类型相关的关键字,C90增加了2个,C99又增加了3个。 

C Data Keywords

Original K&R Keywords

C90 Keywords

C99 Keywords

int

signed

_Bool

long

void

_Complex

short

 

_Imaginary

unsigned

   

char

   

float

   

double

   




 

For some arithmetic operations, such as subtracting one large number from another, floating-point numbers are subject to greater loss of precision.

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—more about precision later.

Floating-point operations are normally slower than integer operations. However, microprocessors developed specifically to handle floating-point operations are now available, and they have closed the gap.

整数到底表示的范围是多少,不同字长的机器就有不同的范围,但是ISO/ANSI C规定了int表示的最小范围,也就是字长是16-bits的时候的范围,即:–32768 到 32767,

如果是遇到有符号整数,则必须要用一位来表示正或负,所以范围有变。


 Very large integers can be treated differently; see the later discussion of the long int type in the section "."

0x或0X开头代表16进制,0开头表示8进制

Just as C enables you write a number in any one of three number systems, it also enables you to display a number in any of these three systems. 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. shows a short example. (Recall that you may have to insert a getchar(); statement in the code for some IDEs to keep the program execution window from closing immediately.)

当整数溢出的时候,如果是无符号整数,则从0开始计数,这是C的规定,对于有符号整数,则没有具体规定,要视情况而定,只不过大多数情况下,是从最小的那个负数开始增加数值


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 print an unsigned int number, use the %u notation. To print a long value, use the %ld format specifier. If int and long are the same size on your system, just %d will suffice, but your program will not work properly when transferred to a system on which the two types are different, so use the %ld specifier for long. You can use the l prefix for x and o, too. Therefore, you would use %lx to print a long integer in hexadecimal format and %lo to print in octal format. Note that although C allows both uppercase and lowercase letters for constant suffixes, these format specifiers use just lowercase.

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, and %ho displays a short integer in octal 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. provides an example. Systems supporting the long long types use %lld and %llu for the signed and unsigned versions. provides a fuller discussion of format specifiers.

  1. 字符类型从本质上来说是整数类型,因为字符型变量在存储器里面是以整数来存储的,每个字符和某个整数是一一对应关系,注意一点就是:对于不同的机器,字符和数字的映射关系是不一样的。而并不都是ascii码表所示的对应关系,比如一些IBM的大型机就是用的EBCDIC表。所以在给字符变量赋值时,直接用字符是万无一失的做法。
  2.  
  3. 在对浮点数进行算数运算的时候,往往会得到一个奇怪的错误答案,比如用一个很大的浮点数,加1,然后再减去原来那个浮点数,结果并不是1.原因在与,计算机内存里面存储浮点数,只是用有限的几位来存储非指数部分,于是乎,加上1之后,也不能把那个1真正存到内存里面,。。。。。。

Arguments and Pitfalls

chapter4

sizeof是C语言的一种单目操作符,并不是函数。sizeof操作符以字节形式给出了其操作数的存储大小。

二、sizeof的使用方法

  1、用于数据类型

  sizeof使用形式:sizeof(type)

  数据类型必须用括号括住。如sizeof(int)。

  2、用于变量

  sizeof使用形式:sizeof(var_name)或sizeof var_name

  变量名可以不用括号括住,带括号的用法更普遍,大多数程序员采用这种形式。

  注意:sizeof操作符不能用于函数类型,不完全类型或位字段。不完全类型指具有未知存储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等。

三、sizeof的结果

  sizeof操作符的结果类型是size_t,它在头文件中typedef为unsigned int类型。该类型保证能容纳实现所建立的最大对象的字节大小。

  1、若操作数具有类型char、unsigned char或signed char,其结果等于1。

  ANSI C正式规定字符类型为1字节。

  2、int、unsigned int 、short int、unsigned short 、long int 、unsigned long 、float、double、long double 类型的sizeof 在ANSI C中没有具体规定,大小依赖于实现,一般可能分别为2、2、2、2、4、4、4、8、10。

  3、当操作数是指针时,sizeof依赖于编译器。例如Microsoft C/C++7.0中,near类指针字节数为2,far、huge类指针字节数为4。一般Unix的指针字节数为4。

  4、当操作数具有数组类型时,其结果是数组的总字节数。

  5、联合类型操作数的sizeof是其最大字节成员的字节数。结构类型操作数的sizeof是这种类型对象的总字节数,包括任何垫补在内。

  让我们看如下结构:

  struct {char b; double x;} a;

  在某些机器上sizeof(a)=12,而一般sizeof(char)+ sizeof(double)=9。

  这是因为编译器在考虑对齐问题时,在结构中插入空位以控制各成员对象的地址对齐。如double类型的结构成员x要放在被4整除的地址。

  6、如果操作数是函数中的数组形参或函数类型的形参,sizeof给出其指针的大小。

六、建议

  由于操作数的字节数在实现时可能出现变化,建议在涉及到操作数字节大小时用sizeof来代替常量计算。


'\0'这个字符在ASCII码表里面是0.


关于scanf,形如: scanf("%s", name); 你输入rui liu 的时候,其实只有rui是输入了的,也就是说scanf() stop reading at first whitespace(blank, tab or newline) it encounters.


打印百分号: %%
 
q=2*++a  ; 首先把a加一,然后再用2乘此时a的值
q=2*a++  ;在a还没加一之前,就乘2,赋值给q,然后再把a加一
++和--运算符具有只小于括号的优先级,也就是说优先级排第二
要避免如下常见错误:
1):printf("%10d %10d\n", num, num*num++);
2):ans = num/2 + 5*(1 + num++);
3):y = n++ + n++;
这个时候,不同编译器会做不同处理

You can easily avoid these problems:

  • Don't use increment or decrement operators on a variable that is part of more than one argument of a function.

  • Don't use increment or decrement operators on a variable that appears more than once in an expression.

类型转换的基本原则:
  1. When appearing in an expression, char and short, both signed and unsigned, are automatically converted to int or, if necessary, to unsigned int. (If short is the same size as int, unsigned short is larger than int; in that case, unsigned short is converted to unsigned int.) Under K&R C, but not under current C, float is automatically converted to double. Because they are conversions to larger types, they are called promotions.

  2. In any operation involving two types, both values are converted to the higher ranking of the two types.

  3. The ranking of types, from highest to lowest, is long double, double, float, unsigned long long, long long, unsigned long, long, unsigned int, and int. One possible exception is when long and int are the same size, in which case unsigned int outranks long. The short and char types don't appear in this list because they would have been already promoted to int or perhaps unsigned int.

  4. In an assignment statement, the final result of the calculations is converted to the type of the variable being assigned a value. This process can result in promotion, as described in rule 1, or demotion, in which a value is converted to a lower-ranking type.

  5. When passed as function arguments, char and short are converted to int, and float is converted to double. This automatic promotion can be overridden by function prototyping, as discussed in Chapter 9, "Functions."

在编程的过程中要尽量避免不同类型数据的运算,这很容易造成一些错误,这也是有些语言不支持不同类型计算的原因。但是有些情况下,确有一定用处。
 
 
while (scanf("%d", &num) == 1)
As long as scanf() reads an integer, it returns 1, and the loop continues.
 

C99 also provides for a stdbool.h header file. This header file makes bool an alias for _Bool and defines true and false as symbolic constants for the values 1 and 0. Including this header file allows you to write code that is compatible with C++, which defines bool, true, and false as keywords.

If your system does not yet support the _Bool type, you can replace _Bool with int, and the example will work the same.

 

在for循环中声明初始化变量是C99里面的标准

Table 7.1. The ctype.h Character-Testing Functions

Name

True If the Argument Is

isalnum()

Alphanumeric (alphabetic or numeric)

isalpha()

Alphabetic

isblank()

A standard blank character (space, horizontal tab, or newline) or any additional locale-specific character so specified

iscntrl()

A control character, such as Ctrl+B

isdigit()

A digit

isgraph()

Any printing character other than a space

islower()

A lowercase character

isprint()

A printing character

ispunct()

A punctuation character (any printing character other than a space or an alphanumeric character)

isspace()

A whitespace character (a space, newline, formfeed, carriage return, vertical tab, horizontal tab, or, possibly, other locale-defined character)

isupper()

An uppercase character

isxdigit()

A hexadecimal-digit character


Table 7.2. The ctype.h Character-Mapping Functions

Name

Action

tolower()

If the argument is an uppercase character, this function returns the lowercase version; otherwise, it just returns the original argument.

toupper()

If the argument is a lowercase character, this function returns the uppercase version; otherwise, it just returns the original argument.


 

When you have a lot of ifs and elses, how does the computer decide which if goes with which else?
The rule is that an else goes with the most recent if unless braces indicate otherwise
 
 

Traditionally, C has used the int type for flags, but the new _Bool type matches the requirements perfectly. Furthermore, by including the stdbool.h header file, you can use bool instead of the keyword _Bool for the type and use the identifiers true and false instead of 1 and 0.

在C99里面,新增加了一个头文件iso646.h ,这个头文件使得用and,or,not代替&&,||和!

 

有一些判断字符的函数: isalnum,  isalpha, isascii, isblank, iscntrl, isdigit, isgraph, islower, isprint, ispunct, isspace, isup-
       per, isxdigit - character classification routines
它们在头文件ctype.h里面定义

 

 有buffered和unbuffered输入两种,在ANSI C规定了C语言中的都是buffered的,但是最早K&R把这个问题留给了编译器开发商来决定。

ANSI C之所以做出这样的规定是因为一些计算机设计来不允许unbuffered输入, 很多IBM PC兼容的编译器支持一系列在conio.h头文件中定义的支持unbuffered输入的函数, 比如getche()和getch(),前者在输入字符的时候并不在显示器上显示出你输入的字符。Unix下是另外一种情形,在unix下使用ioctl()  to specify the type of input you want, and getchar() behaves accordingly. In ANSI C, the setbuf() and setvbuf() functions supply some control over buffering, but the inherent limitations of some systems can restrict the effectiveness of these functions. In short, there is no standard ANSI way of invoking unbuffered input; the means depend on the computer system. 

In dealing with text, 不同系统对判断一行结束有不同的方式,一些系统用newline character,一些系统用the combination of the carriage return and linefeed characters to represent the end of a line. 一些系统measure file sizes to the nearest byte; some measure in blocks of bytes.

When you use the standard I/O package, you are shielded from these differences. Therefore, to check for a newline, you can use if (ch == '\n'). If the system actually uses the carriage-return/linefeed combination, the I/O functions automatically translate back and forth between the two representations.

Conceptually, the C program deals with a stream instead of directly with a file. A stream is an idealized flow of data to which the actual input or output is mapped. That means various kinds of input with differing properties are represented by streams with more uniform properties. The process of opening a file then becomes one of associating a stream with the file, and reading and writing take place via the stream.

discusses files in greater detail. For this chapter, simply note that C treats input and output devices the same as it treats regular files on storage devices. In particular, the keyboard and the display device are treated as files opened automatically by every C program. Keyboard input is represented by a stream called stdin, and output to the screen (or teletype or other output device) is represented by a stream called stdout. The getchar(), putchar(), printf(), and scanf() functions are all members of the standard I/O package, and they deal with these two streams.

One implication of all this is that you can use the same techniques with keyboard input as you do with files. For example, a program reading a file needs a way to detect the end of the file so that it knows where to stop reading. Therefore, C input functions come equipped with a built-in, end-of-file detector. Because keyboard input is treated like a file, you should be able to use that end-of-file detector to terminate keyboard input, too. Let's see how this is done, beginning with files.

C handles this variety of methods by having the getchar() function return a special value when the end of a file is reached, regardless of how the operating system actually detects the end of file. The name given to this value is EOF (end of file). Therefore, the return value for getchar() when it detects an end of file is EOF. The scanf() function also returns EOF on detecting the end of a file. Typically, EOF is defined in the stdio.h file as follows:

#define EOF (-1)

The variable ch is changed from type char to type int because char variables may be represented by unsigned integers in the range 0 to 255, but EOF may have the numeric value -1. That is an impossible value for an unsigned char variable, but not for an int. Fortunately, getchar() is actually type int itself, so it can read the EOF character. Implementations that use a signed char type may get by with declaring ch as type char, but it is better to use the more general form.

To use this program on keyboard input, you need a way to type the EOF character. No, you can't just type the letters E O F, and you can't just type –1. (Typing -1 would transmit two characters: a hyphen and the digit 1.) Instead, you have to find out what your system requires. On most Unix systems, for example, pressing Ctrl+D at the beginning of a line causes the end-of-file signal to be transmitted. Many micro-computing systems recognize Ctrl+Z at the beginning of a line as an end-of-file signal; some interpret a Ctrl+Z anywhere as an end-of-file signal.



阅读(1250) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~