Standard C Episode 1

计算机内存可以记录大量的信息,只有记录在内存中的信息才是可以使用的。计算机的内存管理者是操作系统。程序可以根据需要向操作系统申请存储区,所有存储区必须先申请并经过操作系统分配后才能由程序使用。我们知道计算机里的信息可以简单划分为:

                      /指令
      /控制信息
信息 -            \控制字
      \数据信息
                    |
             /              \
     数值信息     非数值信息
      /    \                            /       \
   定点数  浮点数   字符数据  逻辑数据



C语言中,可以用变量来代表内存中的一个存储区,并可以通过变量名来区分不同存储区。源程序中可以通过变量声明(定义)语句可以向操作系统申请存储区。变量名可以代表两个不同的东西,一是代表存储区本身,二是代表存储区里面存放的数据。
C语言变量分多种类型(数据类型),不同类型变量的数据信息在存储区是有区别的,不同类型的变量可以参与的操作也是有区别的。

 

计算机中的内存基本存储单元是字节byte,最小存储单元是位bit,8bit组成一个字节。每个字节可以用来表示256个数字。我们之所以对计算机中的数据进行分组,划分数据类型就是因为不同数据占有存储空间不一。

字符类型一般占内存一个字节,因此可以通过数字表示256个不同的字符,256个字符各自对应着一个数字,这数字或者介于-127~127或者介于 0-255之间,具体字符所对应的数字取决于编译器。但是一般对于0~127这部分数值和字符的对应关系都是固定的,都是有共识的,这就是ASCII码 表。ASCII码表规定了128个字符对应的数字。所以我们说ASCII码表规定了字符到数字之间的对应关系,ASCII码从0~127.这部分对应没有 编译器差异。
在C语言中使用char表示字符类型,该类型的字符和数字的对应关系取决于编译器,但是对于0~127这部分数字对应的字符是符合ASCII码规定的。
在C语言中还有unsigned char,叫做无符号字符类型。该类型字符和数字对应关系式固定的,没有编译器差异。当然对于0~127这部分数字对应的字符依然是符合ASCII码规定的。



short叫做短整型类型,一般占有2byte,可以表示65535个数字。
unsigned short叫做无符号短整型,一般占有2byte,可以表示65535个数字,而且全部是无符号数,全是正数,数值范围是[0,65534]

long叫做长整型,一般占有4byte
unsigned long叫做无符号长整型,一般占有4byte

int叫做整型,一般占有4byte
unsigned int叫做无符号整型,一般占有4byte

float叫做单精度浮点数类型,一般占有4byte
double叫做双精度浮点数类型,一般占有8byte
long double叫做高精度浮点类型,一般占有12byte
--->以上说的是一般情况,实际应该视计算机平台而定,例如我的计算机lotus-Laptop用sizeof操作符查看结果如下:

 1  // $./a.out
 2  // sizeof(char)                  ===>1 byte
 3  // sizeof(unsigned char)         ===>1 byte
 4  // sizeof(int)                   ===>4 byte
 5  // sizeof(unsigned int)          ===>4 byte
 6  // sizeof(unsigned)              ===>4 byte
 7  // sizeof(short int)             ===>2 byte
 8  // sizeof(short)                 ===>2 byte
 9  // sizeof(unsigned short)        ===>2 byte
10  // sizeof(unsigned short int)    ===>2 byte
11  // sizeof(long int)              ===>4 byte
12  // sizeof(long)                  ===>4 byte
13  // sizeof(unsigned long int)     ===>4 byte
14  // sizeof(unsigned long)         ===>4 byte
15  // 
16  // -------------浮点数的机器码由尾数和阶码组合而成,尾数是一个有符号数--------------
17  // sizeof(float)                 ===>4 byte
18  // sizeof(double)                ===>8 byte
19  // sizeof(long double)           ===>12 byte

 




数值信息分定点数和浮点数。其中定点数也称为整型数,浮点数也称为实型数。

数值信息在机器中的表示:
    数值信息在机器内的表达形式称为"机器数",而"机器数"代表的数值称为此"机器数"的真值。("机器数"采用的二进制编码方法是补码表示方法。)

数值信息在计算机内采用符号数字化处理后,计算机就可以识别和表示数值信息了,为了改进带符号数值的运算方法,人们提出了数值信息的多种二进制编码方法,多种编码方法其实质都是在对负数的表示进行改造,原码、反码和补码就是这样。

