int类型
int类型的值必须是整数(正负整数、0),储存一个int要占用一个 机器字长(目前用32位储存一个int,未来处理器发展到64位后能储存更大的整数)。
1.声明int变量
方法:先写上int,然后写变量名,最 后加上一个分号。
若要声明多个变量,可以单独声明每个变量,也可在int后面 列出多个变量名,变量名之间用逗号分隔。如:
int erns;
int hogs, cows, goats;
变量如何获得值:
1.赋值,如
cows = 112;
2.通过函数获得值,如
scanf()
2.初始化变量
def:为变量赋一个初始值。
--->可以直接在声明中完成。只需在变量名后面加上赋值运算符(=)和待赋 给变量的值即可。如:
int hogs = 21;
int cows = 32, goats = 14;
int dogs, cats = 94; /* 有效,但是这种格式很糟糕 */
该示例的最后一行,只初始化了cats,并未初始化dogs。这种写法很 容易让人误认为dogs也被初始化为94,所以最好不要把初始化的变量和未初 始化的变量放在同一条声明中。
==》简而言之,声明为变量创建和标记存储空间,并为其指定初始值。
3.int类型常量
整型常量或整型字面量:如21,65,94等
C语言把不含小数点和指数的数作为整数;把大多数整型常量视为int类型,但是非常大的整数除外。
4.打印int值
--->可以使用printf()函数打印int类型的值。
%d称为转换说明,它指定了printf()应使用什么格式来显示一个值。
格式化字符串(def:使用Format函数将指定的字符串转换为想要的输出格式)中的每个%d都与待打印变量列表中相应的int 值匹配。这个值可以是int类型的变量、int类型的常量或其他任何值为int类型的表达式。
//程序清单3.2 print1.c程序
/* print1.c - 演示printf()的一些特性 */
#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); // 遗漏2个参数
return 0;
}
!!-- printf()函数的参数数目不定,所以使用printf()函数时,要确保转换说 明的数量与待打印值的数量相等。
5.八进制和十六进制
==》因为8和16都是2的幂,而10却不是。显然,八进制 和十六进制记数系统在表达与计算机相关的值时很方便。
在C语言中,用特定的前缀表示使用哪种进制。0x或0X前缀表示十六进 制值,所以十进制数16表示成十六进制是0x10或0X10。与此类似,0前缀表 示八进制。例如,十进制数16表示成八进制是020。
使用不同的进制数是为了方便,不会影响数被储存的方式。也 就是说,无论把数字写成16、020或0x10,储存该数的方式都相同,因为计算机内部都以二进制进行编码。
6.显示八进制和十六进制
在C程序中,既可以使用和显示不同进制的数。不同的进制要使用不同 的转换说明。以十进制显示数字,使用%d;以八进制显示数字,使用%o; 以十六进制显示数字,使用%x。另外,要显示各进制数的前缀0、0x和0X, 必须分别使用%#o、%#x、%#X。
//程序清单3.3 bases.c程序
/* 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;
}
该程序以3种不同记数系统显示同一个值。printf()函数做了相应的转 换。注意,如果要在八进制和十六进制值前显示0和0x前缀,要分别在转换 说明中加入#。
char类型
char类型用于储存字符(如,字母或标点符号),但是从技术层面看, char是整数类型。因为char类型实际上储存的是整数而不是字符。
计算机使用数字编码来处理字符,即用特定的整数表示特定的字符。
如,在ASCII码中,整数65代表大写字母A。
1.声明char类型变量
char类型变量的声明方式与其他类型变量的声明方式相同。如:
char response;
char itable, latan;
2.字符常量和初始化
(ASCII 码)
char grade = 'A';
在C语言中,用单引号括起来的单个字符被称为字符常量。编译器一发现'A',就会将其转换成相应的代码值。单引号必不可少。
char broiled; /* 声明一个char类型的变量 */
broiled = 'T'; /* 为其赋值,正确 */
broiled = T; /* 错误!此时T是一个变量 */
broiled = "T"; /* 错误!此时"T"是一个字符串 */
!!—C语言将字符常量视为int类型而非char类型。
3.非打印字符
单引号只适用于字符、数字和标点符号。浏览ASCII表会发现,有些 ASCII字符打印不出来。例如,一些代表行为的字符(如,退格、换行、终 端响铃或蜂鸣)。C语言提供了3种方法表示这些字符。
1.使用ASCII码。例如,蜂鸣字符的ASCII值是 7,因此可以这样写:
char beep = 7;
2.使用特殊的符号序列表示一些特殊的字符。这些符号序列叫作转义序列。
如下表:转义序列及含义
\a:警报字符
\b、\f、\n、\r、\t和\v:常用的输出设备控制字符
\、'、":用于打印\、'、"字符
!!—使用ASCII码时,注意数字和数字字符的区别。例如,字符4对应的 ASCII码是52。'4'表示字符4,而不是数值4。
4.打印字符
printf()函数用%c指明待打印的字符。
程序清单3.5演示了打印char类型变量的两种方式。
//程序清单3.5 charcode.c程序
/* charcode.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;
}
5.有符号还是无符号
在关键字char前面使用signed或unsigned。无论编译器默认char是什么类型,signed char表示有符号类型,而 unsigned char表示无符号类型。这在用char类型处理小整数时很有用。如果只用char处理字符,那么char前面无需使用任何修饰符。
float、double和long double
==》C语言中的浮点类型有float、double和long double 类型。它们与FORTRAN和Pascal中的real类型一致。
浮点数的表示类似于科学记数法:
第1列是一般记数法;第2列是科学记数法;第3列是指数记数法(或称为e记数法)
C标准规定:
float类型必须至少能表示6位有效数字,且取值范围至少是 10-37~10+37;C语言提供的另一种浮点类型是double(意为双精度)
double类型和float类型的最小取值范围相同,但至少必须能表示10位有效数字。
第3种浮点类型是long double,以满足比double类型更高的精度要求。不过,C只保证long double类型至少与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),但是不能同时省略两者。
可以省略小数部分(如,3.E16)或整数 部分(如,.45E-6),但是不能同时省略两者。
--->更多有效浮点型常量栗子:
3.14159
.2
4e16
.8E-5
!!:不要在浮点型常量中间加空格。
3.打印浮点值
一些特性:
printf()函数使用%f转换说明打印十进制记数法的float和double类型浮点数,用%e打印指数记数法的浮点数。
打印long double类型要使用%Lf、%Le或%La 转换说明。
给那些未在函数原型中显式说明参数类型的函数(如,printf())传递参数时,C编译器会把float类型的值自动转换成double类型。
//程序清单3.7 showf_pt.c程序
/* showf_pt.c -- 以两种方式显示float类型的值 */
#include <stdio.h>
int main(void)
{
float aboat = 32000.0;
double abet = 2.14e9;
long double dip = 5.32e-5;
printf("%f can be written %e\n", aboat, aboat);
// 下一行要求编译器支持C99或其中的相关特性
printf("And it's %a in hexadecimal, powers of 2 notation\n",
aboat);
printf("%f can be written %e\n", abet, abet);
printf("%Lf can be written %Le\n", dip, dip);
return 0;
}
4.浮点值的上溢和下溢
计算导致数字过大,超过当前类型能表达的范围时,就会发生上溢。如:
设3.4E38为系统最大float类型值:
float toobig = 3.4E38 * 100.0f;
printf("%e\n", toobig);
以十进制为例,把一个有4位有效数字的数(如,0.1234E-10)除以10,
得到:0.0123E-10。
虽然得到了结果,但是在计算过程中却损失了原末尾有效位上的数字。这种情况叫 作下溢。
特殊的浮点值:NaN(not a number的缩写)
如:给asin() 函数传递一个值,该函数将返回一个角度,该角度的正弦就是传入函数的值。
但是正弦值不能大于1,因此,如果传入的参数大于1,该函数的行为是 未定义的。在这种情况下,该函数将返回NaN值,printf()函数可将其显示为 nan、NaN或其他类似的内容。
浮点数舍入错误
/* floaterr.c--演示舍入错误 */
#include <stdio.h>
int main(void)
{
float a,b;
b = 2.0e20 + 1.0;
a = b - 2.0e20;
printf("%f \n", a);
return 0;
}
原因:计算机缺少足够的小数位来完成正确的运算。
3.11编程练习
- 编写一个程序,发出一声警报,然后打印下面的文本:
Startled by the sudden sound, Sally shouted,
"By the Great Pumpkin, what was that!"
#include <stdio.h>
int main(void)
{
printf("\a");
printf("Startled by the sudden sound, ");
printf("Sally shouted,\n");
printf("\"By the Great Pumpkin, what was that!\"\n");
return 0;
}
- 1个水分子的质量约为3.0×10 −23克。1夸脱水大约是950克。编写一个程序,提示用户输入水的夸脱数,并显示水分子的数量。
#include <stdio.h>
#define MASS_PER_MOLE 3.0e-23
#define MASS_PER_QUART 950
int main(void)
{
double quart, molecules;
printf("Please enter a quart for water:");
scanf("%lf", &quart);
//1夸脱水大约是950克;
//1个水分子质量约为3.0 * 10^(-23)克;
molecules = quart * MASS_PER_QUART / MASS_PER_MOLE;
printf("%g quart water includes %e water molecules.\n", quart, molecules);
return 0;
}