第三章 顺序程序设计

原创
2020/10/17 00:51
阅读数 31

章节结构

  • 3.1 顺序程序设计举例

  • 3.2 数据的表现形式及其运算

    • 3.2.1 常量和变量
      • 常量
      • 变量
      • 常变量
      • 标识符
    • 3.2.2 数据类型
    • 3.2.3 整型数据
      • 整型数据的分类
      • 整型变量的符号属性
    • 3.2.4 字符型数据
      • 字符与字符代码
      • 字符变量
    • 3.2.5 浮点型数据
  • 3.3 运算符和表达式

    • 3.3.1 C运算符(13种)
    • 3.3.3 自增(++)、自减(--)运算符
    • 3.3.4 算术表达式和运算符的优先级与结合性
    • 3.3.5 不同类型数据间的混合运算
    • 3.3.6 强制类型转换运算符
  • 3.4 C语句

    • 3.4.1 C语句的作用和分类
    • 3.4.2 最基本的语句——赋值语句
      • 赋值运算符
      • 复合的赋值运算符
      • 赋值表达式
      • 赋值过程中的类型转换
      • 赋值表达式和赋值语句
      • 变量赋初值
  • 3.5 数据的输入输出

    • 3.5.1 输入输出举例

    • 3.5.2 有关数据输入输出的概念

    • 3.5.3 用printf函数输出数据

      • printf函数的一般格式
      • 格式字符
    • 3.5.4 用scanf函数输入数据

      • scanf函数的一般形式
      • scanf函数中的格式声明
      • 使用scanf函数时应注意的问题
    • 3.5.5 字符输入输出函数

      • putchar函数输出一个字符

      • getchar函数输入一个字符

3.2 数据的表现形式及其运算

3.2.1 常量和变量

常量

常量:在程序运行过程中,其值不能被改变的量称为常量。
常量有5种:整型常量、实型常量(小数形式、指数形式)、字符常量(普通字符、转义字符)、字符串常量、符号常量(用#define指令,指定一个符号名称代表一个常量)

  • 普通字符:用单撇号括起来的一个字符,如'a'
    单撇号只是界限符,字符常量只能是一个字符,不包括单撇号。字符常量存储在计算机存储单元中时,并不是存储字符本身,而是以其代码(一般采用ASCII代码)存储的。
  • 转义字符:以字符“"开头的字符序列,也是一种特殊形式的字符常量 注意下面的形式也是转义字符的一种
    \0dd\xdd 与八进制/十六进制对应的字符

同时要注意无论是普通字符还是转义字符,本质都是字符常量,都必须是以单撇号括起来的形式出现

变量

变量:变量名、变量的值、内存单元  

变量必须先定义,后使用
变量名表示一个内存地址

常变量

有类型,占存储单元但不能改变其值

方法是在定义变量时,前面加一个关键字const

标识符

用来对变量、符号常量名、函数、数组、类型等命名的有效字符序列统称为标识符

  1. 下划线、字母、数字。但开头不能是数字
  2. 大小写敏感

3.2.2 数据类型

  1. 在计算机中,数据是存放在存储单元中的,它是具体存在的。而且,存储单元是由有限的字符构成的,每一个存储单元存放数据的范围是有限的。

  2. 所谓类型,就是对数据分配存储单元的安排,包括存储单元的长度(占多少字节)以及数据的存储形式

  3. 不同的类型分配不同的长度和存储形式。

  4. 四大类18种

  1. 基本数据类型:整型数据(char、short、int、long、long long、bool)、浮点型数据(double、float、复数浮点型(double_complex、float_complex))、long_complex)    
  2. 枚举类型(enum):程序中用户定义的整数类型   
  3. 空类型(void)    
  4. 派生类型:数组、指针、结构体、共用体、函数  

纯量类型:算术类型指针类型统称为纯量类型
算术类型:基本类型(包括整型和浮点型)和枚举类型变量的值都是数值,统称为算术类型。
组合类型:数组类型结构体类型统称为组合类型。注意:共用体类型不属于组合类型,因为在同一时间内只有一个成员具有值。

