第三章 数据和C

时间:2024-04-13 20:53:01

一、示例程序

/*platinum.c ---your weight in platinum*/
#include <stdio.h>
int main(void)
{
	float weight;    /*your weight*/
	float value;     /*equal to your weight*/
	printf("Are you worth your worth in platinum\n"); 
	printf("Let's check it out\n");
	printf("Please enter your weight in pounds:\n");
	/*获取用户输入*/
	scanf("%f", & weight);
	/*%f 用于读取键盘的输入,&weight b把输入的值赋值给weight变量。&寻找weight变量地点*/
	/*假设白金的价格是每盎司$700*/
	/*14.5833用于把每英镑常衡盎司转换为金衡盎司*/
	value = 1700.0 * weight * 14.5833;
	printf("Your weight in platinum is worth $%.2f\n", value);
	/*%f 浮点数占位符  数字2代表精确度--百分位*/
	printf("You are easily wroth that !If platinum prices drop,\n");
	printf("eat more to maintain your value.\n");
	getch();
	return 0;
}

二、变量与常量数据

变量variable
常量constant

三、数据型关键字

(一)常用数据类型关键字

int long short unsighed sighed这五个提供基本整数类型的变式
float double  以及long double表示带小数点的数
char
void  _Bool  _Complex  _Imaginary

其中char关键字用于指定字母和其他字符(#,$,*,%)也可以用来表示表较小的整数
_Bool 表示布尔值
_Complex表示复数
_Imaginary表示虚数

(二)位、字节、字

位、字节、字用于描述计算机数据单元或存储单元的术语。这里主要是指存储单元。
位(bit)存储0和1.是计算机内存的基本构建块。
字节(byte)是常用的计算机存储单元。对于几乎所有的机器,1字节 = 8位(C语言有不同的定义)
字是设计计算机时给定的自然存储单元。计算机的字长越大,其数据转移越快,允许的内存访问也更多。

(三)整数

整数以二进制方式存储在计算机中。整数和浮点数不同在于存储方式。

(二)浮点数

浮点数以e计数法(科学计数法)存储时,如:3.16E7表示3.16乘以10的7次方。
计算机把浮点数分为小数部分和指数部分来表示,而且分开存储。
浮点数表示的范围比整数大(整数没有小数部分,浮点数有小数部分)

四、C语言基本数据类型

(一)int类型

int是有符号整形可以是正整数,负整数和零
1、声明方式:
声明为变量创建和标记存储空间,并为其指定初始值。
- int erns;
- int hogs, cows, goats;
2、获取值的方式:
- 赋值crows = 12;
- 函数(如:scanf())
- 初始化变量
	初始化可以直接在声明中完成,
	int hogs = 21;
	int cows = 45, goats = 14;
	int dogs = ,cats = 78;       //在这个时候,实际上只初始化了变量cats。
初始化变量时,不要把未初始化的变量和初始化的变量放在同一条声明中
3、int类型常量
4、打印int值
/*print1.c--演示print()的一些特性*/
#include <stdio.h>
int main(void)
{
	int ten = 10;
	int two = 2;
	printf("Doing it right: ");
	printf("%d minus %d is %d\n", ten, 2, ten - two);
	printf("Doing it wrong: ");
	printf("%d minus %d is %d\n", ten);    ////遗漏两个参数
	getch();
	return 0;
}

5、八进制和十六进制 
8和16是2的幂,在表达计算机相关的值时很方便。
十六进制表示为0x或0X
八进制表示为015;

6、显示十六进制和八进制
不同进制需要使用不同的转换说明。
1)以十进制显示的数字,使用%d,
2)以八进制显示的数字,使用%o;
3)以十六进制显示数字,使用%x;

要显示不同进制的前缀0、0X、0x分别使用以下方式%#o、%#x、%#X

(二)其他整数类型

C语言提供3个附属关键字修饰基本整数类型:short,long,unsigned

  • short int(简写成short)占用的存储空间比int少,属于有符号类型;
  • long int(l简写long)占用的存储空间比int多,属于有符号数据类型;
  • long long int(简写成long long)占用的存储空间比int多,属于有符号数据类型;
  • unsigned int(unsigned)只用于非负值。可获取更多的正值范围。还有unsigned short, unsigned long , unsigned long long
  • signed int(signed)只用于非正值。以获取更多的负值范围。还有signed short, signed long , signed long long
