C语言入门系列之3.顺序程序设计和输入输出

CuterCorley
• 阅读 1576

从程序流程的角度来看,程序可以分为三种基本结构,即顺序结构、分支结构、循环结构,这三种基本结构可以组成各种复杂程序,C语言提供了多种语句来实现这些程序结构。同时C语言提供的输入输出的函数为IO提供了方便的工具。

一、C语句介绍

1.C基本语句

C程序的执行部分是由语句组成的,程序的功能也是由执行语句实现的。 C语句可分为以下五类:

  • 表达式语句 表达式语句:表达式语句由表达式加上分号;组成。 其一般形式为表达式;,执行表达式语句就是计算表达式的值。 例如:
      x=y+z;  // 赋值语句
      y+z;   // 加法运算语句,但计算结果不能保留,无实际意义
      i++;    // 自增1语句,i值增1
  • 函数调用语句 函数调用语句由函数名、实际参数加上分号;组成。 其一般形式为函数名(实际参数表);。 执行函数语句就是调用函数体并把实际参数赋予函数定义中的形式参数,然后执行被调函数体中的语句,求函数值。 例如:
      printf("C Program"); //调用库函数,输出字符串
  • 控制语句 控制语句用于控制程序的流程,以实现程序的各种结构方式,它们由特定的语句定义符组成。 C语言有九种控制语句,可分成以下三类:
    • 条件判断语句:if语句、switch语句;
    • 循环执行语句:do while语句、while语句、for语句;
    • 转向语句:break语句、goto语句、continue语句、return语句。
  • 复合语句 把多个语句用括号{}括起来组成的一个语句称复合语句。 在程序中应把复合语句看成是单条语句,而不是多条语句。 例如:
      { 
          x=y+z;
          a=b+c;
          printf(“%d%d”,x,a);
      }
    这是一条复合语句。 复合语句内的各条语句都必须以分号;结尾,在大括号}外不能加分号
  • 空语句 只有分号;组成的语句称为空语句,即什么也不执行的语句,在程序中可用来作空循环体。 例如:
      while(getchar()!='\n')
      {
          ;
      }
    这里的循环体为空语句,功能是只要从键盘输入的字符不是回车则重新输入。

2.赋值语句

赋值语句是由赋值表达式再加上分号构成的表达式语句。 其一般形式为变量 = 表达式;

赋值语句的功能和特点都与赋值表达式相同,它是程序中使用最多的语句之一。 在赋值语句的使用中需要注意以下几点:

  • 由于在赋值符=右边的表达式也可以又是一个赋值表达式,因此,形式变量=(变量=表达式); 是成立的,从而形成嵌套的情形,其展开之后的一般形式为变量=变量=…=表达式;。 例如:

      a=b=c=d=e=5;
    

    按照赋值运算符的右结合性,因此实际上等效于:

      e=5;
      d=e;
      c=d;
      b=c;
      a=b;
  • 在变量说明中给变量赋初值和赋值语句是有区别的: 给变量赋初值是变量说明的一部分,赋初值后的变量与其后的其他同类变量之间仍必须用逗号间隔,而赋值语句则必须用分号结尾。 例如:

      int a=5,b,c;
  • 在变量说明中,不允许连续给多个变量赋初值。 如int a=b=c=5;是错误的,必须写为int a=5, b=5, c=5;,而赋值语句允许连续赋值。

  • 赋值表达式和赋值语句的区别如下: 赋值表达式是一种表达式,它可以出现在任何允许表达式出现的地方,而赋值语句则不能。 例如,语句if((x=y+5)>0) z=x;是合法的,含义是若表达式x=y+5大于0则z=x,而语句if((x=y+5;)>0) z=x;是非法的,因为x=y+5;是语句,不能出现在表达式中。

二、数据输入输出

所谓输入输出是以计算机为主体而言的,这里主要是向标准输出设备显示器输出数据的语句。 在C语言中,所有的数据输入、输出都是由库函数完成的,因此都是函数语句。 在使用C语言库函数时,要用预编译命令#include有关头文件包括到源文件中。 使用标准输入输出库函数时要用到stdio.h文件,因此源文件开头应有预编译命令#include< stdio.h >#include "stdio.h",其中,stdio是standard input & output的意思。 考虑到printf和scanf函数使用频繁,一些编译器允许在使用这两个函数时可不加#include< stdio.h >#include "stdio.h"。 一般情况下,系统的源文件用尖括号<>,自定义文件用双引号""。

