0
点赞
收藏
分享

微信扫一扫

第三章 数据和C

第三章 数据和C.png

示例程序

//platinum.c  ——your weight in platinum
#include<stdio.h>
int main(void)
{
  float weight;         //你的体重
  float value;          //相当重量的白金价值

  printf("Are you worth your weight in platinum?\n");
  printf("Let's check it out.\n");
  printf("Please enter your weight in pounds:");

  scanf("%f",&weight);  //获取用户的输入

  /*假设白金的价格是每盎司$1700
  14.5833用于把英镑常衡盎司转换为金衡盎司*/
  value=1700.0*weight*14.5833;

  printf("Your weight in platinum is worth $%.2f.\n",value);
  printf("You are easily worth that! If platinum prices drop,\n");
  printf("eat more to maintain your value.\n");
  return 0;
}

输出结果:

Are you worth your weight in platinum?
Let's check it out.
Please enter your weight in pounds:156
Your weight in platinum is worth $3867491.25.
You are easily worth that! If platinum prices drop,
eat more to maintain your value.

提示:警告与错误

错误消息表明程序中有错,不能进行编译,而警告则表明,尽管编写的代码有效,但可能不是程序员想要的。警告并不终止编译。

程序中的新元素

  1. 代码中使用了一种新的变量声明:浮点数类型(float),float类型可以存储带小数的数字
  2. 为了打印新类型的变量,在 printf() 中使用 %f 来处理浮点值。%.2f 中的 .2 用于精确控制输出,指定输出的浮点数只显示小数点后面两位
  3. scanf() 函数用于读取键盘的输入。%f 说明 scanf() 要读取用户从键盘上输入的浮点数,&weight 告诉 scanf() 把输入的值赋给名为 weight 的变量。scanf() 函数使用 & 符号表明找到 weight 变量的地点
  4. 本程序中最突出的新特点是他的交互性
  5. scanf()函数读取用户从键盘上输入的数据,并把数据传递给程序;printf()函数读取程序中的数据,并把数据显示在屏幕上

变量与常量数据

常量:在程序使用之前已经预先设定好了,在整个程序的运行过程中没有变化的数据类型

变量:在程序运行期间可能会改变或被赋值的数据类型

位、字节和字

位、字节和字是描述计算机数据单元或存储单元的术语,这里主要指存储单元

最小的存储单元是位(bit),可以存0或1(或者说,位用于存储“开”或“关”)

位是计算机内存的基本构建块
字节(byte) 是常有的计算机存储单位。对于几乎所有的机器,1字节均为8位(1byte=8bit)

字(word) 是设计计算机时给定的自然存储单位,计算机字长越大,其数据转移越快,允许的内存访问也更多

整数和浮点数

整数

和数学的概念一样,在C语言中,整数是没有小数部分的数,计算机以二进制数字存储整数

浮点数

浮点数与数学中实数的概念差不多。2.75、3.16E7、7.00和2e-8都是浮点数

注意:在一个值后面点上一个小数点,该值就成为一个浮点值

3.16E7表示3.16×10^7(3.16乘以10的7次方)

关键要理解浮点数和整数的存储方案不同。计算机把浮点数分成小数部分和指数部分来表示,而且分开存储这两部分

实际区别

  • 整数没有小数部分,浮点数有小数部分
  • 浮点数可以表示的范围比整数大
  • 对于一些算术运算(如:两个很大的数相减),浮点数损失的精度更多
  • 因为在任何区间内(如:1.0到2.0之间)都存在无穷多个实数,所以计算机的浮点数不能表示区间内所有的值。浮点数通常是实际值的近似值

C 语言基本数据类型

1.int类型

int类型是有符号整型,即int类型的值必须是整数,可以是正整数、负整数或零。其取值范围依计算机系统而异

ISO C规定int的取值范围最小为:-32768~32767

变量如何获得值?

  1. 赋值
  2. 通过函数(例如scanf())获得值

初始化变量就是为变量赋一个初始值,C语言中,初始化可以直接在声明中完成,在变量名后面加上赋值运算符(=)和待赋给变量的值即可

声明为变量创建和标记存储空间,并为其指定初始值

第二章中介绍过,%d指明了在一行中打印整数的位置。%d称为转换说明,它指定了printf()应使用什么格式来显示第一个值