3.2.3 整型数据

整型数据的分类

4种,基本整型(int)、短整型(short)、长整型(long)、双长整型(long long)

C标准只要求long型数据长度不短于int型,short型不长于int型。

sizeof(short) <= sizeof(int) <=sizeof(long)<=sizeof(long long)

负数:在计算机内部以补码形式存储。 正数的补码就是此数的二进制形式
负数的补码:先将此数的绝对值写成二进制形式,然后对其所有二进制位按位取反加1。
-5的补码,首先-5的绝对值是55的二进制形式为0000 0000 0000 0101,按位取反加1后为1111 11111 1111 11011

编译系统分配给不同的数据类型不同大小的存储单元。1字节 = 8 位。

若给整型变量分配2个字节,其中最高位为符号位(0代表正数,1代表负数)。则存储单元中能存放的最大值为2的15次方 -1,即十进制数32767
最小值为-2的15次方,即-32768。
因此整型变量的范围是-32768-32767。超出此范围,就会出现数值的”溢出“,输出的结果显然不正确。

整型变量的符号属性

unsigned

  • (1)只有整型(包括字符型)数据可以加signed或unsigned修饰符,实型数据不能加。
  • (2)对无符号整型数据用”%u“格式输出。%u表示用无符号十进制数的格式输出。
    在将一个变量定义为无符号整型后,不应向它赋予一个负值,否则会得到错误的结果

错误演示
错误的把一个负整数存储在无符号变量中

unsigned short price = -1;  
printf("%d\n",price);  // 结果是65535 = 2的16次方。显然与原意不符合

出错的原因:

  • 系统对-1先转换成补码形式,-1的补码形式为1的二进制形式按位取反再加1就是全部二进位都是1,然后把它存入变量price中。
  • 由于price是无符号短整型变量,其左面第一位不代表符号,按“%d”格式输出,就是2的16次方,即65535

3.2.4 字符型数据

字符与字符代码

字符代码:字符的ASCII代码

  • 数字字符‘0’~‘9’的ASCII代码的十进制数为48~57

  • 大写字母‘A’~‘Z’的ASCII代码的十进制数为65~90

  • 小写字母‘a’~‘z’的ASCII代码的十进制数为97~122

  • 换行字符‘\n’的ASCII代码的十进制数为10(line feed换行符)

  • 空格字符‘ ’ 的ASCII代码的十进制数为32

  • 专用字符‘% ’ 的ASCII代码的十进制数为37

字符'1'和整数1是不同的概念
字符’1‘只是代表一个形状为’1‘的符号,在需要时按原样输出,在内存中以ASCII码形式存储,占1个字节
而整数1是以整数存储方式(二进制补码方式)存储的占2个或4个字节

字符变量

3.2.5 浮点型数据

单精度浮点型(float)、双精度浮点型(double)、长双精度浮点型(long double)

怎样确定常量的类型

常量类型5种。
C语言中,的实型常量都作为双精度浮点型常量。

类型VS变量

每一个变量都属于一个确定的类型,类型是变量的一个重要的属性。变量是占用存储单元的,是具体存在的实体,在其占用的存储单元中可以存放数据。
而类型是变量的共性,是抽象的,不占用存储单元,不能用来存放数据。

3.3 运算符和表达式

3.3.1 C运算符

13种运算符,42个
“成强 针 长算关位,逻条赋逗”
成员符号运算符2个,指向结构体成员运算符,结构体成员运算符
类型转换运算符,(类型)
指针运算符2个,指针运算符、取指针运算符
长度运算符,求字节运算符(sizeof)
算术运算符7个,自加、自减、乘、除、取余、加、减、
关系运算符5个,大于、等于、小于、大于等于、小于等于
位运算符6个,左移、右移、按位取反、按位与、按位异或、按位或
逻辑运算符3个,非、与、或
条件运算符,?: 赋值运算符11个,=、+=、-=、*=、/=、%=、>>=、<<=、&=、^=、| =
逗号运算符(顺序求值运算符),逗号
其他运算符