1.putchar函数(字符输出函数)

putchar函数是字符输出函数,其功能是在显示器上输出单个字符。 其一般形式为:

putchar(字符变量);

例如:

putchar('A');    // 输出大写字母A
putchar(x);      // 输出字符变量x的值
putchar('\101'); // 输出字符A
putchar('\n');   // 换行

控制字符执行控制功能,不在屏幕上显示。

使用putchar函数前必须要用文件包含命令#include <stdio.h>#include "stdio.h"

putchar使用练习如下:

#include <stdio.h>

int main(){
    char a = 'B', b = 'o', c = 'k';
    putchar(a);putchar(b);putchar(b);putchar(c);putchar('\t');
    putchar(a);putchar(b);
    putchar('\n');
    putchar(b);putchar(c);

    return 0;
} 

打印:

Book    Bo
ok

2.getchar函数(键盘输入函数)

getchar函数的功能是从键盘上输入一个字符。 其一般形式为:

getchar();

通常把输入的字符赋予一个字符变量,构成赋值语句,如:

char c;
c = getchar();

getchar练习如下:

#include <stdio.h>

int main(){
    char c;
    printf("input a character:\n");
    c = getchar();
    putchar(c);
    putchar('\n');

    return 0;
} 

如下: C语言入门系列之3.顺序程序设计和输入输出

3.格式化输出printf

printf函数称为格式输出函数,其关键字最末一个字母f即为格式(format) 之意,其功能是按用户指定的格式,把指定的数据显示到屏幕上。

printf函数调用的一般形式

printf函数是一个标准库函数,它的函数原型在头文件stdio.h中。 作为特例,在用少数编译器如VC编译器编译时使用printf函数之前可以不包含stdio.h文件。

printf函数调用的一般形式为:

printf("格式控制字符串", 输出表列);

其中格式控制字符串用于指定输出格式,可由格式字符串和非格式字符串两种组成。 格式字符串是以%开头的字符串,在%后面跟有各种格式字符,以说明输出数据的类型、形式、长度、小数位数等。如:

  • %d表示按十进制整型输出;
  • %ld表示按十进制长整型输出;
  • %c表示按字符型输出等。

非格式字符串在输出时原样打印,在显示中起提示作用。 输出表列中给出了各个输出项,要求格式字符串和各输出项在数量、类型和顺序上一一对应。

练习如下:

#include <stdio.h>

int main(){
    int a = 71, b = 72;
    printf("%d %d\n", a, b);
    printf("%ld, %ld\n", a, b);
    printf("%c %c\n", a, b);
    printf("a=%d, b=%d", a, b);

    return 0;
} 

打印:

71 72
71, 72
G H
a=71, b=72

本例中四次输出了a、b的值,但由于格式控制串不同,输出的结果也不相同。 第一次printf语句格式控制串中,两格式串%d之间加了一个空格(非格式字符),所以输出的a、b值之间有一个空格; 第二次printf语句格式控制串中加入的是非格式字符逗号,因此输出的a、b值之间加了一个逗号; 第三次printf语句格式控制串要求按字符型输出a、b值; 第四次printf语句格式控制串为了提示输出结果增加了非格式字符串。

格式字符串

(1)格式字符串的类型字符用以表示输出数据的类型,格式符和意义如下: C语言入门系列之3.顺序程序设计和输入输出 (2)标志及其意义如下所示: C语言入门系列之3.顺序程序设计和输入输出 (3)输出最小宽度 用十进制整数来表示输出的最少位数。 若实际位数多于定义的宽度,则按实际位数输出,若实际位数少于定义的宽度则补以空格或0。 (4)精度 精度格式符以点号.开头,后跟十进制整数。 本项的意义是:如果输出数字,则表示小数的位数;如果输出的是字符,则表示输出字符的个数;若实际位数大于所定义的精度数,则截去超过的部分。 (5)长度 长度格式符为h、l两种,h表示按短整型量输出,l表示按长整型量输出。

格式字符串举例如下:

#include <stdio.h>

int main(){
    int a = 15;
    float b = 123.7654321;
    double c = 12345678.87654321; 
    char d = 't';
    printf("a=%d,%5d,%o,%x\n", a, a, a, a);
    printf("b=%f,%lf,%5.4lf,%e\n", b, b, b, b);
    printf("c=%lf,%f,%8.4lf\n", c, c, c);
    printf("d=%c,%8c\n", d, d);

    return 0;
} 

