2.下面代码会输出c!=d c=1.900000 d=1.900000.分析原因并给出修改方案。
#include<stdio.h>
int main()
{
double a=1.6,b=0.3,c=1.9;
double d=a+b;
if(c==d)
{
printf("c==d");
}
else printf("c!=d c=%lf d=%lf",c,d);
return 0;
return 0;
}
其原因主要出在精度问题,double类型浮点型并不能精确的表示数据,往往在小数点后几位会不相等。
所以需要我们自己去定义一个精度去判断。
#include<stdio.h>
int main()
{
double a=1.6,b=0.3,c=1.9;
double d=a+b;
double x=0.000001;
if((c-d)<=x&&(c-d)>=-x)
{
printf("c==d");
}
else printf("c!=d c=%lf d=%lf",c,d);
return 0;
return 0;
}
3.有关自动类型转换
1.
1) 若参与运算量的类型不同,则先转换成同一类型,然后进行运算。
2) 转换按数据长度增加的方向进行,以保证精度不降低。如int型和long型运算时,先把int量转成long型后再进行运算。
a.若两种类型的字节数不同,转换成字节数高的类型
b.若两种类型的字节数相同,且一种有符号,一种无符号,则转换成无符号类型
3) 所有的浮点运算都是以双精度进行的,即使仅含float单精度量运算的表达式,也要先转换成double型,再作运算。
(所以float和float型运算时,会自动转换为double类型)。
4) char型和short型参与运算时,必须先转换成int型。
5) 在赋值运算中,赋值号两边量的数据类型不同时,赋值号右边量的类型将转换为左边量的类型。如果右边量的数据类型长度左边长时,将丢失一部分数据,这样会降低精度,丢失的部分按四舍五入向前舍入。
2.注意
(1)若运算数中有double型或float型,则其他类型数据均转换成double类型进行运算。
(2)若运算数中最长的类型为long型.则其他类型数均转换成long型数。
(3)若运算数中最长类型为int型,则char型也转换成int型进行运算。算术转换是在运算过程中自动完成的。
下面用一实例说明:
char ch;
int i,result;
float f;
double d;
result=ch/i+(f*d-i);
(1)首先计算 ch/i,ch → int型,ch/i → int型。
(2)接着计算 f*d-i,由于最长型为double型,故f→double型,i→double型,f*d-i→double型。
(3)(ch/i) 和(f*d-i)进行加运算,由于f*d-i为double型,故ch/i→double型,ch/i+(f*d-i)→double型。
(4)由于result为int型,故ch/i+(f*d-i)→double→int,即进行截断与舍入,最后取值为整型。
3.输出转换
在程序中将数据用printf函数以指定格式输出时,当要输出的盐据类型与输出格式不符时,便自动进行类型转换,如一个long型数据用整型格式(%d)输出时,则相当于将long型转换成整型(int)数据输出;一个字符(char)型数据用整型格式输出时,相当于将char型转换成int型输出。
注意:较长型数据转换成短型数据输出时,其值不能超出短型数据允许的值范围,否则转换时将出错。如:
long a=80000;
printf("%d",a);
运行结果为14464,因为int型允许的最大值为32767,80000超出此值,故结果取以32768为模的余数,即进行如下取余运算:
(80000-32768)-32768=14464;
输出的数据类型与输出格式不符时常常发生错误,如:
int d=9;
printf("%f",d);
或
float c=3.2;
printf("%d",c);
将产生错误的结果。
5.对于下面代码段,如何不用if-else语句实现
if(a>b){
max=a;
}
解:
max=a>b?a:max;
while(a>b){
max=a;
}
6.冒泡排序,最差情况的交换次数为()
最差情况及相反(每次都需要交换位置)第一个n-1次第二个n-2......
所以最终结果为: n*(n-1)/2
7.strlen和sizeof的区别
一.sizeof
sizeof(...)是 运算符,而不是一个函数。
一个简单的例子:
int a;
cout<<sizeof a<<endl;
在头文件中typedef为unsigned int,其值在编译时即计算好了,参数可以是数组、指针、类型、对象、函数等。
它的功能是: 获得保证能容纳实现所建立的最大对象的字节大小。
由于在编译时计算,因此sizeof不能用来返回动态分配的内存空间的大小。
实际上,用sizeof来返回类型以及静态分配的对象、结构或数组所占的空间,返回值跟对象、结构、数组所存储的内容没有关系。
具体而言,当参数分别如下时,sizeof返回的值表示的含义如下:
数组——编译时分配的数组空间大小;
指针——存储该指针所用的空间大小(存储该指针的地址的长度,是长整型,应该为4);
类型——该类型所占的空间大小;
对象——对象的实际占用空间大小;
函数——函数的返回类型所占的空间大小。函数的返回类型不能是void。
*****************
二、strlen
strlen(...)是函数,要在运行时才能计算。
参数必须是字符型指针(char*), 且必须是以'\0'结尾的。当数组名作为参数传入时,实际上数组就退化成指针了。
原文链接:https://blog.csdn.net/niushuai666/article/details/7677210
8.在链表中,使用p->访问p结点的数据域,如果不使用“->”符号,如何访问p结点的数据域
解:(*p).data;
->用于结构体指针,而‘.’用于结构体变量。
9.int a[5]={6,3,4,7,9};int *p=a;你能否写出++*p,*p++,*++p,*a++,*++a所对应的值呢?
首先先了解一下优先级:
自增运算符++和指针运算符*的优先级关系为
左++ > * > 右++
比如 ++ *i 相当于 ++ (*i) ,指针i对应的变量+1。
*i ++ 相当于 * (i++) ,指针i,也就是地址值 +1(其实是加1个变量所占的地址空间)
++*p=7(a[0]+1) *p++=a[0]=6 (之后再加一) *++p=a[1]=3 *a++(错误) *++a(错误)。
解析:*a为a的首地址,为一个常量不可改变故不可以对其++。
10.下面的程序功能是:新建tese.txt文件,为其写入字符串“ok”,并从中读取出来。现已知下面程序无法实现该功能。请在横线上填写一行代码,完善此功能。
#include<stdio.h>
int main()
{
FILE *fp=fopen("test.txt","a+");
char s[20]="ok";
fputs(s,fp);
char t[20];
//
fscanf(fp,"%s",t);
puts(t);
fclose(fp);
return 0;
}
这是由于前面的已经读到末尾了,无法继续往下读取,需要用 从开头继续读取。
所以加一个
rewind(fp);