名称 符号
算术运算符 ++ -- * / % + -
关系运算符 > < == >= <=
逻辑运算符 !&& ||
位运算符 >> << ~ & ^ |
赋值运算符 =及其扩展运算符(+=、-=、*=、/=、%=)
条件运算符 ?:
逗号运算符 ,
指针运算符 * &
求字节运算符 sizeof
强制类型转换运算符 (类型)
成员运算符 . ->
下标运算符 []
其他 如函数调用运算符
  • 多数编译器在处理整除/ 时,都是向0取整(即取整后向0靠拢),比如说-5 / 3,取-1或-2,但是根据向零取整,则会得到-1
  • % 要求操作数必须是整数,结果也是整数

3.3.3 自增(++)、自减(--)运算符

前置,则先增后使用 后置,则先使用后增 但二者结果都相同

3.3.4 算数表达式和运算符的优先级与结合性

在表达式求值时,先按运算符的优先级别顺序进行。
如果在一个运算对象两侧的运算符的优先级别相同,则按回定的“结合方向”处理。

  • 优先级
    4个1,圆下两个结(圆括号、下标、指向结构体成员、结构体成员)
    9个2,

3对针自反,符号强制求长度(逻辑非、按位取反、自加、自减、符号、强制类型转换、取地址、指针、sizeof)

3个3(* / %)
4加减(+ -)
5左右(左移、右移)
关系6(> >= < <=)
等等7(== !=)
位逻条赋逗(按位与、按位异或、按位或、逻辑与、逻辑或、条件、赋值11、逗号)