1、声明其他整数类型
long int estine;
long johns;
short int erns;
short ribs;
unsigned int s_count;
unsigned players;
unsigned long headcount;
unsigned short yesvotes;
long long ago;
2、使用多种整数类型的原因

C语言规定了最低值。二个人计算机发展16位32位64位,导致各整数类型之间有重叠。
int 类型优先考虑unsigned类型,常用语计数,并且unsigned表示更大的数
尽量避免使用long ,但如需使用,则必须使用,以适用底层级位数的电脑。

3、long常量和 long long常量

从int --long ----unsigned ----unsigned long— long long --unsigned long long
并且适用于八进制数和十六进制数(均被视为int型 )
/*编译器以long类型储存一个小数字 */。应该在值的末尾加上L。在16位系统中可以储存为7,在32位系统中则,储存为7L。并且这种方式适用于八进制和十六进制(如,020L和0X10L)
在支持long long类型的系统中用LL后缀表示long long,U或u后缀表示unsigned long long(如: 5ull, 10LLU,6LLU,9Ull)
整数溢出

/*toobigs --超出系统允许的最大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);
	getch();
	return 0;
}

输出为

2147483647 -2147483648 -2147483647
4294967295 0 1
4、打印short,long, long long,signed类型
unsigned int 类型的值    %u

十进制打印long整形        %ld
在十六进制中打印long整形   %lx     //在转换说明中只能用小写
在八进制中打印long整形  %lo	

十进制打印short整形      %hd
八进制打印short整形      %ho
十六进制打印short整形      %hx

h和l前缀都可以和u一起使用,表示无符号类型。如:%lu
%llu    %lld

**使用printf()函数时,切记检查待打印的值都有对应的转换说明**

(三)char类型(使用字符)

char类型用于储存字符(字母和标点符号)
在C语言中,用单括号引起来单个字符被称为字符常量。

  • 1、声明
    char grade; //声明char类型变量
    grade = ‘T’ ; //为grade赋值,‘T’时字符常量
    grade= T ; //错误,T为变量。
    grade = “T”; //错误,T为字符串

  • 2、初始化
    char big_m = ‘M’;

    实际上字符是以数值形式储存的,所以也可以使用数字代码值来表示。但是并不建议这样操作。

  • 3.、非打印字符
    单引号只适用于字符、数字和标点符号。一些代表行为的字符(如退格,换行、终端响铃或峰鸣。)适用于以下方式:

    • 1)使用ASCII码,峰鸣是7,
      char beep = 7;
    • 2)使用特殊的符号序列表示一些特殊的字符——转义序列。把转义序列赋值给字符变量时,必须用单引号把转义序列括起来。
      例如:char nerf = ‘\n’;
      打印效果是另起一行
      常用转义序列
      \a 警报(ANSI C)
      \b 退格
      \f 换页
      \n 换行
      \r 回车
      \t 水平制表符
      \v 垂直制表符
      \ 反斜杠(\)
      ’ 单引号
      " 双引号
      ? 问号
      \0oo 八进制(oo必须是有效的)
      \xhh 十六进制(hh必须是有效的)
    • 3)十六进制形式表示字符常量,即反斜杠后面跟一个X或x,再加上1~3位十六进制数字。
      第三章 数据和C
      printf("Gramps sez,“a\ is a backslash”“n”)——为何没有单引号把转义序列括起来?
      双引号括起来的字符集合叫做字符串;
      建议一般使用字符表示,特殊情况使用ASCII进行标注
    • 4)打印字符
      字符的转换说明为%c。
      printf()函数中的转换说明决定了数据的显示方式,而不是数据的储存方式
/*charcode.c显示字符的代码编号*/
#include <stdio.h>
int main(void)
{
	char ch;
	printf("Please enter a charcater.\n");
	scanf("%c", &ch);  /*用户输入字符,并赋值给字符变量ch*/
	printf(" The code for %c is %d\n", ch, ch );
	getch();
	return 0;
}
  • 5)有符号还是无符号
    不同编译器,实现方式不同。定义不同。需要查阅相应的编译器手册,或者查阅limits.h头文件
    或者在char前面使用signed或者unsigned做有符号或是无符号处理。

(四)_Bool类型

通布尔类型克选择执行哪部分代码

(五)stdint.h和inttypes.h(可移植类型)

不明觉厉。有机会重看。先贴上代码。
在这里插入代码片

