您好,欢迎访问三七文档
C语言基础学习笔记(第一版修改)丁炳亮1数据类型和表达式1.1计算机内数据存储方式理解与测试:什么是补码?我们得先知道模的概念。模“模”是指一个计量系统的计数范围。如时钟等。计算机也可以看成一个计量机器,它也有一个计量范围,即都存在一个“模”。例如:时钟的计量范围是0~11,模=12。表示n位的计算机计量范围是0~2^(n)-1,模=2^(n)。“模”实质上是计量器产生“溢出”的量,它的值在计量器上表示不出来,计量器上只能表示出模的余数。任何有模的计量器,均可化减法为加法运算。例如:假设当前时针指向10点,而准确时间是6点,调整时间可有以下两种拨法:一种是倒拨4小时,即:10-4=6;另一种是顺拨8小时:10+8=12+6=6在以12模的系统中,加8和减4效果是一样的,因此凡是减4运算,都可以用加8来代替。对“模”而言,8和4互为补数。实际上以12模的系统中,11和1,10和2,9和3,7和5,6和6都有这个特性。共同的特点是两者相加等于模。二进制中整数的补码求法是:正数的补码为原码,负数的补码是符号位不变其他位全部取反再整个数加1。我们可以通过下面的代码看下负整数在计算机内部的表示。voidf(intn){unsignedinti;for(i=1,i=15;i;i=1){if(i&n)printf(1);elseprintf(0);}printf(\n);}main(){inta=-0xff;f(a);getch();}输出的结果是1111111100000001。1.2变量与常量理解与测试:1)类型声明在计算机内部数据是以字节为单位存储的,但是我们需要的数据类型有很多种,每种数据类型所占字节和存储方式都不一样。类型声明的作用就是告诉计算机以哪种“格式”去读写该数据数据。类型说明符变量名1,变量名2......,变量名n;类型说明符有基本类型(字符型、整数型、单/双精度型)、高级类型(结构体型、共用体型、枚举类型)、指针型等,其中指针类型包括指向基本类型的指针类型、指向高级类型的指针型和指向函数的指针类型(指向函数指针声明格式在后面章节)。2)符号常量的定义#define标识符常量;使用该种方法定义符号常量一个是可以使代码便于阅读理解,另一个是方便代码内部多个相同常量的统一修改。总结与注意在写计算式的时候要考虑变量是否会越界。一般来说计算式子时是先强制转换成式子中最大存储空间的数据类型(不包括被赋值的变量),还要注意不同的类型数据在不同的编译器中所占的内存有可能是不一样的,例如有些编译器整型是占2个字节有些是占4个字节。同时还要考虑到符号的优先级和结合顺序,如果按符号的优先级和结合顺序运算过程中有越界的那么整个计算结果可能和预想的不一样了,例如inti=100;i=500*i/i;最后i=-155。1.3输出输入理解与测试:1)格式化输入输出函数可以按设定的格式和设定的数据类型接收和输出多个变量。控制格式和数据类型的是数据控制符。2)字符和字符串可以用专门的输出\输入函数。主要有getch();putch();getchar();putchar();gets();puts();其中getch()和putch()是conio.h中声明,getch()不需要等待回车键就返回字符并立即执行下面一语句符,getch()不在屏幕显示输入的字符。getchar();putchar();在stdio.h中声明。getchar()读取键盘上的一个字符,立即返回并显示在屏幕上,需要等待回车键才能执行下一条语句。例如下面的代码:intmain(void){charch,i;for(i=0;i10;i++){ch=getchar();putchar(ch);}getch();}输入:ILOVEYOU输出:ILOVEYOU总结与注意格式输入函数中的参数是变量存放的地址,所以变量前面要”&”符号。如果是数组则可以直接用数组名,因为数组名就是指向该数组首地址的指针常量。1.4运算符号理解与测试:1)表达式中符号的运算顺序是有先后的,根据符号的优先级和结合性(左结合/右结合)来判定。如果是几个符号连在一起C内部是怎么去读的呢?有一个很简单的规则:每一个符号应该包含尽可能多的字符。也就是说,编译器读取符号的方法是,从左到右一个字符一个字符地读入,如果该字符可能组成一个符号,那么在读入下一个字符,直到与下个字符组合成的符号没有意义为止。例如:a---b;这个表达式等效于(a--)-b;2)复合赋值符及表达式在赋值符“=”之前加上其他双目运算符号可以构成复合赋值符。如:+=、-=、*=、/=、%=。构成复合赋值表达式的一般格式为变量双目运算符=表达式等价于变量=变量运算符表达式可以这么去理解,等号左边的相当于变量自增、自减、自除、自取余一个数,这个数由右边的表达式计算得到。如:inta=7,b=3,c=3;a+=b+=c+=5;运算后是a=18,b=11,c=8。3)C中唯一一个三目运算符是条件运算符,由“?”和“:”构成。两个符号必须按下面的格式一起使用:表达式1?表达式2:表达式3三个表达式可以是任意的合法表达式,条件运算符的运算规则如下:如果表达式1的值为真,那么整个表达式的值为表达式2的值,否则为表达式3的值。4)sizeof()也是一个运算符号,它可以对一个数据类型或一个变量取类型长度。但是当一个数组名作为一个实参传递给函数时,在函数内部是不能用sizeof来获取该数组的长度的。因为数组名是一个指向数组首地址的指针,使用sizeof只能取得实参指针类型长度。5)比较少用到的符号是“:”和“,”。冒号运算符在C中有三种用途,第一种是我们上面讲到的与“?”构成三目运算。第二种是在switch中放在常量表达式后面。第三种用法是在结构体中定义位域时用到。struct位域结构名{位域列表};其中位域列表的形式为:类型说明符位域名:位域长度例如:structbs{inta:8;intb:2;intc:6;};逗号运算符的功能是把两个表达式连在一起组成一个新的表达式,称为逗号表达式。其一般格式为表达式1,表达式2,表达式3,...,表达式n;其求值过程是自左向右求两个表达式的值,并以最后一个表达式的值作为整个逗号表达式的值。例如for(a=0,b=0,c=0;b10,a20;b++,a++)++c;运算后c=20,如果把中间的两个语句前后调换for(a=0,b=0,c=0;b10,a20;b++,a++)++c;运算后c=10。6)不同的数据类型的量混合运算的时候,系统会临时把算式中长度小的数据类型自动转换成长度大的数据类型。在某些时候我们需要临时改变一个数据的类型或者说是读取“格式”,我们可以使用强制类型转换符,”(type)”。使用的格式一般如下:(类型说明符)表达式要得到一个数据类型的类型说明符很容易。只要知道如果声明一个给定类型的变量,那么就可以得到该数据类型的转换符就是把声明中变量名和声明的分号去掉。例如:(int)、(float)、(char*)、(int(*)())等等。总结与注意1)“==”和“=”这两个符号也容易在判断语句内出错,严重的还会出现死循环。2)自增“++”和自减“--”可以作为前缀也可以作为后缀。作为变量前缀时,在表达式中每次取用变量值运算前先自增/自减,作为变量后缀时,在表达式中每次取用变量值运算后再自增/自减。例如:main(){inti=2,j=1,n;printf(%d\n,i++);n=i++j?i++:j;printf(%d\n,n);getch();}输出结果:243)在写式子时要注意运算符号对变量的副作用,单目运算有“++”和“--”,双目运算有“=”。4)位运算符号与逻辑符号容易混淆的有“&”和“&&”、“|”和“||”、“~”和“!”。前面两个可以这么记,位运算是单个的所以符号也是单个的。5)在使用位运算符号时要主要如果是有符号数则是对他们的补码执行位运算。对于有符号的整数型使用左移“”右补0,使用右移“”左补1。如下代码:voidf(intn){unsignedinti;for(i=1,i=15;i;i=1){if(i&n)printf(1);elseprintf(0);}printf(\n);}main(){inta=-0xff;f(a);a=1;f(a);getch();}输出的结果是:111111110000000111111111100000006)运算符优先级可以简单归纳如下几点:①单目运算符比任何一个真正意义上的运算符的优先级高。②逻辑运算符比关系运算符优先级高。③移位运算符表算术运算符优先级低,但高于关系运算符。2程序控制结构2.1选择结构理解与测试:使用if-else多层嵌套时else是与上面同一层的最近if相结合的,在程序设计时有过多的分支最好要选择使用if-else,当然如果可以使用switch语句还是尽量选择switch语句或者使用其他能使代码简洁易懂的方法。如下面的代码:main(){inta=10,b=6,c=7,d=8,e=9,f=10;if(ab){printf(%d\n,a);if(bc){printf(%d\n,b);if(cd){printf(%d\n,c);if(de){printf(%d\n,d);if(ef){printf(%d\n,e);}elseprintf(%d\n,f);}}}}getch();}这种代码又长又难看懂,更要命的是经常搞不懂下面的大括号对应上面的哪个大括号。改进后的代码如下main(){inta=10,b=6,c=7,d=8,e=9,f=10;while(1){if(a=b)break;printf(%d\n,a);if(b=c)break;printf(%d\n,b);if(c=d)break;printf(%d\n,c);if(d=e)break;printf(%d\n,d);if(e=f)printf(%d\n,e);elseprintf(%d\n,f);break;}getch();}第二种方法比第一种方法来看上去更干净,理解上差不了多少。2)总结与注意switch语句中每一个分支结束都要有break;语句,如果没有是继续执行下面分支,可能会得到和预料不同的效果。还要注意,case后面跟的一定是整数型或符号型常量表达式,不能是变量,并且不用有相同值的变量表达式,不然会矛盾的。2.2循环结构理解与测试:1)主要有for、while、do-while这三种结构循环体,其中最后一种是比较少用到的,因为一般情况都可以用前面两种替代。2)循环体结构中括号的表达式要知道时候退出,有时候还要知道循环体运行多少次。在循环体内部也可以使用continue语句跳过本次循环,进入下一次循环,或者用break语句退出当前层循环。总结与注意循环结构中表达式的设计很重要。在for循环结构我们经常用到从0到x,循环体执行x+1次,可以写成for(i=0;ix+1;i++)。有时候要考虑变量i是否会越界,例如:for((int)i=10;i0;i-=3);这个循环语句的运行结果一般不是我们想要的。把“==”不注意写成“=”也是容易造成死循环的结果。3数组3.1一维数组理解与测试:1)一维数组的定义如下:类型说明符数组名[常量表达式]如果定义时就进行初始化,常量表达式可以省略。动态存储的数组没有初始化所有元素的值都为随机。静态存储的数据没有初始化所有的元素自动赋0。2)一维数组名是一个指针常量,指向数组的首地址。由于是指针常量所以不能对其赋值,只能当指针引用。同理一个数组不能对另一个数组整体赋值。数组引用时下标是从0开始计算的。3)字符型数组初始化可以直接赋值字符串。chars[]={“Happy”};或者chars[]=”Happy”;。总结与注意数组引用时下标不要越界,字符串数组初始化时,数组元素个数要比字符串多一个,因为字符串结束有个“\n”符,否则越界就会发生预料不到的结果。如下:mai
本文标题:C语言基础学习笔记
链接地址:https://www.777doc.com/doc-1885072 .html