程序示例:

#include<stdio.h>
int main(void)
{
  int ten = 10 , two = 2;
  printf("Doing it wrong: ");
  printf("%d minus %d is %d\n",ten);//遗漏两个参数
  printf("Doing it right: ");
  printf("%d minus %d is %d\n",ten,2,ten-two);

  return 0;
} 

输出结果:

Doing it wrong: 10 minus 6422368 is 4201614
Doing it right: 10 minus 2 is 8

第一行输出中由于没有给后两个%d提供任何值,所以打印出来的值是内存中的任意值(运行该程序时显示的这两个数值会与输出示例中的数值不同,因为内存中存储的数据不同,编译器管理内存的位置也不同)

在使用printf()函数时,要确保转换说明的数量与待打印值的数量相等

2.八进制和十六进制

8和16都是2的倍数,八进制和十六进制计数系统在表达与计算机相关的值时很方便0x或0X前缀表示十六进制,所以十进制数16表示成十六进制是0x10或0X10。与此类似,0前缀表示八进制,例如十进制数16表示成八进制是020。

使用不同的进制是为了方便,不会影响数被存储的方式

十进制数:%d

八进制数:%o

十六进制数:%x

另外,要显示各进制数的前缀0、0x和0X,必须分别使用%#o、%#x、%#X。要分别在转换说明中加入#

//bases.c--以十进制、八进制、十六进制打印十进制数100
#include<stdio.h>
int main(void)
{
  int x=100;

  printf("dec = %d; octal = %o; hex = %x\n",x,x,x);
  printf("dec = %d; octal = %#o; hex = %#x\n",x,x,x);

  return 0;
}

编译结果如下:

dec = 100; octal = 144; hex = 64
dec = 100; octal = 0144; hex = 0x64

3.其它整数类型

1.short int类型(或者简写为short)占用的存储空间可能比int类型少,常用于较小数值的场合以节省空间

2.long int或long占用的存储空间可能比int多,适用于较大数值的场合

3.long long int或long long(C99标准加入)占用的存储空间可能比long多,适用于更大数值的场合,该类型至少占64位

4.unsigned int或unsigned只用于非负值的场合。这种类型与有符号类型表示的范围不同,例如,16位的unsigned int允许的取值范围是0~65535,而不是-32768~32767。用于表示正负号的位现在用于表示另一个二进制位,所以无符号整型可以表示更大的数

5.在任何有符号类型前面添加关键字signed,可强调使用有符号类型的意图

4.整数溢出

如果整数超出了相应类型的取值范围会怎样?下面分别将有符号类型和无符号类型的整数设置为比最大值略大,看看会发生什么( printf()函数使用%u说明显示 unsigned int类型的值)

//toobig.c--超出系统允许的最大int值
#include<stdio.h>
int main(void)
{
  int i=2147483647;
  unsigned int j=4294967295;

  printf("%d %d %d\n",i,i+1,i+2);
  printf("%u %u %u\n",j,j+1,j+2);

  return 0;
}

编译结果如下:

2147483647 -2147483648 -2147483647
4294967295 0 1

可以把无符号整数j看作是汽车的里程表,当达到它能表示的最大值时,会重新从起始点开始。整数i也是类似的情况,它们主要的区别是在超过最大值时,unsigned int类型的变量j从0开始;而int类型的变量i则从-2147483648开始。
注意,当i超出(溢出)其相应类型所能表示的最大值时,系统并未通知用户,因此在编程时必须自己注意这类问题

在x和o前面可以使用l前缀,%lx表示以十六进制格式打印long类型整数,%lo表示以八进制格式打印long类型整数

对于short类型,可以使用h前缀,%hd表示以十进制显示short类型的整数,%ho表示以八进制显示short类型的整数

#include<stdio.h>
int main(void)
{
  unsigned int un=3000000000;
  short end=200;
  long big=65537;
  long long verybig=12345678908642;

  printf("un=%u and not %d\n",un,un);
  printf("end=%hd and %d\n",end,end);
  printf("big=%ld and not %hd\n",big,big);
  printf("verybig=%lld and not %ld\n",verybig,verybig);

  return 0;
}

编译结果如下:

un=3000000000 and not -1294967296
end=200 and 200
big=65537 and not 1
verybig=12345678908642 and not 1942899938