再贴上结果

First, assume int32_t is int
me32 = 4933945
Next, let's not make any assumption.
Instead, use a "macro" from inttypes.h:
me32 = 4933945

(六)float、double和long double

浮点数能表示包括小数在内的更大范围的书,用指数(e)计数法表示(非常大或者非常小);
  • float类型必须至少能有6位有效数字,取值范围至少是10-37~10+37。

  • double类型至少必须能表示10位有效数字

  • long double

    1、声明和初始化浮点型变量
    float noah, jonah;
    double trouble;
    float planck = 6.63e-34
    long double gnp;
    2、浮点型常量
    基本形式:有符号的数字(包括小数点),后面紧跟E或e,最后一个是有符号数表示10的指数。如下:
    -1.56E+12;
    2.87e-3;
    其中,正号可以省略。可以没有小数点(如,2E5)或指数部分(如,19.28),但不能同时省略(小数部分和指数部分)。可以省略整数部分(如,.45E-6)或小数部分(如3.E16),但不能同时省略(整数部分和小数部分)。
    常见的浮点常量表示:
    3.14159
    4e16
    .8E-5
    100.
    浮点型常量中间不能加空格

  • 在浮点数后面加上f或F,编译器识别为float类型,如,2.3f和9.11E9F。

  • 编译器默认浮点型为double

  • long double 在浮点数后面加l或L识别。如,54.3l和4.32L(建议使用L

  • 十六进制表示浮点型常量。在十六进制数前加上十六进制前缀(0x或0X),分别用p和P代替e和E,用2的幂代替10的幂(p计数法)。如:0xa.1fp10。
    3、打印浮点值

      - 1)十进制格式:
      printf()函数用%f转换说明打印float和double类型。
      %e打印指数计数法浮点数。
      - 2)十六进制格式
      用a和A分别代替E和e。
      打印long double使用%Lf,%Le或%La转换说明。
    

    4、上溢和下溢
    上溢

      计算导致数字过大超过当前能表达的范围是,就会发生上溢。这种情况下会给变量附一个无穷大的特定值。printf()显示该值为inf或infinity
    

    下溢

      当除以一个极小数时,虽然会得到结果,但是在计算过程中却损失了原末尾有效数上的数字。
    

    NaN

      not a number
    

    浮点舍入错误

      给定一个数,+1,再-1
    
/*floaterr.c——演示舍入错误*/
#include <stdio.h>
int main(int argc, char const *argv[])
{
	float a, b;
	b = 2.0e20;
	a = b - 2.0e20;
	printf("%f \n", a);
	getch();
	
	return 0;
}

浮点数表示法

(七)复数和虚数类型

实数部分表示float_Complex、double_Complex、long double_Complex
虚数部分表示float_Imaginary、double_Imaginary、long double_Imaginary
如果包含complex.h头文件,可用complex代替Complex,用I代替-1的平方根。

(八)其他类型

	数组、指针、结构和联合

(九)类型大小

使用**sizeof()**函数查看指定类型的大小,printf()函数中使用%zd,%u,%lu转换说明匹配sizeof()返回类型。

/*typesize.c——打印类型大小*/
#include <stdio.h>
int main(void)
{
	/*C99为类型大小做%lu说明*/
	printf("Type int has a size of %lu bytes.\n", sizeof(int));
	printf("Type char has a size of %lu bytes.\n", sizeof(char));
	printf("Type long has a size of %lu bytes.\n", sizeof(long));
	printf("Type long long has a size of %lu bytes.\n", sizeof(long long));
	printf("Type double has a size of %lu bytes.\n", sizeof(double));
	printf("Type long double has a size of %lu bytes.\n", sizeof(long double));
	printf("Type float has a size of %lu bytes.\n", sizeof(float));
	getch();

	return 0;
}

结果如下:

Type int has a size of 4 bytes.
Type char has a size of 1 bytes.
Type long has a size of 4 bytes.
Type long long has a size of 8 bytes.
Type double has a size of 8 bytes.
Type long double has a size of 12 bytes.
Type float has a size of 4 bytes.

五、使用数据类型

(一)声明

	声明变量时必须选择有含义的变量名
	初始化变量应使用与变量类型匹配的常数类型。
	把一个类型的数值初始化给不同类型变量时,编译器会把值转换成与变量匹配的类型,导致部分数据丢失。

