第一篇:4.2 C语言中的强制类型转换
一、自动类型转换
● 字符型变量的值实质上是一个8位的整数值,因此取值范围一般是-128~127,char型变量也可以加修饰符unsigned,则unsigned char 型变量的取值范围是0~255(有些机器把char型当做unsighed char型对待,取值范围总是0~255)。● 如果一个运算符两边的运算数类型不同,先要将其转换为相同的类型,即较低类型转换为较高类型,然后再参加运算,转换规则如下图所示。double ←── float 高 ↑ long ↑ unsigned ↑
int ←── char,short 低
● 图中横向箭头表示必须的转换,如两个float型数参加运算,虽然它们类型相同,但仍要先转成double型再进行运算,结果亦为double型。纵向箭头表示当运算符两边的运算数为不同类型时的转换,如一个long 型数据与一个int型数据一起运算,需要先将int型数据转换为long型,然后两者再进行运算,结果为long型。所有这些转换都是由系统自动进行的,使用时你只需从中了解结果的类型即可。这些转换可以说是自动的,但然,C语言也提供了以显式的形式强制转换类型的机制。● 当较低类型的数据转换为较高类型时,一般只是形式上有所改变,而不影响数据的实质内容,而较高类型的数据转换为较低类型时则可能有些数据丢失。
二、赋值中的类型转换
当赋值运算符两边的运算对象类型不同时,将要发生类型转换,转换的规则是:把赋值运算符右侧表达式的类型转换为左侧变量的类型。具体的转换如下:(1)浮点型与整型
● 将浮点数(单双精度)转换为整数时,将舍弃浮点数的小数部分,只保留整数部分。
将整型值赋给浮点型变量,数值不变,只将形式改为浮点形式,即小数点后带若干个0。注意:赋值时的类型转换实际上是强制的。(2)单、双精度浮点型
● 由于C语言中的浮点值总是用双精度表示的,所以float 型数据只是在尾部加0延长为doub1e型数据参加运算,然后直接赋值。doub1e型数据转换为float型时,通过截尾数来实现,截断前要进行四舍五入操作。
(3)char型与int型
● int型数值赋给char型变量时,只保留其最低8位,高位部分舍弃。
● chr型数值赋给int型变量时,一些编译程序不管其值大小都作正数处理,而另一些编译程序在转换时,若char型数据值大于127,就作为负数处理。对于使用者来讲,如果原来char型 数据取正值,转换后仍为正值;如果原来char型值可正可负,则转换后也仍然保持原值,只是数据的内部表示形式有所不同。
(4)int型与1ong型
● long型数据赋给int型变量时,将低16位值送给int型变量,而将高16 位截断舍弃。(这里假定int型
占两个字节)。
将int型数据送给long型变量时,其外部值保持不变,而内部形式有所改变。
(5)无符号整数
● 将一个unsigned型数据赋给一个占据同样长度存储单元的整型变量时(如:unsigned→int、unsigned long→long,unsigned short→short),原值照赋,内部的存储方式不变,但外部值却可能改变。● 将一个非unsigned整型数据赋给长度相同的unsigned型变量时,内部存储形式不变,但外部表示时总是无符号的。
/*例:赋值运算符举例 */ main(){ unsigned a,b;
int i,j;
a=65535;
i=-1;
j=a;
b=i;
printf(“(unsigned)%u→(int)%dn”,a,j);
printf(“(int)%d→(unsigned)%un”,i,b);}
运行结果为:
(unsigned)65535→(int)-1(int)-1→(unsigned)65535
● 计算机中数据用补码表示,int型量最高位是符号位,为1时表示负值,为0时表示正值。如果一个无符号数的值小于32768则最高位为0,赋给 int型变量后、得到正值。如果无符号数大于等于32768,则最高位为1,赋给整型变量后就得到一个负整数值。反之,当一个负整数赋给unsigned 型变量时,得到的无符号值是一个大于32768的值。
● C语言这种赋值时的类型转换形式可能会使人感到不精密和不严格,因为不管表达式的值怎样,系统都自动将其转为赋值运算符左部变量的类型。
● 而转变后数据可能有所不同,在不加注意时就可能带来错误。这确实是个缺点,也遭到许多人们批评。但不应忘记的是:c面言最初是为了替代汇编语言而设计的,所以类型变换比较随意。当然,用强制类型转换是一个好习惯,这样,至少从程序上可以看出想干什么。
==
在C语言中,不同数据类型的运算对象进行混合运算,或者需要将一个表达式的结果转换成期望的类型时,就需要依据数据类型转换规则进行转换。具体有以下几种情况:
2.8.1各类数值型数据间混合运算时的类型转换规则
整型、实型、字符型数据间可以混合运算。在这种情况下,需要将不一致的数据类型转
换成一致的数据类型,然后进行运算。为了保证运算精度,系统在运算时的转换规则是将存储长度较短的运算对象转换成存储长度较长的类型,然后再进行处理。这种转换是系统自动进行的,具体如图2-9所示。
double ←── float 高 ↑ long ↑ unsigned ↑
int ←── char,short 低
对图2-9的说明如下:
1)纵向箭头表示必定会进行的转换,如float型数据必先转换为double型数据,然后与其他操作数进行运算。与此类似,char型或short型数据必先转换为int型数据,然后进行运算。
2)横向箭头表示当运算对象为不同类型数据时的转换方向,如int型数据与unsigned型数据进行运算,int型转换为unsigned型后方可进行运 算。int型数据与double型数据进行运算,int型直接转换为double型后进行运算,不能理解为先转换为unsigned int型,然后转换为long int型,最后再转换为double型。
2.8.2 赋值时的类型转换
当赋值运算符两侧的类型不同时,需进行类型转换,这种转换也是系统自动进行的。具体转换原则如下:
1)float、double型赋值给int型:直接截断小数。
例如:int i=f+0.6;f的值4.0,右边算术表达式运算后的结果为一个值为4.6的double型数据,根据上述转换原则,直接舍弃小数,所以i的值为4。2)int、char型赋值给float、double型:补足有效位以进行数据类型转换。
例如:float f=4;float为7位有效数字,所以f的值为4.000000。3)char型(1字节)赋值给int型(2字节):数值赋给int的低8位,高8位补0。
4)long int型赋值给int型:long int截断低字节给int型。
5)int 型赋值给long int:赋给long int的低16位,如果int的最高位是0,则long int的高16位全为0;如果int的最高位是1,则long int的高8位全为1(称为“符号扩展”)。
6)unsigned int型赋值给int型:直接传送数值。
7)非unsigned数据型赋值给位数相同的unsigned 数据:直接传送数值。
2.8.3 强制类型转换
除了以上的两种自动类型转换外,在C语言中,允许强制类型转换,将某一数据的数据类型转换为指定的另一种数据类型。强制转换是用强制转换运算符进行的,强制转换运算符为:(类型名),强制转换运算符组成的运算表达式的一般形式为:
(类型名)(表达式)例如:
(int)(x + y)//将x+y的值转换成整型,即取整数部分。(float)x + y //将x转换成单精度型。
强制转换运算符优先级比算术运算符高。同表达式中数据类型的自动转换一样,强制类型转换也是临时转换,对原运算对象的类型没有影响。
例如,已知有变量定义:int b=7;float a=2.5,c=4.7;求下面算术表达式的值。
a+(int)(b/3*(int)(a+c)/2.0)%4;
根据运算符结合性规则,上述表达式要自左之右执行,b/3为2,2*int(a+c)为14,14/2.0为7.0,强制类型转换后为7,7%4为3;a的值2.5与3相加,最终结果为5.5。
第二篇:c语言中swap问题小结
#include
printf(“swap1: x:%d,y:%dn”,x,y);//形参传值,不能交换,实际传过去是拷贝的一份,没改变主函数中x,y swap2(&x,&y);
printf(“swap2: x:%d,y:%dn”,x,y);//不能交换,函数中只是地址交换了下,地址指向的内容没有交换 swap3(&x,&y);
printf(“swap3: x:%d,y:%dn”,x,y);//能交换,地址指向的内容进行了交换 swap4(&x,&y);
printf(“swap4: x:%d,y:%dn”,x,y);//能交换,地址指向的内容进行交换 swap5(&x,&y);
printf(“swap5: x:%d,y:%dn”,x,y);//能交换,地址指向的内容进行交换 return 0;} swap1: x:4,y:3 swap2: x:4,y:3 swap3: x:3,y:4 swap4: x:4,y:3 swap5: x:3,y:4
第三篇:C语言中的文本Txt操作
对于文件使用方式有以下几点说明:
1)文件使用方式由r,w,a,t,b,+六个字符拼成,各字符的含义是:
r(read):
读
w(write):
写
+:
读和写
a(append):
追加
t(text):
文本文件,可省略不写
b(banary):
二进制文件
2)用“r”打开一个文件时,该文件必须已经存在,且只能从该文件读出。
3)用“w”打开的文件只能向该文件写入。若打开的文件不存在,则以指定的文件名建立该文件,若打开的文件已经存在,则将该文件删去,重建一个新文件。
4)若要向一个已存在的文件追加新的信息,只能用“a”方式打开文件。但此时该文件必须是存在的,否则将会出错。
5)在打开一个文件时,如果出错,fopen将返回一个空指针值NULL。在程序中可以用这一信息来判别是否完成打开文件的工作,并作相应的处理。
将一个txt文本里的数排序再输出到另一个文本里
#include“stdio.h” #include“stdlib.h” main(){
FILE *p1,*p2;int a[10],i,j,temp;if((p1=fopen(“E:in.txt”,“r”))==NULL)
{
printf(“cannot open filen”);
exit(0);} if((p2=fopen(“E:out.txt”,“w”))==NULL){
printf(“cannot open filen”);
exit(0);} for(i=0;i<10;i++)fscanf(p1,“%d”,&a[i]);for(i=0;i<10;i++){
for(j=0;j<10-i;j++)
if(a[j]>a[j+1])
temp=a[j+1];
a[j+1]=a[j];
a[j]=temp;}
for(i=0;i<10;i++)fprintf(p2,“%d”,a[i]);}
第四篇:C语言中union应用总结
C语言中union应用总结
定义共用体的类型变量的一般形式为: union 共用体名 {
成员列表; }变量列表; 例如: union data {
int i;
unsigned char c[4];
float f;};union data a;//定义union类型的变量
共用体变量a中的成员i、c、f三个变量在内存中从同一个地址开始存储,即在同一个内存中可以用来存放几种不同类型的数据;共用体变量a所占内存的长度等于最长成员的长度,这里c[4]和f的长度都为4字节。例如进行如下赋值: a.i = 100;a.f = 100.5;那么此时共用体变量a中的成员i已经没有值了,因为存储该值的内存现在已经被用来存储成员f的值了。共用体成员间是共享内存的,对共用体的一个成员赋值,其他成员的值跟着发生变化。利用共用体成员间是共享内存的这一特性,有以下几种应用:
1、在需要将浮点数据转移时,使用共同体,按4个字节的char型数据传输,带来通信效率的提高。一般浮点数发送方法:是将浮点数放大一定的倍数,再取整,再按整数的高低位传输。还需要传输这个放大的倍数,如果浮点数是个负数的话,还要将符号位一并发送。接收方收到这几条报文后,才能将数据还原。但是接收方还原的浮点数据与发送方发送的浮点数不一样,因为小数位数发生变化。使用共同体就不会出现这个问题了,在 接收方,使用共同体,将收到到的4个char数据赋值给a.c数组,a.f就是还原的数据,这个数据和发送的数据是一样的,也不管发送的浮点数是正还是负。如有a.f =-12.34;则a.c[0] = 0xa4, a.c[1] = 0x70, a.c[2] = 0x45, a.c[3] = 0xc1。如有a.c[0] = 0xa4, a.c[1] = 0x70, a.c[2] = 0x45, a.c[3] = 0xc1,则a.f =-12.34。使用这种方式传输浮点数,数据是不会丢失的,报文也更简单。
2、将浮点数保存到文件中时,保存为4个字节的char型数据,节约空间。如果保存为文本需要占用的字节数等于数值的字符的个数,有可能占用1~20字节,而用共用体的char型数据,占用的空间大小固定为4字节,对大量浮点数据的存储,节约的空间更多,分析保存的浮点数也是很方便的。
3、用在强制类型转换上。如将int数据转为float,可以这样使用union: a.i =1234;赋值后,a.f就是转换后的值等于1234。
第五篇:C语言中的EOF
C语言中的EOF EOF是指文件的结束符,是一个宏定义.对于键盘输入来说,getchar()只有在遇到文本结束标记(ASCII编码为26)时才会返回EOF,其它情况都会返回一个输入符号值。所以对于这种程序,要想让循环信息运行,只能输入这个文本结束标记。输入这个标记有多种方法,常用的就是按F6键,或者按Ctrl-Z组合键,或者打开数字小键盘之后按住Alt键再依次按小键盘上的26两个数字键最后放开Alt键,等,都可以输入这个文本结束标记。
借助于getchar 与putchar 函数,可以在不了解其它输入/输出知识的情况下编写出数量惊人的有用的代码。最简单的例子就是把输入一次一个字符地复制到输出,其基本思想如下: 读一个字符
while(该字符不是文件结束指示符)输出刚读入的字符 读下一个字符
将上述基本思想转换为C语言程序为: #include
字符在键盘、屏幕或其它的任何地方无论以什么形式表现,它在机器内部都是以位模式存储的。char 类型专门用于存储这种字符型数据,当然任何整型(int)也可以用于存储字符型数据。因为某些潜在的重要原因,我们在此使用int类型。
这里需要解决如何区分文件中有效数据与输入结束符的问题。C语言采取的解决方法是:
在没有输入时,getchar 函数将返回一个特殊值,这个特殊值与任何实际字符都不同。这个值称为EOF(end of file,文件结束)。我们在声明变量c 的时候,必须让它大到足以存放getchar函数返回的任何值。这里之所以不把c声明成char类型,是因为它必须足够大,除了能存储任何可能的字符外还要能存储文件结束符EOF。因此,我们将c声明成int类型。
EOF 定义在头文件
对于经验比较丰富的C 语言程序员,可以把这个字符复制程序编写得更精炼一些。在C语言中,类似于c = getchar()之类的赋值操作是一个表达式,并且具有一个值,即赋值后左边变量保存的值。也就是说,赋值可以作为更大的表达式的一部分出现。如果将为c赋值的操作放在while循环语句的测试部分中,上述字符复制程序便可以改写成下列形式: #include
c =(getchar()!= EOF)