首页 > 技术文章 > [C语言程序设计现代方法] 第1章 第2章 C语言概述和基本概念

star-air 2021-10-03 17:38 原文

教材:《C语言程序设计_现代方法 第2版》


C语言概述和基本概念

第1章 C语言概述

C语言的历史

一些饶有余味的历史节点:

  • 上世纪60年代、ThompsonBCPL语言的基础上设计了B语言

  • 1971年、加入开发的RitchieB语言的基础上设计了C语言

  • 1978年、K&R两位编写了第一本C语言教程The C Programming Lauguage,这一版的标准叫做经典C,后来出的第二本里参考了ANSI里的标准

  • 1983年、美国国家标准协会(ANSI)开始制定C语言标准;1990年,国际标准化组织(ISO)通过此项标准,后来ANSI C这一标准叫做标准C

  • C语言的发展:Concurrent C 和 Objective C 以及C++语言

    • C++比C语言难学,因此最好先精通C++语言
    • 使用C++语言时,需要避免C语言的编程习惯

C语言的优缺点

C语言的自身特性

  • C语言是一种低级语言。C语言的设计思想是更好的操控底层,因此C语言是较其他高级语言来说比较底层的一门语言。
  • C语言是一种小型语言。与其他语言相比,C语言的语法是相对较少的。
  • C语言是一种包容性语言。C语言提供了更广阔的自由度。

C语言的优点

  • 高效性。
  • 可移植性。
  • 功能强大。
  • 灵活性。
  • 标准库。
  • 与UNIX系统的集成。

C语言的缺点

  • C程序可能会漏洞百出。
  • C程序可能会难以理解。
  • C程序可能会难以修改。

高效的使用C语言

  • 学习如何规避C语言的缺陷。
  • 使用软件工具使程序更加可靠。
  • 利用现有的代码库。
  • 采用一套切合实际的编码规范。
  • 避免"投机取巧"和极度复杂的代码
  • 使用标准C,少用经典C
  • 避免不可移植性。

第2章 C语言基本概念

预处理指令、函数、变量、语句

程序编译和链接

当写完一个程序后,例如以下程序

#include<stdio.h>

main()
{
    printf("to c,or not to c,that is the question")
}

要经历以下过程:

预处理->编译->链接

  • 预处理:处理#开头的指令,可以给程序添加内容,也可以修改程序
  • 编译:将程序翻译成机器指令(目标代码object code)
  • 链接:将所有相关程序的目标代码整合在一起。

gcc编译器可以通过指令进行编译:gcc -o fun fun.c
也可以使用一些集成开发环境IDE进行开发。

简单程序的通用形式

指令

预处理器执行的命令称为指令

函数

有输入有返回值的特定语句块就叫做函数

语句

语言是程序运行时执行的命令。

注释

/**/组成的注释

  • 注释可以出现在程序的任意位置。
  • 注释可以占用多行。
  • 可以同代码放在一行。
  • 防止注释缺失或者注释嵌套。

变量和赋值

类型

intfloat

  • int类型又叫做整型。取值范围-32768 ~ 32767
  • float类型又叫浮点型。做运算时比int慢,同时数值不精确(四舍五入)。

声明

使用变量之前需要对其进行声明。例如 int height;

如果光声明不初始化,变量的值 是不确定的。

赋值

变量 通过赋值的方式获得值。height = 8;

显示变量的值

使用库函数中的printf来 打印变量,例如 printf("profit:$%.2f\n",profit);

  • %d用于int型变量
  • %f用于float型变量。默认情况下,%f显示 小数点后六位的数据,如果需要指定小数点后 n位,用%.nf表示。

初始化

在声明的时候即对变量赋值,就是对变量进行初始化 。例如int height = 8;

显示表达式的值

printf也可以显示任意表达式的值。

读入输入

scanfprintf差不多。

需要提前定义一个变量。scanf("%f",&x)

定义常量

常量(constant)是程序执行过程中固定不变的量。

  • 常量通常采用 宏定义的 方式命名。
  • 命名规范是全部用大写,_连接

标识符

对变量 ,函数,宏及其他实体命名的名字叫做 标识符

  • 标识符必须以字母或者下划线_开头。
  • 标识符区分大小写。

关键字

关键字对编译器来说有特殊意义 ,因此不能拿来作为标识符使用。

C语言程序的布局

  • 语句可以划分在任意多行内,如果过长则要压缩在一行内。
  • 记号之间的空格应该便于肉眼区别记号。
  • 缩进有 助于识别程序嵌套。
  • 空行可以把程序分成逻辑单元。

exercise & project

exercise

2.01

Create and run Kernighan and Ritchie's famous "hello, world" program:

#include <stdio.h>

int main(void)
{
    printf("hello, world\n");
}