打印:

a=15,   15,17,f
b=123.765434,123.765434,123.7654,1.237654e+002
c=12345678.876543,12345678.876543,12345678.8765
d=t,       t

使用printf函数时还要注意输出表列中的求值顺序。不同的编译系统不一定相同,可以从左到右,也可从右到左。

一个printf()语句和多个printf()语句的区别练习如下:

#include <stdio.h>

int main(){
    int i = 8;
    printf("第一次:\n%d\n%d\n%d\n%d\n%d\n%d\n", ++i, --i, i++, i--, -i++, -i--);
    i = 8;
    printf("第二次:\n%d\n", ++i);
    printf("%d\n", --i);
    printf("%d\n", i++);
    printf("%d\n", i--);
    printf("%d\n", -i++);
    printf("%d\n", -i--);

    return 0;
} 

打印:

第一次:
8
8
7
8
-7
-8
第二次:
9
8
8
9
-8
-9

两次的区别是用一个printf语句还是多个printf语句输出,从结果可以看出是不同的; 显然,第二次的结果更容易理解。

4.格式化输入scanf

scanf函数称为格式输入函数,即按用户指定的格式从键盘上把数据输入到指定的变量之中。

scanf函数的一般形式

scanf函数是一个标准库函数,它的函数原型在头文件stdio.h中。 与printf函数相同,在少数编译器中允许在使用scanf函数之前不包含stdio.h文件。 scanf函数的一般形式为:

scanf("格式控制字符串", 地址表列);

其中,格式控制字符串的作用与printf函数相同,但不能显示非格式字符串,也就是不能显示提示字符串。 地址表列中给出各变量的地址,地址是由地址运算符& 加变量名组成的。 例如&a, &b分别表示变量a和变量b的地址,这个地址就是编译系统在内存中给a、b变量分配的地址。 在C语言中,使用了地址这个概念,这是与其他语言不同的,C语言允许对内存中的地址进行控制,也就是可以控制系统的底层。

应该把变量的值和变量的地址这两个不同的概念区别开来,变量的地址是C编译系统分配的,用户不必关心具体的地址是多少。 在赋值表达式中给变量赋值,如a = 567;中,a为变量名,567是变量的值,&a是变量a的地址。

但在赋值号左边是变量名a,不能写地址,而scanf函数在本质上也是给变量赋值,但要求写变量的地址,如&a。 这两者的意义是不同的,&是一个取地址运算符,&a是一个表达式,其功能是求变量的地址。

练习如下:

#include <stdio.h>

int main(){
    int a, b, c;
    printf("Input a, b, c: \n");
    scanf("%d%d%d", &a, &b, &c);
    printf("a=%d, b=%d, c=%d\n", a, b, c);

    return 0;
} 

打印:

Input a, b, c:
12 34 56
a=12, b=34, c=56

可以看到,如果有多个输入,需要分割不同的输入,否则会阻塞等待,一般可以用空格或回车(换行)分隔。

格式字符串

格式字符串的一般形式为:

%[*][输入数据宽度][长度]类型;

其中有方括号[]的项为任选项。 各项的意义如下: (1) 类型 表示输入数据的类型,其格式符和意义如下: C语言入门系列之3.顺序程序设计和输入输出 (2)符 用以表示该输入项,读入后不赋予相应的变量,即跳过该输入值。 如`scanf("%d %d %d", &a, &b);中,当输入1 2 3时,把1赋予a,2被跳过,3赋予b。 (3)宽度 用十进制整数指定输入的宽度(即字符数)。 如scanf("%5d", &a);,输入12345678,只把12345赋予变量a,其余部分被截去; 而scanf("%4d%4d", &a, &b);`,输入12345678,则将把1234赋予a、5678赋予b。 (4)长度 长度格式符为l和h,l表示输入长整型数据(%ld) 和双精度浮点数(%lf),h表示输入短整型数据。