原码:符号-绝对值表示的编码,称为原码。
反码:正数的反码表示与原码表示一样。负数的反码的符号位与原码相同,其余各位按位取反。
补码:正数的补码表示与原码表示一样。负数的补码可由该数的反码再加1求得。
--->补码的好处是:(1)零的表示唯一(2)符号位可作为数值参加运算

对于原码、反码和补码我们得出的结论是:
(1)计算机数值信息的"机器数"采用的是补码,这样可以简化带符号数值的运算
(2)正数的反码和补码和原码相同
(3)负数补码计算方法可以总结为对其相反数"按位求反再加一",其实质就是对负数的相反数求相反数。补码的补码就是原码的相反数
(4)补码参与运算的结果依然是补码

##################################################
附:负数补码计算方法"按位求反再加1"其实质就是求相反数,以下是简明推理过程
以-13机器数的推理为例:
-13=?
-13+13=0

******** + 00001101 =  00000000
******** + 00001101 = 100000000
******** = 100000000 - 00001101
******** =  11111111 + 1 - 00001101
******** = 11111111 - 00001101 + 1
******** = 11110010 + 1
******** = 11110011

试求-51的机器码?
-51=?
-51+51=0
******** + 00110011 =  00000000
******** + 00110011 = 100000000
******** = 100000000 - 00110011
******** =  11111111 + 1 - 00110011
******** =  11111111 - 00110011 + 1
******** =             11001100 + 1
******** = 11001101

##################################################

 

 

 

 

C语言源程序中向指定存储区存放数据的操作许多,其中赋值操作符是 = 是最核心的,该操作符可以把右操作数赋给左操作数,左操作数应该是一个允许存放数据的存储区。我们把可以放在赋值操作符左边的变量成为左值变量,把可以放在赋值操作符右边的变量称为右值变量。


ANSI C标准库标准输入输出模型中,不管文本从何处输入又或向何处输出都将按照字符流处理,文本流是一个多行字符组成的字符序列,每一行行末都有一个换行符。(PS:往往程序可以通过统计换行符来得到总行数)