优先级 运算符 含义 要求运算对象的个数 结合方向
1 () [] -> . 圆括号,下标运算符、指向结构体成员运算符、结构体成员运算符 自左至右
2 ! ~ ++ -- - (类型) * & sizeof 逻辑非运算符、按位取反运算符、自增运算符、自减运算符、符号运算符、类型运算符、指针运算符、取地址运算符、长度运算符 单目运算符 自右至左
3 * / % 乘法、除法、取余 双目运算符 自左至右
4 + - 加法、减法运算符 双目运算符 自左至右
5 << >> 左移运算符、右移运算符 双目运算符 自左至右
6 < <= > >= 关系运算符 双目运算符 自左至右
7 == != 等于运算符、不等于运算符 双目运算符 自左至右
8 & 按位与运算符 双目运算符 自左至右
9 ^ 按位异或运算符 双目运算符 自左至右
10 | 按位或运算符 双目运算符 自左至右
11 && 逻辑运算符 双目运算符 自左至右
12 || 逻辑或运算符 双目运算符 自左至右
13 ?: 条件运算符 三目运算符 自右至左
14 = += -= *= /= %= >>= <<= &= ^= |= 赋值运算符 双目运算符 自右至左
15 . 逗号运算符(顺序求值运算符) 自左至右
  • 结合性 结合性是C语言的特点之一。 结合性针对的是优先级相同的运算符之间应遵守的规则
    (也可以是同一个运算符在同一个表达式中出现多次时应执行的规则)
    • 左结合性:自左至右的结合方向,运算对象先与左边的运算符结合
    • 右结合性:自右至左的结合方向,运算对象先与右边的运算符结合(典型的如赋值运算符单目运算符条件运算符,简称赋单条

int * a(int x,int y)
()的优先级高于*,因此a先于()结合,显然这就是个函数形式
这个函数前面有一个*,表示此函数是指针函数(函数值是指针)

3.3.5 不同类型数据间的混合运算

三种情况编译系统自动完成类型转换

  • + - * / 运算的操作数有一个为float或double,先把类型转换为double型然后再运算,结果都将是double类型
  • int型与float或double型数据进行运算,先把类型转换为double型然后再运算,结果都是double型
  • 字符型数据与整型数据或实型数据进行运算,就是把ASCII代码与整数运算或实型数据,结果是整型或double型

3.3.6 强制转换运算符

注意:强制转运算符也是运算符的一种,因此它描述的是运算过程的现象,且优先级比赋值运算符高。(从这里可以看出运算符的优先级的重要性) (类型名) (表达式)
后面的表达式最好用括号括起来。

3.4 C语句

3.4.1 C语句的作用和分类

C语句共五种

  • 控制语句(9种):条件语句(if语句)、循环语句(3种,do...while语句、for语句、while语句)、多分支选择语句(switch语句)、终止switch或循环语句(break语句)、终止本次循环语句(continue)、返回语句(return)、转向语句(goto语句)
  • 函数调用语句
  • 表达式语句
  • 空语句
  • 复合语句 (1)控制语句用于完成一定的控制功能
    (2)函数调用语句:由一个函数调用加一个分号构成 (3)表达式语句:由一个表达式加一个分号构成 (4)空语句:只有一个分号 (5)复合语句:用{}把一些语句和声明括起来称为复合语句(又称为语句块

3.4.2 最基本的语句——赋值语句(表达式语句的一种)

赋值运算符

赋值符号=就是赋值运算符
关键词:赋值操作(又称赋值运算):赋值运算符的作用就是将一个数据赋给一个变量,这种操作就叫赋值操作

复合赋值运算符

赋值符前面加上其他运算符,就构成符合的运算符,因而可以进行复合赋值运算
凡是二元(二目)运算符,都可以与赋值符一起组合成符合赋值符

赋值表达式

赋值表达式:有赋值运算符将一个变量和一个表达式连接起来的式子
注意:赋值表达式也是表达式的一种 格式: 变量 赋值运算符 表达式
赋值运算符 左侧应该是一个可修改值得左值。(常量不能修改,因此不能作为左值)

赋值过程中的类型转换(注意与不同类型数据间的混合运算的区别)

如果赋值运算符两侧到的类型不一致,但都是基本类型时,在赋值时要进行类型转换。类型转换是由系统自动进行的。
自动转换五规则
(1)将浮点型数据(包括但、双精度)赋给整型变量时,先对浮点数取整,即舍弃小数部分,然后赋予整型变量
(2)将整型数据赋给单、双精度变量时,数值不变,但以浮点数形式存储到变量中。
(3)将一个double型数据赋给float变量时,先将双精度数转换为单精度,即支取6~7位有效数字,存储到float型变量的4字节中。
(4) 字符型数据赋给整型数据时,将字符的ASCII代码赋给整型变量
(5)赋给一个占字节少的整型变量或字符变量时,只将低字节原封不动地送到被赋值的变量(即发生“截断“)

例如:把4个字节的int型数据赋给占2个字节的short变量或占1个字节的char变量

这些赋值规则的本质:整型数据之间的赋值,按存储单元的存储形式直接传送。实型数据之间以及整型与实型之间的赋值,实型之间的赋值,是先转换(类型)后赋值

赋值表达式和赋值语句

赋值语句就是赋值表达式加一个分号组成。

  1. 注意if的条件中可以包含赋值表达式,但不能包含赋值语句
  2. 一个表达式中可以包含一个或多个赋值表达式,但决不能包含赋值语句

变量赋初值

C语言,给变量赋初值,这种是错误的 int a=b=c=3;

3.5 数据的输入输出

3.5.1 输入输出举例

3.5.2 有关数据输入输出的概念

    1. 所谓输入输出是以计算机主机为主题而言的。
    • 从计算机向输出设备输出数据称为输出
    • 向计算机输入数据称为输入
    1. C语言本身不提供输入输出语句。是由C标准函数库中函数来实现的。
    1. 要在程序文本的开头用预处理指令#include把有关头文件放在本程序中
    • 标准方式 #include <头文件名称>,编译系统从存放C编译系统的子目录去找所要包含的文件。
    • #include "头文件名称":在编译时,编译系统先在用户的当前目录中寻找要包含的文件,若找不到,再按标准方式查找

3.5.3 用printf函数输出数据

printf函数的一般格式

printf(格式控制,输出表列)

  • 格式控制 用双引号括起来的一个字符串,称为格式控制字符串,简称格式字符串
    格式声明普通字符构成
    • 格式声明:由%格式字符组成,如%d,%f等
      格式声明的一般形式: % 附加字符 格式字符
      附加字符可以没有
      • 格式字符比较负责需要单独介绍
  • 输出表列可以是常量变量或者表达式

格式字符

格式声明是由%格式字符组成。 常用的格式字符

十格八数两字,XEG可大写(常用格式字符有10个,其中数值类的有8个,字符有2个,一个字符一个字符串;除了XEG可以大写,其他必须小写)

  • d格式符:用来输出一个有符号的十进制
  • c格式符:用来输出一个字符
  • s格式符:用来输出一个字符串
  • f格式符:用来输出实数
    • 基本型%f,一般情况是实数中的整数部分全部输出,小数部分输出6位
    • 指定数据宽度和小数位数,用%m.nf(注意:这里表示输出的数据占m列,其中包括n位小数,即m已经把n计算在内了)
    • 输出的数据向左对齐%-m.nf(左对齐,位数不够,在右边填充空格)
      默认右对齐,如果有-符号,则左对齐。+不代表右对齐,会当成普通字符输出。
    • 如果需要输出double型数据可以使用格式符号lf

    输入双精度型变量的值要用格式声明“%lf”
    float 型数据小数点后是6个有效数字,
    double类数据小数点后是15个有效数字

  • e格式符:用格式声明%e指定以指数形式输出实数
  • 其他格式符:i(按照十进制整型数据实际长度输出);o格式字符(八进制整数形式)、x格式符(十六进制整数形式)、u(无符号十进制)、g(浮点数,自动选f格式或e格式,不输出无意义的0)

格式字符:数值类8个 d u i of XEG,2个(一个字符,一个字符串)。

printf函数中的格式附加字符

4个格式附加字符

格式附加字符 说明
l 长整型整数,可加在格式符d、o、x、u前面
m(代表一个正整数) 数据最小宽度
n(代表一个正整数) 对实数,表示输出n位小数;对字符串,表示截取的字符个数
- 输出的数字或字符在域内向左靠

printf函数的5点说明

  1. printf函数输出时,务必注意输出对象的类型应与上述格式说明匹配,否则将会出现错误
  2. 除了XEG外,其他格式字符必须用小写字母,如~~%d不能写成%D~~
  3. 可以在printf函数中的格式控制字符串内包含转义字符,如\n,\t,\b,\r,\f和\377等
  4. 一个格式声明是以%开头,以duioxfegXEGcs等12个格式字符之一结束,中间可以插入附加格式字符(或称为修饰符);注意printf函数使用输出表列替换格式字符,但是普通字符会被原样输出
  5. 在printf函数中输出百分号%,应该在格式控制字符串中用连续两个%表示即可

3.5.4 用scanf函数输入数据

scanf函数的一般形式

scanf(格式控制,地址声明)

scanf函数中的格式声明

格式字符

同printf函数
有一个需要注意的地方,s |格式字符|说明| |:----------:|:---------:| |s|输入字符串,将字符串送到一个字符数组中,在输入时以非空白字符开始,以第一个空白字符结束。字符串以串结束标志'\0'作为其最后一个字符|

格式附加字符(又称修饰符)
字符 说明
l 输入长整型数据(可用%ld,%lo,%lu,%lx)以及double型数据(用%lf或%le)
h 输入短整型数据(可用%hd,%ho,%hx)
域宽 指定输入数据所占宽度(列数),域宽应为正整数
* 本输入项在读入后不赋给相应的变量
注意:scanf函数中的格式附加字符有 * 表示本输入项在读入后不赋给相应的变量

使用scanf函数时应注意的问题

  1. scanf函数中的格式控制后面应当是变量地址,而不是变量名
  2. 如果在格式控制字符串中除了格式声明以外还有其他字符,则在输入数据时在对应的位置上也要输入这些字符
  3. 在用“%c”格式声明输入字符时,空格字符换行字符中的字符都作为有效字符输入(意思就是说空格和enter键都会被捕捉到,作为scanf函数的参数)

即用%c时,键盘输入的空格字符换行字符都会当做scanf函数中的地址声明
这里容易出现的一个错误就是,本来作为分割意义的空格字符和换行字符,被用来替换格式字符了,这会造成格式字符的个数和实际捕捉到的地址声明个数不一致,

  1. 在输入数值数据时,如输入空格、回车、Tab键或者是非法字符(不属于数值的字符),则表示该数据结束

scanf("%d%c%f",&a,&b,&c);
若输入1234a123u.26此处按下回车键 此时 %d对应1234%c对应a%f对应123
后面的字符没有被读入

scanf函数常用的格式说明(补充)

  1. 在格式串中,必须含有与输入项一一对应的格式转换说明符
  2. 在VC6.0环境下,输入short型整数的格式控制符要求%hd
  3. 在scanf()函数的格式字符前可以加入一个正整数指定输入数据所占的宽度,但不可以对实数指定小数位的宽度
  4. 输入是一个字符流,scanf()函数从这个流中按照格式控制指定的格式解析出相应数据,送到指定的地址变量中,因此当数据少于输入项时,运行程序将等待输入,直到满足输入要求为止;当输入数据多于输入项时,多余的数据在输入流中没有作废,等待下一个输入操作语句继续从输入流读取数据
  5. scanf()函数返回值是本次scanf()函数调用正确输入的数据项的个数

3.5.5 字符输入输出函数

转义字符

转移字符,分为两部分组成,反斜杠\ASCII码值
其中ASCII码值可以是十进制或者八进制或者十六进制

  • 无论是用哪一种数制表示,数值范围应该与ASCII码值范围一致。 目前标准的ASCII码值范围在0~127
  • 若用十进制则格式为\ddd八进制则格式为\odd十六进制则格式为\xdd

putchar函数输出一个字符

字符输出函数
putchar(c) // 在计算机显示屏上显示变量c的值
c是2常2变(有条件的整型变量),可以是字符常量、整型常量、字符变量或 整型变量(要求其值在字符的ASCII代码范围内)

getchar函数输入一个字符

字符输入函数
getchar() 从计算机终端输入一个字符。getchar()函数值就是得到的那个字符

getchar函数不仅可以从输入设备获得一个可显示的字符,而且可以获得在屏幕上无法显示的字符,如控制字符

用getchar函数得到的字符可以赋值给一个字符变量或整型变量;也可以直接作为表达式的一部分

...
char a;
a = getchar(); //从键盘输入一个字符,送给字符变量a
putchar(a); // 将变量a的值输出

getchar函数的一个问题

getchar()函数不仅可以从输入设备获得一个可显示的字符,而且可以获得在屏幕上无法显示的字符,如控制字符(比如换行符)
这会容易发生一些意料之外的问题。特别是在连续多个getchar()语句,此时会把一些空格符号或回车也作为一个字符输入

在使用getchar和putchar函数时注意字符与字符串(字符数组)的区别

getchar()从输入设备获取一个字符,putchar(char)输出一个字符
而strlwr等函数处理的是字符串和字符数组,
因此若要使它们之间产生联系,就涉及到字符如何转换成字符数组的问题

要使得单个字符转换成字符串,注意必须将字符数组长度定为2,因为包括字符串结尾符'\0'

char a,b[2];

a = getchar();
b[0] = a;
printf("%s",strlwr(b));

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部