Do you get a warning message from the compiler? If so, what's needed to make it go away?

Solution:

Compiling the program produced no errors using gcc version 7.2.0. Here is the complete output of run commands:

$ gcc 1.c -o 1 -Wall -W -pedantic -std=c99
(no output, no warnings or errors)

$ gcc 1.c -o 1 -Wall -W -pedantic -std=c89
1.c: in function 'main':
1.c:5:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^

This warning can be fixed by amending return 0;

#include <stdio.h>

int main(void) {
    printf("hello, world\n");
    return 0;
}

$ gcc 1b.c -o 1b -Wall -W -pedantic -std=c89
(no output, no warnings or errors)
2.02

Consider the following program:

#include <stdio.h>

int main(void)
{
    printf("Parkinson's Law:\nWork expands so as to ");
    printf("fill the time\n");
    printf("available for its completion.\n");
    return 0;
}

(a) Identify the directives and statements in this program.
(b) What output does the program produce?

Solution

(a)

The only directive in the program is #include <stdio.h> in line 1. The statements are the lines 5-8: the printf() statements and the return statement.

(b)

The program produces the following:

Parkinson's Law:
Work expands so as to fill the time
available for its completion.
2.03

Condense the dweight.c program by (1) replacing the assignments to height,
length, and width with initializers and (2) removing the weight variable,
instead calculating (volume + 165) / 166 within the last printf.

Solution

#include <stdio.h>

int main(void) {

    int height = 8,
        length = 12,
        width = 10,
        volume = height * length * width;

    printf("Dimensions: %dx%dx%d\n", length, width, height);
    printf("Volume (cbic inches): %d\n", volume);
    printf("Dimensional weight (pounds): %d\n", (volume + 165) / 166);

    return 0;
}

2.04

