3.3.2 字符型
储存方式:以整数形式(ASCALL码的形式)储存
储存空间:见下表右边两列
前面这些决定整数型常量的数据类型。
下面要储存这些常量,就要定义相应的变量的数据类型;
定义储存字符形数据的变量,如上表左边一列所示;
注意: 1.所以符号第一位是表示符号的,实际能起到限定范围的是后面7位; 所以他的范围是 -128-----127,首先字符型符号无意义; 只有正数所以他的范围是128种;也就是从0开始 范围是0--127。 但是对于无符号的;把他的负数加绝对值那么他的范围就变成了0-255。 2.以整数形式储存:如下图; 3.char c='?'; '?'在ASCALL表中对应的是63,此时是把对应的63赋值给c;所以说字符型是一种特殊的整数型。输出的时候可以通过"%d"输出整数,"%c"输出字符。 4.再定义变量的时候,既不加signed 也不加 unsigned 那么这个char究竟是哪一种,由编译系统自己决定,他不像int ,如果你不加,它默认是signed int.
3.3.3浮点型
为什么叫做浮点型:
咱们之前说过实数型它通常可以表示指数形式;在计算机里面实数型也是以指数的形式储存;既然以指数的形式储存那么;0.123E2 1.23E1 12.3E0 这些都可以用指数去表示同一个数;那么这同一个数就漂浮来漂浮去;不确定具体的表现形式;所以带小数点的数也叫浮点数;
标准指数式:
所以为了避免这一情况;咱们必须把这种储存方式规范化;就是储存时根据字节分为三个区域 第一区域表示符号 ;第二个区域表示小数;然后第三个区域表示指数大小;所以就是在小数区域里面;小数点前面必须是0;小数点后面必须不为0;这样得出的一个数值就是标准化的储存方式;
浮点数
储存方式:以规范化的二进制数指数形式存放在储存单元的。(见下图)
储存大小:见下图右边三列
前面这些决定整数型常量的数据类型。
下面要储存这些常量,就要定义相应的变量的数据类型;
变量的数据类型见表左边第一栏。
1.对于某种具体类型,比如float。它具有四个字节,32bit . 他具体三个区域各分配多少字节,是由编译系统自行决定的。 2.由于二进制形式表示一个实数以及储存单元的长度是有限的, 因此不可能得到完全精确的数值,只能储存有限的精确度。 小数部分,实数的有效数字就多。指数部分越大,范围就大。 所以对于三种类型的有效数字以及范围见上表。
3.4 数据类型的转换
为什么要类型转换?
对于任意一个数值 345 还是345.0 你知道是整型还是实型 ,但是你不知道电脑是究竟把他当int ,long ,还是long long。
但是电脑会自动默认一种,比如如果电脑默认345.0是双精度型。
float a=345.0时就会出现警告,不是错误。这里警告会精度丢失,怎么才能不出现精度丢失呢?
注意 对于一个表达式而言,电脑是如何实现数据转换; 里面有很多的变量,有些变量之间所定义的类型也是不同的.比如a+b+c; 如果你定义的a是int ;b是float ;c是double ;你会发现这是不是处理起来非常的复杂; 怎么处理究竟是以哪一个数值为依据的呢;电脑会进行判断;判断哪一个才是精度最高的; 然后会把所有其他的数据转换成精度最高的数据;比如int 3会变成 3.0再变成双精度的3.0;char 先用ascall 码转变成整数型再把转化成双精度; 最后输出精确度最高的;
1.放在数值之后
在345.0后面加一个f float a=345.0f这样就在赋值之前强制转换了;
2.强制转换运算符()
(类型)(表达式)
举例: 说过%左右两边只能用整数; 那么遇到%左边不是整数怎么办呢; 比如就是 (int)(x+y)%5 这样的话就可以解决这个问题了;
3. 不同类型数值赋值的转换原理
最后最后也是最重要的;赋值的时候如果是同类型的就直接赋值了;如果是不同类型的怎么办;
分类: 1.浮点型》》》》》整型:舍弃小数;然后赋值,此时以补码储存; 2.整型》》》》》》浮点型:先把23 转化23.0;就是把整型先转化成浮点型 在赋值给变量,此事以指数储存; !!?3.double》》》》float:就是15个有效数字只取6个; 把原本8位的数截断后放到4个字节里面;但是有可能截断之后还是放不进去; 这就出现了错误;; !!?占有字节多整型》》》占有字节少的整型:拦腰截断 直接赋值; 但是长的赋给短的 短的范围里面不能够接受;就是截断后长的还不在短的范围里面 那么就会出现错误;输出错误结果;即失真; 像这种比较麻烦;;;其实我知道你还是不能明白透彻; 4.double》》》》float:就是把原本6个有效数字拓展到15位;四个字节放到8个字节里面; 5.字符型》》》整型:先把转化成整数 ;通过ascall
3.5 运算符
学习运算符,了解运算符的主要功能 && 先后顺序。
括号=>单目运算符=>算术运算符=>赋值运算符;
3.5.1 初等运算符
首先是( ):圆括号 :自左向右
3.5.2 单目运算符
自右向左 !:逻辑运算符 ++:自增运算符 --:自减运算符 -:符号运算符 (类型):类型转换运算符 *:指针运算符 &:取地址运算符 注意: 这里咱们要中点讲解一下自增和自减; 以自增举例子;i++和++i有什么区别呢; 首先i++他是先处理i再加上1;然而++i是先加上1然后处理i; 我们具体用一个实例举例子; i=3;printf("%d",++i);输出4;;;如果是i++输出的就是3 ps:自增和自减运算符一般都最好只对一个变量使用; 又是对于表达式比较复杂的咱们适当的加一加括号啥的,使它更加直观,避免二义性;
3.5.3 算术运算符
自左向右 *:乘法运算符 /:除法运算符 %:求余运算符 +:加法运算符 -:减法运算符 先乘除 后加减 注意: 1.首先是除法; 就是两个实数相除,输出的结果是一个双精度的实数;没必要取不取整数; 但是对于整数除以整数而言;他必须要取整数; 如果两个都是整数的话;向0在取整数; 如果其中之一有负数的话是向0取还是向更小的负数去取证决定具体的编译系统本身; 2.取余数 取余数必须两边都是整数;结果是余数;
3.5.4 赋值运算符
自右到左 =:赋值运算符
3.5.5 逻辑运算
3.5.6 位运算
3.5.7 深度剖析位运算
详细运算符见下表:
3.6 c语言表达式处理的过程
举例:
int i=3; float f=2.5; double c=7.5; 处理10+‘a’+i*f-d/3 电脑是怎么处理他的; 自左向右开始扫描; 10+‘a’首先a通过ascall码进行转换成整数型;然后相加;得到结果107; 然后遇到107+i*f首先处理乘法 乘法的优先顺序大于加减;i一个是单精度 一个是双精度怎么办就是电脑此时会将单精度转成双精度;然后算出一个双精度的数 然后这个双精度的数值会和107相加;此时107会转化成双精度的数值; 得出一个双精度结果114.5; 最后114.5与d/3相减 同样的方法我不解释了;最后得出一个双精度的数值;;
3.7语句
一个程序往往由预处理指令加 数据声明 再加一个个函数构成; 函数是由函数首部 加函数体构成; 函数体里面又有数据声明加执行部分; 而这个执行部分就是咱们说的语句;
咱们语句分为五大类
首先控制语句: if ()...else ... for()... while().... do...while() continue break switch return goto
函数调用语句就是函数加上一个分号; opp(a,b);
表达式语句;表达式语句就是表达式加上一个分号; a=b+c;
然后是空语句 就是没有语句加上一个分号; ;
复合语句;复合语句由各种各样的语句和一些声明括起来;
3.7.1 赋值语句
1.赋值运算符
=; -=; +=; *=; %=; /=; 注意: 1.后面是什么意思呢;举个例子你就明白了;a+=b;就是a=a+b;然后其他都是同理;
2.赋值表达式
变量 赋值运算符 表达式 ;
注意:
1.这里我强调一下左值右值的问题对于赋值语句左值一般指被赋值的;右值一般指赋值的;左值右值是相对而言的;对于a=b=c而言;b=c的时候b是左值 c是右值 ;a=b时a是左值 ;b是右值;
2.对于赋值表达式一般就是自右向左执行;
3.对与赋值语句和赋值表达式 你可以把赋值表达式放在别的语句里面;但是你不能把赋值语句放在别的语句中;
/*举例子*/;
if((a=b)>0) max=a;是正确的; if((a=b;)>0) max=a;是错误的;
3.赋初值
对于变量赋初值 int a=3;
就是先声明a; 结束后执行a=3是在执行部分完成;
3.7.2 printf输出函数
输出语句printf()是一个函数 其一般格式为
printf(格式控制,输出表列);
printf("a=%d",i);
printf(参数1,参数2,参数3…);
这儿参数1就是格式控制 ;这个必须有,参数2 参数3可以省略;
printf("please tell me why?");
1.格式控制;
格式控制用双引号 括起来然后就是里面包括一些 普通字符 和 控制字符;
”a=%d“;就是一个例子; 然后就是a=都是普通字符;普通字符还包括 空格 换行 逗号等等都可以; 控制字符单独说;
控制字符
%d %i:首先它输出的是一个有符号的!!!十进制!!!!整数!!! %5d 5是指区域宽度 是五个空格;然后其数值就是自右向左第一位开始输出数值;如果想自左向右则:%-5d;; 如果想输出其他整型比如%ld;%lld %c:输出一个字符!!在0-127内正常输出;如果超出了这个范围就按照127对应的字符输出; %s:输出的是字符串;不输出双引号; %f:用来输出实数;一般输出六位;;那你肯定会问是输出double 还是 float 我想说你输出什么就是什么; 只不过这儿就是在没有限定的情况下只有六位而已; 当然你可以限定; %m.nf; m是指总的区域宽度;而后面n是指小数点后面的数字位数;一般从右往左填充; 也可以从左往右填充;变成%-m.nf即可; %e %E;指定以指数的形式输出实数;那么就是输出的指数就是有一个标准化形式;就是小数点之前必须只有一个非0数字;右边只准6位;e E用哪个取决于%e %E用哪个;在其后面有一个空位输出符号正还是负数;然后有三个空位;输出指数大小; %o:以八进制!!整数输出;八进制是没有正负的; %x %X:以十六进制输出整数: %u:输出无符号型号的数据 一般用于 unsigned %g %G: 输出的实数 系统会根据谁输出简便自己去判断输出%f还是%e;那个无意义0少,就输出那个;
2.输出表列
就是变量;或者表达式之类都可以;
3.7.3 scanf输入函数
scanf();也是一个函数;
调用的一般格式为
scanf (格式声明,地址表列);
格式声明与printf一样;包括普通字符和格式字符;但是要注意要一一对应;
哪怕是一个空格;逗号;地址表列就是&a 变量前面加& 表示输入到这个地址;
3.7.4 putchar 与getchar 函数
putchar(c);输出一个字符;包括控制字符也可以; getchar(c);输入一个字符;包括控制字符也可以; 注意: 1.在输入时候 你输入电脑上的数字在没有按下enter的时候他是放在缓冲区里面的;处理系统还没有接受;按下后 按先后顺序一个一个接受字符空格 控制字符也算; 2.这个c可以是什么 字符常量;整型常量;字符变量 ;整型变量;
3.8例题
例题一:给出三角形三个边求解三角形的面积
/**/ #include <stdio.h> #include <math.h> int main () { double a,b,c,s,area; a=3.67; b=5.43; c=6.21; s=(a+b+c)/2; area=sqrt(s*(s-a)*(s-b)*(s-c)); printf("a=%f\tb=%f\tc=%f\n",a,b,c); printf("area=%f\n",area); return 0; } 首先咱们看这个例子有那些不明白的; 首先是#include 这同样是预编译处理的调用文件;这是一个数学库函数;是因为下面有sqrt()这个函数; 这个函数是从这个预处理文件中直接调用的; 完了,还有很多\t ;啥是\t 就是输出位转到下一个tab位置输出; 你坑定会问什么是tab位置 八个空格一个tab区 一个制表 你姑且就记住这么多就行了;而\t就是转到下一个tab区开头; 无论原本这个数在tab区的第几位; 从这串代码中你发现函数体里面的执行部分大部分都是包含赋值语句的;