使用错误的转换说明会得到意想不到的结果

5.char类型

用于存储字符,从技术层面看char是整数类型,因为char类型实际上存储的是整数而不是字符。计算机使用数字编码来处理字符,即用特定的整数表示

char类型变量的声明方式与其他类型变量的声明方式相同

在C语言中用单引号括起来的单个字符被称为字符常量

char broiled;//声明一个char类型的变量

broiled='T';//为其赋值,正确

broiled=T;//错误,此时T是一个变量

broiled=“T”//错误,此时T是一个字符串

实际上字符是以数值形式存储的,所以也可使用数字代码值来赋值,但这是一种不好的编程风格,例如

char grade = 65;

char grade = ‘A’;

表示非打印字符的方法:

1.使用ASCII码

2.转义字符,把转义字符赋给字符变量时,必须用单引号把转义字符括起来,例如:

char nerf='\n';

转义字符.jpg

打印字符:

printf()函数用%c指明待打印的字符

#include<stdio.h>
int main(void)
{
  char ch;

  printf("Please enter a character.\n");
  scanf("%c",&ch);       //用户输入字符
  printf("The code for %c is %d.\n",ch,ch);

  return 0;
}

编译结果如下:

Please enter a character.
C
The code for C is 67.

有些C编译器把char实现为有符号类型,char可表示的范围是-128~127。有些C编译器把char实现为无符号类型,那么char可表示的范围是0~255

6.float类型

C语言中的浮点类型有float、double、long double类型

浮点数的表示类似于科学计数法

float类型至少能够表示6位有效数字

double类型至少能够表示10位有效数字

浮点型常量的基本形式是:有符号的数字(包括小数点),后面紧跟e或E,最后是一个有符号数表示10的指数

-1.56E+12

2.87e-3

正号可以省略,可以没有小数点(如,2E5)或指数部分(如,19.28),但是不能同时省略两者

可以省略小数部分(如,3.E16)或整数部分(如,.45E-6),但是不能同时省略两者

不要在浮点型常量中间加空格:1.56 E+12(错误!)

默认情况下,编译器假定浮点型常量是double类型的精度,在浮点数后面加上f或F后缀可覆盖默认设置,编译器会将浮点型常量看作float类型,如2.3f和9.11E9F,没有后缀的浮点型常量是double类型

C99标准添加了一种新的浮点型常量格式——用十六进制表示浮点型常量,即在十六进制数前加上十六进制前缀(0x或0X),用p和P分别代替e和E,用2的幂代替10的幂(即,p计数法)。如下所示
0xa.1fp10
十六进制a等于十进制10,.1f是1/16加上15/256(十六进制F等于十进制15), P10是2^10或1024。0xa.1fp10表示的值是(10+1/16+15/256)×1024(即,十进制10364.0)

转换说明符.jpg

浮点数上溢:计算导致数字过大,超过当前类型能表达的范围时就会发生上溢

浮点数下溢:计算过程中损失了原末尾有效位上的数字

如何知道当前系统的指定类型的大小是多少?

sizeof()是C语言的内置运算符,以字节为单位给出指定类型的大小

把一个类型的数值初始化给不同类型的变量时,编译器会把值转换成与变量匹配的类型,这将导致部分数据丢失

编程练习

1.编写一个程序,要求提示输入一个ASCII码值(如66),然后打印输出的字符

#include<stdio.h>
int main(void)
{
  int number;
  printf("Please enter a number from 0 to 127:");
  scanf("%d",&number);
  printf("%d ASCII value is %c\n",number,number);

  return 0;
}

编译结果为:

Please enter a number from 0 to 127:65
65 ASCII value is A

#include<stdio.h>
int main(void)
{
  int input;
  printf("Enter a value of char int ASCII:");
  scanf("%d",&input);
  printf("You input value is %d,and char is %c\n",input,input);

  return 0;
}

编译结果为:

Enter a value of char int ASCII:100
You input value is 100,and char is d

2.编写一个程序,发出一声警报,然后打印下列文本

Starled by the sudden sound,Sally shouted,

"By the Great Pumkin,what was that!"

#include<stdio.h>
int main(void)
{
  char ch='\a';
  printf("%c",ch);
  printf("Starled by the sudden sound,Sally shouted,\n");
  printf("By the Great Pumkin,what was that!\n");  
  return 0;
}