Write a program that declares several int and float variables--without
initializing them--and then prints their values. Is there any pattern to the
values? (Usually there isn't.)

Solution

#include <stdio.h>

int main(void) {

    int a, b, c, d, e;
    float f, g, h, i, j;
    
    printf("%d\n%d\n%d\n%d\n%d\n%f\n%f\n%f\n%f\n%f\n", 
           a, b, c, d, e, f, g, h, i, j);

    return 0;
}

There is no pattern for the first few integers produced, however, upon repeated
compilations and repeated tests, the last two integers and all floats are
usually 0 or 0.000000, with occasional deviation to "random" garbage values.

2.05

Which of the following are not legal C identifiers?

(a) 100_bottles
(b) _100_bottles
(c) one_hundred_bottles
(d) bottles_by_the_hundred

Solution

(a) is not a legal identifier, because identifiers must start with a letter or
underscore.

2.06

Why is it not a good idea for an identifier to contain more than one adjacent
underscore (as in current___balance, for example)?

Solution

An identifier with multiple consecutive underscores are difficult to read. It is
hard to determine exactly how many underscore characters there are in the
identifier, and the use of multiple underscores serves no purpose.

2.07

Which of the following are keywords in C?

(a) `for`  
(b) `If`  
(c) `main`  
(d) `printf`  
(e) `while`

Solution

(a) and (e) are keywords. (b) would be a keyword if If was written as if.

2.08

How many tokens are there in the following statemnt?

answer=(3*q-p*p)/3;

Solution

There are thirteen tokens in the statement, six of which are non-unique.

2.09

Insert spaces between the tokens in Exercise 8 to make the statement easier to
read.

Solution

answer = (3 * q - p * p) / 3;
2.10

In the dweight.c program (Section 2.4), which spaces are essential?

Solution

Below is the complete dweight.c program, as written in Section 2.4:

/* Computes the dimensional weight of a 12" x 10" x 8" box */

#include <stdio.h>

int main(void)
{
    int height, length, width, volume, weight;

    height = 8;
    length = 12;
    width = 10;
    volume = height * length * width;
    weight = (volume + 165) / 166;

    printf("Dimensions: %dx%dx%d\n", length, width, height);
    printf("Volume (cubic inches): %d\n", volume);
    printf("Dimensional weight (pounds): %d\n", weight);

    return 0;
}

The only spaces which are necessary are the line break in the #include
directive and its space between #include and <stdio.h> as well as the space
between return and 0.

practice

2.01

Write a program that uses printf to display the following picture on the
screen:

       *
      *
     *
*   *
 * *
  *

Solution

#include <stdio.h>

int main(void) {
    
    printf("       *\n");
    printf("      * \n");
    printf("     *  \n");
    printf("*   *   \n");
    printf(" * *    \n");
    printf("  *     \n");

    return 0;
}

2.02

Write a program that computes the volume of a sphere with a 10-meter radius,
using the formula v = 4/3πr³. Write the fraction 4/3 as 4.0f/3.0f. (Try
writing it as 4/3. What happens?) Hint: C doesn't have an exponentiation
operator, so you'll need to multiply r by itself twice to compute r³.

Solution

#include <stdio.h>

int main(void) {

    printf("Sphere volume: %.2f cubic meters\n", 4.0f/3.0f * 3.14f * 1000);
    return 0;
}

Writing the fraction in integer form will result in a integer rounding error,
returning 1.

2.03

Modify the program of Programming Project 2 so that it prompts the user to enter
the radius of the sphere.

Solution

#include <stdio.h>

int main(void) {

    int r = 0;

    printf("Enter radius: ");
    scanf("%d", &r);

    printf("\nSphere volume: %.2f cubic meters\n",
           4.0f/3.0f * 3.14f * r * r * r);
    return 0;
}

2.04

Write a program that asks the user to enter a dollars-and-cents amount, then
displays the amount with a 5% tax added:

Enter an amount: 100.00
With tax added: $105.00

Solution

#include <stdio.h>

int main(void) {

    float money = 0.0f;
    printf("Enter an amount: ");
    scanf("%f", &money);
    printf("With tax added: $%.2f\n", money * 1.05f);

    return 0;
}

2.05

Write a program that asks the user to enter a value for x and then displays the
value of the following polynomial:

3x5 + 2x4 - 5x3 - x2 + 7x - 6

Hint: C doesn't have an exponentiation operator, so you'll need to multiply x
by itself repeatedly in order to compute the powers of x. (For example, x * x * x is x cubed.)

Solution

#include <stdio.h>

int main(void) {

    int x = 0;

    printf("Enter value for x: ");
    scanf("%d", &x);
    printf("Result: %d\n",
           (3 * x * x * x * x * x) + (2 * x * x * x * x) - (5 * x * x * x)
           - (x * x) + (7 * x) - 6);

    return 0;
}

2.06

Modify the program of Programming Project 5 so that the polynomial is evaluated
using the following formula:

((((3x + 2)x-5)x-1)x+7)x-6

Note that the modified program performs fewer multiplications. This technique
for evaluating polynomials is known as Horner's Rule.

Solution

#include <stdio.h>

int main(void) {

    int x = 0;

    printf("Enter value for x: ");
    scanf("%d", &x);
    printf("Result: %d\n",
           ((((3 * x + 2) * x - 5) * x - 1) * x + 7) * x - 6);

    return 0;
}

2.07

Write a program that asks the user to enter a U.S. dollar amount and then shows
how to pay that amount using the smallest number of $20, $10, $5 and $1 bills:

Enter a dollar amount: 93

$20 bills: 4
$10 bills: 1
 $5 bills: 0
 $1 bills: 3

Hint: Divide the amount by 20 to determine the number of $20 bills needed, and
then reduce the amount by the total value of the $20 bills. Repeat for the
other bill sizes. Be sure to use integer values throughout, not floating-point
numbers.

Solution

#include <stdio.h>

int main(void) {

    int money = 0;

    printf("Enter a dollar amount: ");
    scanf("%d", &money);

    printf("$20 bills: %d\n", money/20);
    money -= 20 * (money/20);

    printf("$10 bills: %d\n", money/10);
    money -= 10 * (money/10);

    printf(" $5 bills: %d\n", money/5);
    money -= 5 * (money/5);

    printf(" $1 bills: %d\n", money);

    return 0;
}

2.08

Write a program that calculates the remaining balance on a loan after the first,
second, and third monthly payments:

Enter amount of loan: 20000.00
Enter interest rate: 6.0
Enter monthly payment: 386.66

Balance remaining after first payment: $19713.34
Balance remaining after second payment: $19425.25
Balance remaining after third payment: $19135.71

Display each balance with two digits after the decimal point. Hint: Each
month, the balance is decreased by the amount of the payment, but increased by
the balance times the monthly interest rate. To find the monthly interest rate,
convert the interest rate entered by the user to a percentage and divide it by

Solution

#include <stdio.h>

int main(void) {

    float loan = 0.0f,
          rate = 0.0f,
          payment = 0.0f;

    printf("Enter amount of loan: ");
    scanf("%f", &loan);

    printf("Enter interest rate: ");
    scanf("%f", &rate);

    printf("Enter monthly payment: ");
    scanf("%f", &payment);


    loan = loan - payment + (loan * rate / 100.0 / 12.0);
    printf("Balance remaining after first payment: $%.2f\n", loan);

    
    loan = loan - payment + (loan * rate / 100.0 / 12.0);
    printf("Balance remaining after second payment: $%.2f\n", loan); 

    loan = loan - payment + (loan * rate / 100.0 / 12.0);
    printf("Balance remaining after third payment: $%.2f\n", loan);

    return 0;
}

推荐阅读