使用scanf函数需要注意以下几点: (1)scanf函数中没有精度控制,如scanf("%5.2f",&a);是非法的,不能企图用此语句输入小数为2位的实数。 (2)scanf中要求给出变量地址,如给出变量名则会出错,如scanf("%d",a);是非法的,应改为scnaf("%d",&a);。 (3)在输入多个数值数据时,若格式控制串中没有非格式字符作输入数据之间的间隔则可用空格、TAB或回车作间隔。 C编译在碰到空格、TAB、回车或非法数据(如对%d输入12A时,A即为非法数据)时即认为该数据结束。 (4)在输入字符数据时,若格式控制串中无非格式字符,则认为所有输入的字符均为有效字符。 例如scanf("%c%c%c",&a,&b,&c);,输入d e f,则把'd'赋予a, ' '赋予b,'e'赋予c,只有当输入为def时,才能把'd'赋于a,'e'赋予b,'f'赋予c; 如果在格式控制中加入空格作为间隔,如scanf ("%c %c %c",&a,&b,&c);,则输入时各数据之间可加空格。

测试如下:

#include <stdio.h>

int main(){
    char a, b;
    printf("Input character a, b: \n");
    scanf("%c%c", &a, &b);
    printf("a=%c, b=%c\n",a, b);

    return 0;
} 

打印:

Input character a, b:
a b
a=a, b=

显然,此时输入空格时,因为空格也是一个字符,所以b即为空格' '。 如果要想在字符之间输入空格也可以分别接收,需要在scanf()中传入格式化字符串时也加入空格,如scanf("%c %c", &a, &b);,此时输入的数据之间有空格间隔也可以接收到想要输入的字符。 如果a、b变量为整型或其他类型时,不存在这种情况。 (5)如果格式控制串中有非格式字符则输入时也要输入该非格式字符。 例如scanf("%d,%d,%d",&a,&b,&c);,其中用非格式符,作间隔符,故输入时应为5,6,7; 又如scanf("a=%d,b=%d,c=%d",&a,&b,&c);,则输入应为a=5,b=6,c=7。 (6)如输入的数据与输出的类型不一致时,虽然编译能够通过,但结果不正确。

测试如下:

#include <stdio.h>

int main(){
    int a;
    printf("Input a number:\n");
    scanf("%d", &a);
    printf("%ld\n", a);

    return 0;
}

打印:

Input a number:
9876543210
1286608618

由于输入数据类型为整型,而输出语句的格式串中说明为长整型,因此输出结果和输入数据不一致。

练习--输入三个小写字母,输出其ASCII码和对应的大写字母:

#include <stdio.h>

int main(){
    char a, b, c;
    printf("Input character a, b, c:\n");
    scanf("%c %c %c", &a, &b, &c);
    printf("%d, %d, %d\n%c, %c, %c", a, b, c, a-32, b-32, c-32);    

    return 0;
}

打印:

Input character a, b, c:
a h o
97, 104, 111
A, H, O

练习--输出各种类型的字节长度:

#include <stdio.h>

int main(){
    int a;
    long b;
    float f;
    double d;
    char c;
    printf("int:%d\nlong:%d\nfloat:%d\ndouble:%d\nchar:%d\n", sizeof(a), sizeof(b), sizeof(f), sizeof(d), sizeof(c));    

    return 0;
}

打印:

int:4
long:4
float:4
double:8
char:1

显然,可以得到在当前编译环境下各种类型所占大小。

练习--求三角形面积: 输入三角形的三边长,求三角形面积: 已知三角形的三边长a,b,c,则该三角形的面积公式为: C语言入门系列之3.顺序程序设计和输入输出 其中s = (a+b+c)/2。

代码示例如下:

#include <stdio.h>
#include <math.h>

int main(){
    double a, b, c, s, area;
    scanf("%lf,%lf,%lf", &a, &b, &c);
    s = 1.0 / 2 * (a + b + c);
    area = sqrt(s * (s - a) * (s - b) * (s - c));
    printf("a = %7.2g, b = % 7.2g, c = %7.2g, s = %7.2g\n", a, b, c, s);
    printf("area = %7.2f\n", area);


    return 0;
}

打印:

3,4,5
a =       3, b =       4, c =       5, s =       6
area =    6.00

显然,在输入的3条边有意义的情况下,可以计算出三角形的面积; %g是根据数值不同自动选择%f或%e,7.2指字段宽度为7个字符,小数点后面有2个数字。

练习--求二次方程的根: C语言入门系列之3.顺序程序设计和输入输出 代码如下:

#include <stdio.h>
#include <math.h>

