首页 > 代码库 > Standard C episode 1

Standard C episode 1

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操作符查看结果如下:
##################################################
int->4
unsigned int->4
unsigned->4
short int->2
short->2
unsigned short int->2
unsigned short->2
long int->4
long->4
unsigned long int->4
unsigned long->4
char->1
unsigned char->1
float->4
double->8
long double->12
##################################################




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

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

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

原码:符号-绝对值表示的编码,称为原码。
反码:正数的反码表示与原码表示一样。负数的反码的符号位与原码相同,其余各位按位取反。
补码:正数的补码表示与原码表示一样。负数的补码可由该数的反码再加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     }  

 

Standard C episode 1