C语言源程序中,一个字符串常量应该用双引号""括起来才行! 并且,一般地,一个字符串常量应该置于同一行才可以,因为编译器是不会主动到其他行寻找字符串结束分隔符"的。 (PS: 当然,如果字符串常量被人为分散在多行,应该使用续行符号\来连接两行,以方便编译器认定一个完整的字符串)

 

 

 1     /* 
 2      * printf格式控制字符串中转义字符序列\r练习 
 3      * */  
 4       
 5     #include <stdio.h>  
 6       
 7     int main()  
 8     {  
 9         long int integer = 0;  
10       
11         for (integer = 1; integer <= 987654321l; integer++)  
12             if (integer % 4 )  
13                 printf(".");  
14             else  
15                 printf("\r");  
16       
17         return 0;  
18     }  

 

 1     /* 
 2      * printf练习 
 3      * 转义字符序列 
 4      * */  
 5       
 6     #include <stdio.h>  
 7     int main()  
 8     {  
 9         printf("\"\"\n");//输出引号  
10         printf("\\\n");//输出反斜杠  
11         printf("%%\n");//输出百分号  
12         printf("\a");//输出一个蜂鸣声  
13         printf("abc\rxyz\n");//输出abc后退回再输出xyz  
14         /*printf("\c\n");//编译会出warning,提示有无法识别的转义字符序列.进一步如果忽略warning,那么\c整体被忽略(也就是说\c根本就没有被编译入机器码)*/  
15           
16         printf("%x\n", '%');  
17         printf("\x5\n");//格式控制字符串中可以用转义字符序列来实现通用的字符表达方式,通过使用转义字符序列代表任意字符  
18       
19         return 0;  
20     }  

 

 1     /* 
 2      * 
 3      * scanf练习 
 4      * */  
 5       
 6     #include <stdio.h>  
 7       
 8     int main()  
 9     {  
10       
11         int integer = 0;  
12         scanf("%d", &integer);  
13         printf("%d\n", integer);  
14       
15         /* 
16         int num = 0; 
17         scanf("%d", num);//这样的调用scanf()会引起编译warning 
18                         //当gcc 02scanf.c -Wall编译时,编译器报warning 
19                         //如果忽略warning,所生成目标代码执行时候可能引发操作系统强制终止代码执行, 因为代码执行至scanf("%d", num)时,将num当一个地址值使用,这样可能会引起地址越界 
20         printf("%d\n", num); 
21         */  
22       
23         return 0;  
24     }  

 

 1     /* 
 2      * 打印C各数据类型当前占有的存储空间大小(byte) 
 3      * */  
 4       
 5     #include <stdio.h>  
 6     int main()  
 7     {  
 8         printf("int->%d\n", sizeof(int));  
 9         printf("unsigned int->%d\n", sizeof(unsigned int));  
10         printf("unsigned->%d\n", sizeof(unsigned));  
11         printf("short int->%d\n", sizeof(short int));  
12         printf("short->%d\n", sizeof(short));  
13         printf("unsigned short int->%d\n", sizeof(unsigned short int));  
14         printf("unsigned short->%d\n", sizeof(unsigned short));  
15         printf("long int->%d\n", sizeof(long int));  
16         printf("long->%d\n", sizeof(long));  
17         printf("unsigned long int->%d\n", sizeof(unsigned long int));  
18         printf("unsigned long->%d\n", sizeof(unsigned long));  
19         printf("char->%d\n", sizeof(char));  
20         printf("unsigned char->%d\n", sizeof(unsigned char));  
21         printf("float->%d\n", sizeof(float));  
22         printf("double->%d\n", sizeof(double));  
23         printf("long double->%d\n", sizeof(long double));  
24       
25         return 0;  
26     }  
 1     /* 
 2      * sizeof()练习 
 3      * */  
 4     #include <stdio.h>  
 5       
 6     main()  
 7     {  
 8         char character = 0;  
 9         unsigned char character_u = 0;  
10         printf("char类型变量character占有%d个字节\n", sizeof(character));  
11         printf("unsigned char类型变量character_u占有%d个字节\n", sizeof(character_u));  
12       
13         /*C语言中我们之所以区分数据类型,就是因为不同数据所占存储空间大小不一*/  
14         printf("char类型变量占有%d个字节\n", sizeof(char));  
15         printf("unsigned char类型变量占有%d个字节\n", sizeof(unsigned char));  
16     }  

 

 1     /* 
 2      * sizeof()练习 
 3      * sizeof()只是用来计算操作数占有的存储空间,它不影响操作数本身.请分析本例 
 4      * */  
 5     #include <stdio.h>  
 6       
 7     main()  
 8     {  
 9         char character = 0;  
10       
11         character = 'a';  
12         printf("char类型变量character存放着%c, 占有%d个字节\n",character, sizeof(char));  
13       
14         sizeof(character = 'b');//sizeof关键字可以对表达式的结果计算占有存储空间大小,但是表达式中的所有修改都不会保留,所以本例程的两行打印结果一样。  
15         printf("char类型变量character存放着%c, 占有%d个字节\n",character, sizeof(char));  
16     }  

 

 1     /* 
 2      * 
 3      * Discreption:计算87+97演示溢出的例程 
 4      * 当采用一个字节存储时,87+97会溢出 
 5      * */  
 6     #include <stdio.h>  
 7     main()  
 8     {  
 9         char c = 87;  
10         printf("%d\n", c);  
11         c = c + 87;//这里会溢出  
12         printf("%d\n", c);  
13     }  

 

 1     /* 
 2      * 操作符练习 
 3      * */  
 4       
 5     #include <stdio.h>  
 6     main()  
 7     {  
 8         int num1 = 0, num2 = 0;  
 9       
10         printf("15 / 7 = %d\n", 15 / 7);  
11         printf("15 %% 7 = %d\n", 15 % 7);  
12         num1 = num2 = 7;  
13         printf("num1是%d, num2是%d\n", num1, num2);  
14         num1 += 2;//num = num + 2;  
15         printf("num1是%d\n", num1);  
16         num1 *= 2 + 3;//复合赋值操作符的优先级和赋值操作符的优先级一样,所以语句num *= 2 + 3;等效于语句num = num * (2 + 3);  
17         printf("num1是%d\n", num1);  
18       
19     }  

 

posted on 2014-11-16 01:43  來時的路  阅读(151)  评论(0编辑  收藏  举报