int main(){
    double a, b, c, x1, x2, delta, p, q;
    scanf("a=%lf, b=%lf, c=%lf", &a, &b, &c);
    delta = b * b - 4 * a * c;
    p = -b / (2 * a);
    q = sqrt(delta) / (2 * a);
    x1 = p + q;
    x2 = p - q;
    printf("\nx1=%5.2lf\nx2=%5.2lf\n", x1, x2);        

    return 0;
}

打印:

a=1, b=-2, c=1

x1= 1.00
x2= 1.00

本文原文首发来自博客专栏C语言学习,由本人转发至https://www.helloworld.net/p/OJyTGeiALU2D,其他平台均属侵权,可点击https://blog.csdn.net/CUFEECR/article/details/105604811查看原文,也可点击https://blog.csdn.net/CUFEECR浏览更多优质原创内容。

点赞
收藏
评论区
推荐文章
CuterCorley CuterCorley
3年前
C语言入门系列之5.循环控制结构程序
@一、概述循环结构是程序中一种很重要的结构。其特点是:在给定条件成立时,反复执行某程序段,直到条件不成立为止。给定的条件称为循环条件,反复执行的程序段称为循环体。C语言提供了多种循环语句,可以组成各种不同形式的循环结构:goto语句和if语句构成循环;while语句;dowhile语句;for语句。二、got
Stella981 Stella981
3年前
C# Aspose.Cells导出xlsx格式Excel,打开文件报“Excel 已完成文件级验证和修复。此工作簿的某些部分可能已被修复或丢弃”
报错信息:最近打开下载的Excel,会报如下错误。(xls格式不受影响)!(https://oscimg.oschina.net/oscnet/2b6f0c8d7f97368d095d9f0c96bcb36d410.png)!(https://oscimg.oschina.net/oscnet/fe1a8000d00cec3c
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Stella981 Stella981
3年前
Sentinel 1.7.2 发布,完善开源生态及扩展性
多样化的适配模块到目前为止,Sentinel已覆盖微服务、APIGateway和ServiceMesh三大板块的核心生态,同时多语言已推出Java、C、Go三种语言的原生实现。!78636450_ef3a4b00_78da_11ea_89ce_c7a2b58c2deb(https://yqfile.alicd
Wesley13 Wesley13
3年前
C++——分支语句
  在日常生活中的很多时候,我们要进行判断,比如说:判断11是否等于2,今天的主食吃米饭还是馒头,喜欢一个人到底要不要表白......咳咳,总之,需要做判断的情况有很多很多。程序本就是为了解决问题而编写的,自然也有很多需要进行判断的地方。这一节的内容就是学会如何使用分支语句进行判断。  在学习分支语句前先介绍一个新的数据类型:布尔值(bool)  
Stella981 Stella981
3年前
Nginx反向代理upstream模块介绍
!(https://oscimg.oschina.net/oscnet/1e67c46e359a4d6c8f36b590a372961f.gif)!(https://oscimg.oschina.net/oscnet/819eda5e7de54c23b54b04cfc00d3206.jpg)1.Nginx反
Wesley13 Wesley13
3年前
Java05
Java05Java基础语法(四)循环结构循环结构(重复/迭代):根据条件重复执行部分语句1、while循环结构while(条件表达式){     循环体语句;}1)语法:a、while是关键字        b、“条件表达式”必须用括号括起来        c、“{}”表示循环的控制范围,若没有“{}”,whil
小万哥 小万哥
12个月前
C 语言教程:条件和 if...else 语句
C语言中的条件和if...else语句您已经学习过C语言支持数学中的常见逻辑条件:小于:a<b小于或等于:ab大于或等于:ab等于:ab不等于:a!b您可以使用这些条件来根据不同的决策执行不同的操作。C语言具有以下条件语句:使用if来指定要执行的代码块,如
小万哥 小万哥
12个月前
C 语言中的 switch 语句和 while 循环详解
C语言中的switch语句替代多重if..else语句,可以使用switch语句。switch语句用于选择多个代码块中的一个来执行cswitch(表达式)casex://代码块break;casey://代码块break;default://代码块工作原理
小万哥 小万哥
11个月前
深入解析 C 语言中的 for 循环、break 和 continue
C语言中的for循环当您确切地知道要循环执行代码块的次数时,可以使用for循环而不是while循环cfor(语句1;语句2;语句3)//要执行的代码块语句1在执行代码块之前执行(一次)。语句2定义执行代码块的条件。语句3在执行代码块后执行(每次)。下面的示