(二)命名约定

	在变量中体现其类型。如:i_ 前缀表示int类型,us_代表unsigned short类型

六、参数和陷阱

	**一个字符串就是一个参数**
  • C语言中用逗号分隔函数中的参数
  • C语言通过函数原型机制检查函数调用时参数格式的个数和类型是否正确。
  • C语言中printf()函数和scanf()函数与其他函数不同,其参数个数可变。
  • 程序员要确保转换说明的数量、类型与后面参数的数量、类型相匹配。

七、转义序列示例

/*escape.c——使用转义序列*/
#include <stdio.h>
int main(void)
{
	float salary;
	printf("\aEnter your desired monthly salary: ");   /*1*/
	printf("$____\b\b\b\b\b\b\b\n");    /*2*/
	scanf("%f", &salary);
	printf("\n\t$%.2f a month is $%.2f a year.", salary, salary * 12.0);   /*3*/
	printf("\rGee!\n");                     /*4*/
	getch();
	return 0;	
}

(一)程序运行情况

(二)刷新输出

	缓冲区??

八、关键概念

  • 1、浮点数和整数在本质上不同,区别主要在于存储方式和运算过程。

九、本章小结

  • 基本数据类型:整数型和浮点型

    整数型:

      通过为类型分配的储存量以及是有符号还是无符号,区分不同整数类型。
    

    浮点型:

      float、double和long double。并可通过关键字_Complex和_Imaginary组合实现复数类型。
    

    进制

      八进制、十进制、十六进制通过前缀0x和0X表示,通过前缀ll或LL表示long long型,l或L表示long型
    
  • 字符常量

      单引号表示字符。转义序列表示非打印字符。
    
  • 转换类型

      %+各类字符
    

十、复习题

1、指出下面各种数据使用的合适数据类型(有些可使用多种数据类型)

	a.East Simpletion的人口;						//unsigned long 	、long
	b.DVD影碟的价格									//float  unsigned char
	c.本章出现次数最多的字母(字)						//char,unsign char
	d.本章出现次数最多的字母次数。						//int

2、在什么情况下要用long类型的变量替代int类型的变量?

3、使用那些可移植的数据类型可以获得32位有符号整数?选择的理由是什么?

4、指出下列常量的类型和含义(如果有的话):

	a.'b’					
	b.2016
	c.99.44
	d.0XAA
	e.2.0E30

5、Dottie Cawm编写了一个程序,请找出程序中的错误。

include <stdio.h>    			//头文件以#开始
main								//函数 返回值类型、参数未定义
(										//应使用{}包含函数体
	float g; k;						//声明多个变量,用逗号;
	float tax, rate;				
	g = e21;						//浮点数常量不能同时省略整数部分和小数部分
	tax = rate * g;				//rate没有初始值
	

)

6、写出下列常量在生命中使用的数据类型和在printf()中对应的转换说明:

第三章 数据和C
第三章 数据和C

7、写出下列常量在生命中使用的数据类型和在printf()中对应的转换说明(假设int位16位):

第三章 数据和C
第三章 数据和C

8、假设程序的看开头有下列声明:

int imate = 2;
long shot = 53456;
char grade = ‘a’;
float log = 2.71828;

把下面printf()语句中的转换字符补充完整:

printf("The odds against the %_ were %_ to 1.\n", imate, shot);    //d     d
printf("A score of %_is not an %_ grade.\n", log, grade);         //f   c

9、假设ch是char类型的变量。分别用转义序列、十进制值、八进制字符常量和十六进制字符常量赋值给ch(假设使用ASCII编码值)。

ch = '\r'

ch = 13

ch = '015'

ch = '\0xd'

10、修正下面的程序(在C中, /表示除以)。

												        //缺少头文件					
void main(int)     //this promgram is perfect            //main()函数参数,和返回值类型错误
{
	cows,legs integer;								
	printf("How many cow legs did you count?\n")
	scanf("%c", legs); 									//%c转换说明指的是char类型。
	cows = legs / 4;
	printf("That implies there are %f cows.\n", cows)     //int类型的转换说明为%d
														//缺少return
}

修正后的代码:

#include <stdio.h>   /*修正后的求牛的数量*/
int main(void)    //this promgram is perfect
{
	int cows;
	int legs;
	printf("How many cow legs did you count?\n");
	scanf("%d", &legs);
	cows = legs / 4;
	printf("That implies there are %d cows.\n", cows);
	getch();
	return 0;
}

