复习题

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

a.East Simpleton的人口
b.DVD影碟的价格
c.本章出现次数最多的字母
d.本章出现次数最多的字母次数
答:
a.int类型,也可以是short类型或unsigned short类型,人口数是一个整数。
b.float类型,价格通常不是一个整数(也可以使用 double类型,但实际上不需要那么高的精度)。
c.char类型。
d.int类型,也可以是unsigned类型。

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

答:
原因之一:在系统中要表示的数超过了int可表示的范围,这时要使用1ong类型。
原因之二:如果要处理更大的值,那么使用一种在所有系统上都保证至少是32位的类型,可提高程序的可移
植性。

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

答:如果要正好获得32位的整数,可以使用int32_t类型。要获得可存储至少32位整数的最小类型可以使int_least32_t类型。如果要为32位整数提供最快的计算速度,可以选择 int_fast32_t类型(假设你的系统已定义了上述类型)。PS:C中的基本数据类型声明定义时,在栈区自动分配或销毁内存,分配的内存大小不同的操作系统不尽相同;可移植的数据类型又称为精确宽度整数类型,增强代码的可移植性。

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

a.’\b’
b.1066
c.99.44
d.0XAA
e.2.0e30
答:
a. char类型常量(但是存储为int类型)PS:C语言将字符常量视为int类型而非char类型,如下

  1. #include <stdio.h>
  2. //编译过程中会警告,因数据被裁减
  3. int main(void)
  4. {
  5. char grade = 'FATE';
  6. //在C语言中,字符常量视为int类型,而非char类型
  7. printf("字符常量的大小:%d\n",sizeof('a'));//4个字节
  8. //只取后八位
  9. printf("grade = %c\n", grade);//输出E
  10. return 0;
  11. }

b. int类型常量
c. double类型常
d. unsigned int类型常量,十六进制格式,PS:前面是答案给出的,但感觉应该是int类型->八进制和十六进制常量存储为正整型
e. double类型常量

常见的整型常量的例子
类型 十六进制 八进制 十进制
char \0x41 \0101 N.A.
int 0x41 0101 65
unsigned int 0x41u 0101u 65u
long 0x41L 0101L 65L
unsigned long 0x41UL 0101UL 65UL
long long 0x41LL 0101LL 65LL
unsigned long long 0x41ULL 01010ULL 65ULL

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

include <stdio.h>
main
(
    float g; h;
    float tax, rate;

    g = e21;
    tax = rate*g;
)

