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     }  
时间: 2024-10-08 18:32:45

Standard C episode 1的相关文章

Standard C Episode 3

程序语言中的控制流语句用于控制各计算操作执行的次序.控制流结构有:(1)顺序结构(2)分支结构(3)循环结构 if...else语句是经典的分支结构控制语句,同样"switch (表达式)...case 常量表达式" 语句也可以实现分支处理."表达式"可以是任何表达式,"常量表达式"也可以是任何常量表达式.case分支一般包含多条语句时也不必用大括号括起来,因 为每一个case分支只会给出switch分支结构中语句执行的开始位置,而不确定终止位置

Standard C Episode 5

理解变量标识符的作用域和可见性,以及变量生存期. (1)标识符的作用域和可见性     作用域:作用域是一个标识符在源程序中有效的区域.     可见性:程序运行到某一点,能够引用到的标识符,就是该处可见的标识符. (2)变量生存期:     变量的生存期就是指变量从创建到销毁的时间范围.变量按照生存期分“静态生存期”和“动态生存期”.静态生存期:如果变量的生存期与程序的运行期相同,则称该变量具有“静态生存期”; 动态生存期:变量生存期始于创建声明点,结束于作用域结束处. 注意:源程序声明(定义

Standard C Episode 2

源程序中,但凡可以出现某种类型的数据的地方都可以用同类型的表达式替换.一个表达式的类型,取决于多个方面. 操作符有单目操作符和双目操作符, 还有三目操作符(? : 是C语言唯一的一个三目操作符)."目"指的是操作数的个数! C语言没有指定同一操作符的多个操作数的计算顺序(除了&& || ? : 和,).所以语句x = f() + g();的计算结果依赖不同的编译器. 1 /* 2 * 文件名: 3mu.c 3 * 描述:(1)一个表达式的类型取决于多个方面(表达式的操作

Standard C Episode 4

稍微简单的复杂数据类型:数组 计算机程序处理的对象是数据信息(计算机中的信息包括数据信息和控制信息),计算机内存可以存储大量信息,姑且可以认为只有存储在内存中的数据信息才是可 以使用的.内存由操作系统管理,程序要使用内存存储空间需要向操作系统申请并被成功分配后才可以使用,C语言提供的变量声明(定义)语句可以实现向操作系 统申请存储空间. C语言提供的变量声明(定义)语句实现向操作系统申请存储区(存储空间),变量名有"两个代表",一是代表所申请到的存储区,一是代表存储区里面存放的数 据信

Standard C Episode 6

字符串.字符串是以'\0'结尾的字符序列.C语言字符串在内存中的存储规则:按照串中字符出现的顺序在内存中连续存储,末尾是字符串结束符'\0'. 注:'\0'(查ASCII码表可知'\0'就是0)是表示字符串的字符,它的位置决定了一个字符串中有效字符的个数. 字符串常量.字符串常量在源程序词法记号中属于"文字",它和其他文字"数字.布尔文字.以及字符"一样.但区别是“字符串常量文字代表的是首字符地址”. 注:编译器编译时候会把源程序中重复出现的相同文字只存储一回.多个

Standard C Episode 8

C语言函数和程序结构 通过函数可以把大的计算任务分解成若干个较小任务,从而使得思路更加清晰,同时函数也大大提高了代码的复用率,提高了工作效率.要注意的是多函数之间应该尽可能地高聚合低耦合.另一方面,一个程序可以保存在一个或者多个源文件中.各个文件可以单独编译. 注意:一般地,头文件中不会放那些在程序运行时发生具体效应的语句.例如声明(定义)一个变量的语句是不会放在头文件中的.再例如结构体声明(定义)语句就可以放头文件里,但结构体变量声明(定义)语句是不会放在头文件中的. make工具可以用来进行

Standard C Episode 9

typedef关键字可以给数据类型起别名. 结构体.结构体可以如下定义一个结构体变量 1 /* 2 * 结构体 3 * */ 4 #include <stdio.h> 5 /*struct { 6 int age; 7 char gender; 8 float height; 9 } student;//声明(定义)无名结构体的同时定义了结构体变量student 10 */ 11 /*struct student { 12 int age; 13 char gender; 14 float h

Standard C Episode 10

标准库函数malloc/calloc/realloc以及free的堆内存分配与回收 1 /* 2 * malloc练习 3 * 4 * */ 5 6 #include <stdlib.h> 7 #include <stdio.h> 8 9 int main() 10 { 11 int *p_value = NULL; 12 13 p_value = (int *) malloc (1 * sizeof(int)); 14 if (p_value) { 15 printf("

Standard C Episode 7

编译预处理 #define可以定义宏.宏可以带参数,叫做带参数的宏,其参数叫做宏的参数. #undef 可以解除宏的定义. 1 /* 2 宏练习 3 */ 4 5 #include <stdio.h> 6 #define NEG( r) r = 0 - r 7 8 main() 9 { 10 int value = 4; 11 NEG(value); 12 printf("value是%d\n", value); 13 } 1 /* 2 宏练习 3 */ 4 #includ