11、指出下列转义序列的含义:

a.\n    		换行符
b.\\			\	
c.\"	    	"
d.\t			制表符

十一、编程练习

1.通过试验(即编写带有此类问题的程序)观察系统如何处理整数上溢、浮点数上溢和浮点数下溢的情况。

/*test_1.c——测试整数上溢、浮点数上溢和浮点数下溢的情况。*/
#include <stdio.h>
int main(void)
{
	int i_upoutter;
	float f_upoutter;
	float f_downner;
	i_upoutter = 4567891256;
	f_upoutter = 2.45E20;
	f_downner = 2.32E3;
	printf("This is number %d\n", i_upoutter + 1);
	printf("Let's find out a float outter %f\n", f_upoutter + 1);
	printf("Let's find out a float lower %f\n", 2 / f_downner); 
	getch();
	return 0;
}

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

/*test_02-——将输入的ASCII码值转换为字符*/
#include <stdio.h>
int main(void)
{
	char c_single_word;
	printf("Please enter a ASCII number: \n");
	scanf("%d", &c_single_word);
	printf("%c is this what you want?\n", c_single_word);
	printf("Thanks\n");
	scanf("Y or N\n");			//如何让输入显示在thanks之前???
	
	getch();
	return 0;
}

3.编写一个程序,发出一声警报,然后打印下面的文本:

Startled by the sudden sound, Sally shouted,
"By the Great Pumpkin, what was that!"
/*test_03.c——发出一声警报,然后打印文本*/
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
	printf("\a");
	printf("Startled by the suddensound, Sally shouted, \n");

printf("\"By the Great Pumkin,what was that!\"\n");
	getch();
	return 0;
}

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

Enter a floating-point value: 64.25
fixed-point notation: 64.250000
exponential notation: 6.425000e+01
p notation: 0x1.01p+6
/*test_04.c——浮点数不同性的打印*/
#include <stdio.h>
int main(void)
{
	float f_float;
	f_float = 64.25f;
	printf("Enter a floating-point value:    %f\n", f_float);
	printf("fixed-point notation:  %6f\n", f_float);
	printf("exponential notation:   %e\n", f_float);
	printf("p notation:  %a\n", f_float);
	getch();
	return 0;
}

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

/*test_05.c——年龄对应的秒*/
#include <stdio.h>
int main(void)
{
	double d_seconds;
	int age;
	d_seconds = 3.156E7;
	printf("Please input your age: ");
	scanf("%d", &age);
	printf("You have servived %f senconds\n", d_seconds * age);
	getch();
	return 0;

}

6.1个水分子的质量约为3.0×10−23克。1夸脱水大约是950克。编写一个程序,提示用户输入水的夸脱数,并显示水分子的数量。

#include <stdio.h>
int main(void)
{
	double d_h2o;
	int i_water_weight = 950;
	d_h2o = 3.0e-23;
	float f_water_num;
	printf("Please input how much water you  want:   ");
	scanf("%f", &f_water_num);
	printf("This is the vlaue of water  %e", d_h2o * i_water_weight * f_water_num);
	
	return 0;
}
	
	

7.1英寸相当于2.54厘米。编写一个程序,提示用户输入身高(/英寸),然后以厘米为单位显示身高。

#include <stdio.h>
int main(void)
{
    float  f_inner, f_height;
    f_inner = 2.54;
    printf("Please input your height:   ");
    scanf("%f", &f_height);
    printf("This is your height:  %f", f_inner * f_height);
    return 0;
}

8.在美国的体积测量系统中,1品脱等于2杯,1杯等于8盎司,1盎司等于2大汤勺,1大汤勺等于3茶勺。编写一个程序,提示用户输入杯数,并以品脱、盎司、汤勺、茶勺为单位显示等价容量。思考对于该程序,为何使用浮点类型比整数类型更合适?

#include <stdio.h>
int main(void)
{
	float f_ant, f_big_one, f_small_one;
	float i_cup;
	f_ant = i_cup * 8;
	f_big_one = f_ant * 2;
	f_small_one = f_big_one * 3;
	
	printf("Please enter how many cups u want:   ");
	scanf("%f", &i_cup);
	printf("ant value is %f \n", f_ant);
	printf("The big_one value is %f\n", f_big_one);
	printf("The samll one value is %f \n", f_small_one);
	return 0;
}