答:
第1行:应该是# include< stdio.h>
第2行:应该是 int main(void
第3行:把(改为{
第4行:g和h之间的;改成,
第5行:没问题
第6行:没问题
第7行:虽然这数字比较大,但在e前面应至少有一个数字,如1e21或1.0e21都可以。
第8行:没问题,至少没有语法问题。
第9行:把 )改成 }
除此之外,还缺少一些内容。首先,没有给rate变量赋值;其次未使用h变量;而且程序不会报告计算结果。虽然这些错误不会影响程序的运行(编译器可能给出变量未被使用的警告),但是它们确实与程序设计的初衷不符合。另外,在该程序的末尾应该有一个return语句。正确的程序如下:

#include <stdio.h>

int main(void)
{
    float g, h;
    float tax, rate;

    rate = 0.8;
    g = 1.0e5;
    tax = rate * g;
    h = g + tax;
    printf("You owe $%f plus $%f in taxes for a total of $%f.\n", g, tax, h);
    return 0;
}

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

答:

常量 类型 转换说明(%转换字符)
12 int %d
0X3 unsigned int %#X
‘C’ char(实际上是int) %c
2.34E07 double %e
‘\040’ char(实际上是int) %c
7.0 double %f
6L long %ld
6.0f float %f
0x5.b6p12 float %a(浮点十六进制)

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

常量 类型 转换说明(%转换字符)
012 unsigned int %#o
2.9e05L long double %le
‘S’ char(实际上是int) %c
10000 long %ld
‘\n’ char(实际上是int) %c
20.0f float %f
0x44 unsinged int %x
-40 int %d

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

int imate = 2;
long shot = 53456;
char grade = 'A';
float log = 2.71828;

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

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

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

答:

char ch;
ch = '\r';
ch = 13;
ch = 015;
ch = 0xd;

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

void main(int) / this program is perfect /
{
    cows, legs integer;
    printf("How many cow legs did you count?\n);
    scanf("%c", legs);
    cows = legs / 4;
    printf("That implies there are %f cows.\n", cows)
}

答:正确的程序如下:

#include <stdio.h>

int main(void)/*this program is perfect*/
{
    int cows, legs;
    printf("How many cow legs did you counts?\n");
    scanf("%d", &legs);
    cows = legs / 4;
    printf("That implies there are %d cows.\n", cows);    
    return 0;
}

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

a.\n 换行字符
b.\ 反斜杠字符
c.\” 双引号字符
d.\t 制表字符

编程练习

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

#include <stdio.h>
/* 编译时会发出警告 */
int main(void)
{
    //整型上溢出,截断处理
    char ch = 10000;
    printf("ch = %d\n", ch);
    // 浮点上溢出
    float fd = 10.234e9999999;
    printf("fd = %f\n", fd);
    // 浮点下溢出
    fd = 10.234e-9999999;
    printf("fd = %f\n", fd);
    return 0;
}

编译警告:

04.c: In function ‘main’:
04.c:6:2: warning: overflow in implicit constant conversion(隐式常量转换中的溢出) [-Woverflow]
  char ch = 10000;
  ^
04.c:9:2: warning: floating constant exceeds range of ‘double’ (浮点常量超出了“double”的范围)[-Woverflow]
  float fd = 10.234e9999999;
  ^
04.c:12:2: warning: floating constant truncated to zero(浮点常量被截断为零) [-Woverflow]
  fd = 10.234e-9999999;
  ^

运行结果:

ch = 16
fd = inf
fd = 0.000000

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

/*官方*/
#include <stdio.h>
int main(void)
{
    int ascii;
    printf("Enter an ASCII code: ");
    scanf("%d", &ascii);
    printf("%d is the ASCII code for %c.\n", ascii, ascii);
    return 0;
}
/*自己写的*/
#include <stdio.h>

int main(void)
{
    char ch;
    printf("请输入一个ASCII码值:");
    scanf("%d", &ch);
    printf("你输入的字符是%c\n", ch);
    return 0;
}

3.打印文本并响铃

编写一个程序,发出一声警报,然后打印下面的文本:
Startled by the sudden sound, Sally shouted,
“By the Great Pumpkin, what was that!”

#include <stdio.h>

int main(void)
{
    //响铃
    printf("%c", '\a');
    printf("Startled by the sudden sound, Sally shouted,\n\"By the Great Pumpkin, what was that!\"\n");
    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
#include <stdio.h>
int main(void)
{
    float num;
    printf("Enter a floating-point value: ");
    scanf("%f", &num);
    printf("fixed-point notation: %f\n", num);
    printf("exponential notation: %e\n", num);
    printf("p notation: %a\n", num);
    return 0;
}

5.计算年龄的秒数

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

#include <stdio.h>

int main(void)
{
    int age;
    double year_seconds = 3.156e7;
    printf("请输入你的年龄:");
    scanf("%d", &age);
    printf("你的年龄对应的秒数是:%f\n", age * year_seconds);
    return 0;
}

6.计算水分子的数量

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

#include <stdio.h>
int main(void)
{
    float mass_mol = 3.0e-23; /* mass of water molecule in grams */
    float mass_qt = 950; /* mass of quart of water in grams */
    float quarts;
    float molecules;
    printf("Enter the number of quarts of water: ");
    scanf("%f", &quarts);
    molecules = quarts * mass_qt / mass_mol;
    printf("%f quarts of water contain %e molecules.\n", quarts, molecules);
    return 0;
}

7.身高英寸转厘米

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

#include <stdio.h>
#define SCALER 2.54

int main(void)
{
    float height;
    printf("请按照英寸输入的你的身高:");
    scanf("%f", &height);
    printf("你的身高是:%f厘米\n", SCALER * height);
    return 0;
}

8.测量系统单位换算

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

#include <stdio.h>

int main(void)
{
    int cup;
    printf("请输入杯数:");
    scanf("%d", &cup);

    printf("%d杯等于%f品脱\n", cup, cup / 2.0);// 整型除以整型得到整型
    printf("%d杯等于%d盎司\n", cup, cup * 8);
    printf("%d杯等于%d大汤勺\n", cup, cup * 8 * 2);
    printf("%d杯等于%d茶勺\n", cup, cup * 8 * 2 * 3);
    return 0;
}

总结

C Primer Plus 第三章复习题 - 图1注意:
1.数据类型的大小根据各系统的实现而定
2.可以使用sizeof查看数据类型的大小,如下:

#include <stdio.h>

int main(void)
{
    printf("char类型大小:%d\n", sizeof(char));
    printf("short类型大小:%d\n", sizeof(short));
    printf("int类型大小:%d\n", sizeof(int));
    printf("long类型大小:%d\n", sizeof(long));
    printf("long long类型大小:%d\n", sizeof(long long));

    printf("float类型大小:%d\n", sizeof(float));
    printf("double类型大小:%d\n", sizeof(double));
    printf("long类型大小:%d\n", sizeof(double));

    return 0;
}

结果如下:

char类型大小:1
short类型大小:2
int类型大小:4
long类型大小:8
long long类型大小:8
float类型大小:4
double类型大小:8
long类型大小:8

3.整数可以表示为十进制、八进制或十六进制。0前缀表示八进制数,0x或0X前缀表示十六进制数。例如,32、040、0x20分别以十进制、八进制、十六进制表示同一个值。l或L前缀表明该值是long类型, ll或LL前缀表明该
值是long long类型。
4.转义序列

转义序列 含义
\a 警报(ANSI C)
\b 退格
\f 换页
\n 换行
\r 回车
\t 水平制表符
\v 垂直制表符
\\ 反斜杠(\)
\‘ 单引号
\“ 双引号
\? 问号
\0oo 八进制值(oo必须是有效的八进制数,即每个o可表示0~7中的一个数)
\xhh 十六进制值(hh必须是有效的十六进制数,即每个h可表示0~f中的一个数)