3.一年大约有3.156*10^7秒,编写一个程序,提示用户输入年龄,然后显示该年龄对应的秒数

#include<stdio.h>
int main(void)
{
  int age;
  long long int sec;
  printf("Please enter your age:");
  scanf("%d",&age);
  sec=3.156E7*age;
  printf("The number of seconds for your age is %lld\n",sec); 

  return 0;
}

编译结果为:

Please enter your age:68
The number of seconds for your age is 2146080000

#include<stdio.h>
#define SEC_PER_YEAR 3.156e7
int main(void)
{
  float second,year;
  printf("Enter how many years old you are:");
  scanf("%f",&year);
  second=SEC_PER_YEAR*year;
  printf("You are:%.1f years old.\n",year); 
  printf("And you are %e seconds old, too.\n",second); 

  return 0;
}

编译结果为:

Enter how many years old you are:68
You are:68.0 years old.
And you are 2.146080e+009 seconds old, too.

4.一个水分子的质量约为3.0*10^-23克,1夸脱(1夸脱=0.000946立方米)水大约是950克。编写一个程序,提示用户输入水的夸脱数,并显示水分子的数量

#include<stdio.h>
#define WATER_QUALITY 3.0e-23 
int main(void)
{
  int quart;
  double gram,quantity;
  printf("Please enter the number of quarts of water:");
  scanf("%d",&quart);
  gram=quart*950;
  quantity=gram/WATER_QUALITY;
  printf("The number of water molecules is %lf.\n",quantity); 

  return 0;
}

编译结果为:

Please enter the number of quarts of water:1
The number of water molecules is 31666666666666666000000000.000000.

#include<stdio.h>
#define MASS_PER_MOLE 3.0e-23 
#define MASS_PER_QUART 950
//使用预编译指令定义水分子质量,1夸脱水质量
int main(void)
{
  float quart,quantity;
  printf("Enter how many quart:");
  scanf("%f",&quart);
  quantity=quart*MASS_PER_QUART/MASS_PER_MOLE;//计算水分子数
  printf("There are %e molecules.\n",quantity); 

  return 0;
}

编译结果为:

Enter how many quart:1
There are 3.166667e+025 molecules.

  1. 1英寸相当于2.54厘米,编写一个程序,提示用户输入身高(/英寸),然后以厘米为单位显示身高
#include<stdio.h>
int main(void)
{
  float height,cm;
  printf("Enter your height in inches:");
  scanf("%f",&height);
  cm=height*2.54;
  printf("your height is %f centimeter.\n",cm); 

  return 0;
}

编译结果为:

Enter your height in inches:74.6
your height is 189.483994 centimeter.

#include<stdio.h>
#define INCH_TO_CM 2.54//英寸到厘米的转化系数
int main(void)
{
  float inch,cm;
  printf("Enter the inch of your heigh:");
  scanf("%f",&inch);
  cm=inch*INCH_TO_CM;//将英寸转化为厘米
  printf("Hi ,your are %0.2f inch ,or %.2f cm heigh.\n",inch,cm); 

  return 0;
}

编译结果为:

Enter the inch of your heigh:74.6
Hi ,your are 74.60 inch ,or 189.48 cm heigh.

6.编写一个程序,读取一个浮点数,先打印成小数点形式,在打印成指数形式。然后,如果系统支持,再打印成p计数法(即十六进制计数法)。按以下格式刷出(实际显示的指数位数因系统而异)

Enter a floating-point value:64.25

fixed-point notation:64.250000

exponential notation:6..425000e+01

p notation:0x1.01p+6

#include<stdio.h>
int main(void)
{
  float input;
  printf("Enter a floating-point value:");
  scanf("%f",&input);
  //读取用户的输入,存储至input变量中
  printf("fixed-point notation:%f\n",input); 
  //打印普通形式,转换说明符使用 %f
  printf("fixed-point notation:%e\n",input); 
  //打印指数形式,转换说明符使用 %e
  printf("p notation:%a\n",input);   
   //打印p计数法形式,转换说明符使用 %a
  return 0;
}

编译结果为:

Enter a floating-point value:64.25
fixed-point notation:64.250000
fixed-point notation:6.425000e+001
p notation:0x1.010000p+6

举报

相关推荐

0 条评论