C语言程序设计(理论课)第二章(理解)算法和第三章数据类型及其运算
第二章算法——程序的灵魂
算法+数据结构=程序
数据结构
对数据的描述。在程序中要指定用到哪些数据,以及这些数据的类型和数据的组织形式。
算法
对操作的描述。即要求计算机进行操作的步骤。
广义的说,为解决一个问题而采取的方法和步骤,就称为“算法”。
对同一个问题,可以有不同的解题方法和步骤。为了有效地进行解题,不仅需要保证算法的正确,还要考虑算法的质量,选择合适的算法
第三章数据类型及其运算
3.1常量和变量
在计算机高级语言中,数据的两种表现:
A常量 B变量
1、常量:在程序运行过程中,其值不能被改变的量。
1.整型常量…1000,122345,0,-345
2.实型常量…小数形式123.456;指数形式12.34e3,-34.8E-23
3.字符常量…普通字符‘a’,‘Z’,‘3’,’?’,’#’;转义字符‘\n‘,‘\012‘,‘h1B’
4.字符串常量…“123”,“boy”
5.符号常量…#definePI3.1416//注意行末没有分号
转义字符 | 字符值 | 输出结果 |
---|---|---|
\’ | 一个单撤号(’) | 输出单撤号字符’ |
\" | 一个双撤号(") | 输出双撤号字符‘’ |
\? | 一个问号(?) | 输出问号字符? |
\ \ | 一个反斜杠() | 输出反斜线字符\ |
\a | 警告(alert) | 产生声音或视觉信号 |
\b | 退格(backspace) | 将光标当前位置后退一个字符 |
\f | 换页(form feed) | 将光标当前位置移到下一页开头 |
\n | 换行 | 将光标当前位置移到下一行的开头 |
\r | 回车(carriage return) | 将光标当前位置移到本行的开头 |
\t | 水平制表符 | 将光标当前位置移到下一个Tab位置 (相当于空格) |
\v | 垂直制表符 | 将光标当前位置移到下一个垂直制表对齐点 |
\o、\oo或\ooo其中o代表一个八进制数字 | 与该八进制码对应的ASCII字符 | 与该八进制码对应字符 |
\xh[h…]其h代表一个十六进制数字 | 与该十六进制码对应的ASCII字符 | 与该十六进制码对应字符 |
2、变量
变量代表一个有名字的、具有特定属性的一个储存单元。
变量用来存放数据,也就是存放变量的值。
在程序运行期间,变量的值是可以改变的。
变量必须先定义,后使用。(重要)
变量定义的一般形式:类型名 变量名=初值
int a,b,c //定义a,b,c为整型变量
float m=3.5,n=-7.8,p //定义m,n,p为浮点型变量并对m和n指定初值
3、标识符 (重要,考选择题)
标识符就是一个对象的名字。用于标识变量、符号常量、函数、数组、类型等
标识符只能由字母、数字和下划线 3种字符组成,且第一个字符必须为字母或下划线
注意:
· 变量名中区分大小写字母
· 不能使用关键字作为变量名
· 变量的名字应该尽量反应变量在程序中的作用与含义
C语言中的(32个)关键字
union联合数据类型 | break | case | while |
char字符 | continue | default | do |
double双精度 | else | switch | return |
float浮点型 | for | goto | if |
int整型 | long长整型 | extern外部变量(存储类型) | const(其他) |
short短整型 | signed有符号类型 | static静态变量(存储类型) | sizeof(其他) |
struct结构体 | enum枚举类型 | auto自动变量(存储类型) | typedef(其他) |
unsigned无符号型 | void无返回值类型 | register寄存器变量(存储类型) | volatile(其他) |
未标注的为数据类型关键字
黄色标注为控制语句关键字
3.2数据类型
所谓类型,就是对数据分配储存单元的安排,包括储存单元的长度(占了多少字节)以及数据的存储形式。
不同的类型分配不同的长度和存储形式
基本类型int | |||
短整型 short int | |||
整型类型 | 长整型long int | ||
基本类型 | *双长整型 long long int | ||
字符型 char | |||
*布尔型bool | |||
单精度浮点型float | |||
浮点类型 | 双精度浮点型double | ||
复数浮点型float_complex,double_complex,long long_complex | |||
数据类型 | 枚举类型enum | ||
空类型void | |||
指针类型 * | |||
派生类型 | 数组类型[ ] | ||
结构体类型 union | |||
函数类型 |
3.3整型数据
整型常量的形式
1、 十进制整数
如:123,-456,4
2、 八进制整数
以0开头的数是八进制数,如:0123表示八进制数123
3、 十六进制整数
以0x开头的数是十六进制数,如:0x123表示十六进制123
1、整型数据在内存中的存储方式
int i; //定义i为整型变量
i=10; //给i赋以整数10
十进制10的二进制形式是1010,在内存中存放的情况:
0000000000001010
实际上数值是以补码表示的。正整数的补码与原码一样。负整数的补码值是
第一步:将此数绝对值的二进制形式;
第二步:除最高位符号位外其他数取反;
第三步:加1。-10的补码:
原码:1000000000001010
11111111111110101
补码: 1111111111110110
2、整型数据的分类
整型数据类型名称 | 整型数据类型 | 字节数 | 取值范围 |
---|---|---|---|
基本型 | int | 4(基本型根据用的编辑器不同而不同,有的是2) | -2147483648~ 2147483647(-2131~2131-1) |
短整型 | short int/short | 2(字节数x8=16位) | -32768~ 32767(-215~215-1) |
长整型 | long int/long | 4 (32位) | -2147483648~2147483647(-2131 ~ 231-1) |
双长整型 | long long int/long long | 8 (64位) | -9223372036854775807(-263~262-1) |
说明:C标准没有具体规定各种类型数据所占用存储单元的长度,只要求sizeof(short)≤sizeof(int)≤sizeof(long)≤sizeof(long long),具体由各种编译系统自行决定的。
sizeof是测量类型或变量长度的运算符。
3、整型数据的溢出
【例3.1】整型数据的溢出
#include<stdio.h>
int main()
{short int a,b;a=32767;b=a+1;printf("a=%d,a+1=%d\n",a,b);return 0;
}
a:0111111111111111→32767
b:1000000000000000→ -32768
一个字节的短整型变量只能容纳-32768~32767的数,无法表示大于32768或小于-32768的数。遇到此情况就发生==“溢出”==,如果将变量b改为int或long型就能得到正确的结果32768。
** 说明** :用计算机实现计算和数学上的纯理论计算是不相同的,计算机的计算是通过工程的方法实现的。
4、无符号整型变量(重要)
在定义int,short int和long int类型变量时,都可以加 修饰符 unsigned,以指定为“无符号整数”。加修饰符signed或缺省,则表示“有符号整数”。
对无符号整数用“%u”格式输出,表示无符号十进制数。对有符号整数一般用“%d”格式输出。
在将一个变量定位为无符号整型后,不应向它赋予一个负值,否则会得到错误的结果。
整型数据类型 | 缺省形式的整型数据类型 | 字节数 | 取值范围 |
---|---|---|---|
[signed] int | int | 4 | -2147483648~ 2147483647(-2131~2131-1) |
unsigned [int] | unsigned | 4 | 0~4294967295(0 ~ 232-1) |
[signed] short [int] | short | 2 | -32768 ~ 32768(-215 ~ 215-1) |
unsigned short [int] | unsigned short | 2 | 0 ~ 2165535(0~216-1) |
[signed] long [int] | long | 4 | -2147483648~2147483647(-231 ~ 231-1) |
unsigned long [int] | unsigned long | 4 | 0~4294967295(0 ~ 232-1) |
[signed] long long [int] | long long | 8 | -9223372036854775808~9223372036854775807(-263 ~ 263-1) |
unsigned long long [int] | unsigned long long | 8 | 0 ~ 18446744073709551615(0~264-1) |
3.4浮点型数据
123.456=123.456100 =1.23456102=1234.56*10-1
由于小数点位置可以浮动,所以实数的指数形式称为浮点数。
用指数形式表示可以有1.23456e2,1234.56e-1等,在字母e或E前的小数部分中,小数点左边只有一位非零数字的表示形式,即1.23456e2形式为标准化的指数形式。
浮点数类型包括float(单精度浮点型)、double(双精度浮点型)、long double(长双精度浮点型)。
注意:由于用二进制形式表示一个实数以及存储单元的长度是有限的,因此不可能得到完全精确的值,只能存储成有限的精确度。小数部分占的位(bit)数越多,数的有效数字就越多,精确度也就越高。指数部分占的位数愈多,则能表示的数值范围越大
①实型数据
类型 | 字节数 | 有效数字 | 数值范围(绝对值) |
---|---|---|---|
float | 4 | 6 | 0以及1.210-38 ~ 3.41038 |
double | 8 | 15 | 0以及2.310-308 ~ 1.710308 |
long double | 8 | 15 | 0以及2.310-308 ~ 1.710308 |
16 | 19 | 0以及3.410-4932 ~ 1.1104932 |
②浮点型常量的类型
C编译系统把浮点型常量都按双精度处理,分配8个字节。
double d;
d=2.45678*4523.65;
//系统把2.45678和4523.65作为双精度数,乘积也是一个双精度数赋给双精度浮点型变量d。由于双精度数可以提供15~16位有效数字,这样做可以使计算结果更精确(但运算速度会降低)。
float f;
f=3.141592654;
//如果把一个浮点型常量赋给一个单精度浮点变量,会提示精度损失,值保证6~7位有效位数
//若要表示单精度浮点常量,可在数值后加f或F(如1.23f)
③浮点型数据的舍入误差
【例3.2】检查浮点型数据的舍入误差
解题思路: 将一个双精度数赋给一个单精度浮点型变量,检查其误差。
#include<stdio.h>
int main()
{float a;a=3.141592612;printf("a=%f\n",a);return 0;
}
3.5字符型数据
字符是按其代码(整数)形式存储的
①字符常量:
普通字符
- 字母:大写英文字母A~Z,小写英文字母a ~ z
- 数字:0 ~ 9
- 专门符号:29个,包括
! " # & ’ ( ) * + , - . / ; : < = > ? [ \ ] ^ _ ` { | } ~ - 空格符:空格、水平制表符(tab)、垂直制表符、换行、换页(form feed)
- 不能显示空字符:空(null)字符(以’\0’表示)、警告(以’\a’表示)、退格(以’\b’表示)、回车(以’\r’表示)等。
ASCII码表
A和a差了32个
主要考字母
注意:字符‘1’和整数1是不同的概念。
字符和字符可以相加
字符‘1’只是代表一个形状为‘1’的符号,在需要时按原样输出,在内存中以ASCII码形式存储,占一个字节。(八位)
00110001
而整数1是以整数存储方式(二进制补码方式)存储的,占2个或4个字节。(16位或32位)
00000000000000000000000000000001
整数运算1+1等于整数2,而字符‘1+1’并不等于整数2或字符‘2’。
转义字符
字符形式 | 含义 | ASCII码 |
---|---|---|
\n | 换行,将当前位置移到下一行的开头 | 10 |
\t | 水平制表符(跳到下一个Tab位置) | |
\b | 退格,将当前位置移到前一列 | 8 |
\r | 回车,将当前位置移到本行的开头 | 13 |
\f | 换页,将当前位置移到下页开头 | 12 |
\a | 发出铃声 | 7 |
\\ | 代表一个反斜杠字符”\“ | 92 |
\’ | 代表一个单引号字符 | 39 |
\" | 代表一个双引号字符 | 34 |
\ddd | 以1~3位八进制所代表的字符 | |
\hhh | 以1~2位十六进制数所代表的字符 |
②字符变量
字符变量是用类型符char定义字符变量。
char c1,c2;
c1='a';
c2='b';
//将字符常量放到字符变量中,实际上并不是把该字符本身放到变量的内存单元中,而是将该字符对应的ASCII代码放到变量的存储单元中。可以把字符变量看成只有一个字节的整型变量。
变量名 | 变量的值 | 变量的实际存放形式 |
---|---|---|
c1 | 97 | 01100001 |
c2 | 98 | 01100010 |
字符型数据和整型数据之间可以通用
在输出字符变量的值时,可以选择以十进制整数形式输出(用格式字符“%d”),或以字符形式输出(用格式符“%c”)。
因此,也可以对字符数据进行算数运算
【例3.3】向字符变量赋予整数。
#include<stdio.h>
int main()
{int c1,c2;c1=97;c2=98;printf("c1=%c,c2=%c\n",c1,c2); //用字符形式输出printf("c1=%d,c2=%d\n",c1,c2); //用十进制形式输出return 0;
}
【例3.4】把小写字母转换为相应的大写字母。
解题思路:找到大小写字母之间转换的规律:小写字母与大写字母ASCII代码的差值为32。C语言允许字符数据与整数直接进行算术运算。
#include<stdio.h>
int main()
{char c1,c2;c1='a'; //将97存入c1c2='b'; //将98存入c2c1=c1-32; //c1的值为65c2=c2-32; //c2的值为66printf("%c,%c\n",c1,c2); //以字符形式输出c1和c2return 0;
}
字符型数据的存储空间和值的范围
类型 | 字节数 | |
---|---|---|
[signed]char(有符号字符型) | 1 (8位) | -128~127,即-27 ~ (27-1) |
unsigned char(无符号字符型) | 1 | 0~255,即0 ~ 28-1 |
说明:在使用有符号型变量时,允许存储的值为-128 ~ 127,但字符的代码不可能为负值。所以在存储字符时实际上只用到0 ~ 127这一部分,其第一位都是0.
如果将一个负整数赋给有符号字符型变量是合法的,但它不代表一个字符,而作为一个字节整型变量存储负整数。
③字符串常量
一对双引号括起来的字符序列
例如:“How do you do.”,“CHINA”,“a”,"$123.45"
printf("How do you do."); //用printf函数输出一个字符串
区别字符常量和字符串常量:
char c;c='a'; //正确
char c;c='a'; //错误,不能把一个字符串常量赋给一个字符变量
C规定:在每一个字符串常量的结尾加一个字符串结束标志"/0"(ASCII码为0的空字符),以便编译系统据此判断字符串是否结束。字符串常量“a”,实际上在内存中是:a\0它占2个字节内存单元,字符常量’a’以及字符变量c都只占1个字节内存单元。
注意:在写字符串时不必加“\0”,‘\0’字符是系统自动加上的。
3.6运算符和表达式
C运算符
序号 | 名称 | 符号 |
---|---|---|
1 | 算术运算符 | + - * / % ++ - - |
2 | 关系运算符 | < > == >= <= != |
3 | 逻辑运算符 | ! && || |
4 | 位运算符 | >> << ~ | ^ & |
5 | 赋值运算符 | =及其扩展赋值运算符 |
6 | 条件运算符 | ?: |
7 | 逗号运算符 | , |
8 | 指针运算符 | * & |
9 | 求字节数运算符 | sizeof |
10 | 强制类型转换运算符 | (类型) |
11 | 成员运算符 | . - > |
12 | 下标运算符 | [] |
13 | 其他 | 如函数调用运算符() |
3.6.1算数运算符
①基本的算数运算符
运算符 | 含义 | 举例 | 结果 |
---|---|---|---|
+ | 正号运算符(单目运算符) | +a | a的值 |
- | 负号运算符(单目运算符) | -a | a的算术负值 |
* | 乘法运算符 | a*b | a和b的乘积 |
/ | 除法运算符 | a/b | a除以b的商 |
% | 求余运算符 | a%b | a除以b的余数 |
+ | 加法运算符 | a+b | a和b的和 |
- | 减法运算符 | a-b | a和b的差 |
++ | 自加 | a++ ,++a | a的值加1 |
- - | 自减 | a- -,- - a | a的值减1 |
两个实数相除的结果是双精度实数,两个整数相除的结果为整数
%运算符要求参加运算的运算对象(即操作数)为整数,结果也是整数
②自增(++)自减(- -)运算符
++i,- -i 在使用i之前,先使i的值加/减1
i++,i- - 在使用i之后,使i的值加/减1
++i是先执行i=i+1,再使用i的值;而i++是先使用i的值,再执行i=i+1。
int i=3,j;
j=++i; //i的值先变成4,再赋给j,j的值为4
int i=3;
printf("%d",++i); //输出4
int i=3,j;
j=i++; //先将i的值3赋给j,j的值为3,然后i变为4
int i=3;
printf("%d",i++); //输出3
建议谨慎使用++和- -运算符,只用简单的形式,即i++,i- -,且把他们作为单独的表达式
C表达式
C表达式是指把符合C语言规定的、用运算符和括号将数据(包括常量、变量、函数)连接起来的式子
- 算术表达式 如2+6.7*3.5+sin(0.5)
- 关系表达式 如x>0,y<z+6
- 逻辑表达式 如x>0&&y<0
- 赋值表达式 如a=5.6
- 逗号表达式 如x=3,y=4,z=5
- 条件表达式
运算符的优先级与结合性
在表达式求值时要考虑运算符的优先级,按运算符的优先级别高低次序执行,例如先乘除后加减。如果在一个运算对象两侧的运算符的优先级别相同,则按C语言规定的“结合方向”处理。
C语言规定了各种运算符的结合方向(也称为结合性),算术运算符的结合方向为 “自左至右” ,又称 “左结合性”,即运算对象先于左面的运算符结合,因此在求a-b+c时,b先于减号结合,执行a-b的运算,再执行加c的运算。有些运算符(如++,- -,赋值运算符)的结合方向为 “自右至左” ,即右结合性。
不同类型数据间的混合运算
如果一个运算两侧的数据类型不同,则先自动进行类型转换,使二者成为同一种类型,然后进行运算。整型、实型、字符型数据间可以进行混合运算。,规律为:
- +、-、*、/运算的两个数中有一个数为float或double型,结果时double型,因为系统将所有float型数据都先转换为double型,然后进行运算。
- 如果int型与float型数据进行运算,先把int型和float型数据转换为double型,然后进行运算,结果double型。
- 字符(char)型数据与整型数据进行运算,就是把字符的ASCII代码与整型数据进行运算。如果字符型数据与实型数据进行运算,则将字符的ASCII代码转换为double型数据,然后进行运算。
int i;
float f;
double d;
long n;
printf("%lf",50+'b'+i*f-d/n);
程序分析
50+‘b’+if-d/n
①进行50+'b’的运算,先将’b’转换成整数98,运算结果为148。
②由于“ * ”比“+”优先,先进行 i * f 的运算,先将i与f都转换成double型,运算结果为double型。
③整数148与if的积相加。先将整数148转换成双精度数(按双精度型数据存储),结果为double型。
④将变量n化成double型,d/n结果为double型
⑤将50+‘b’+i*f的结果与d/n的商相减,结果为double型。
转换的规则 | |||
---|---|---|---|
高 | double | ← | float |
↑ | long | ||
↑ | unsigned | ||
低 | int | ← | char |
课本附录完整优先级
简表
强制类型转换运算符
自动类型转换
在运算时不必用户干预,系统自动进行的类型转换
强制类型转换
当自动类型转换不能实现目的时,可以用强制类型转换
(类型名)(表达式)
(double)a //将a转换成doubel型
(int)(x+y) //将x+y的值转换成int型
(float)(5%3) //将5%3的值转换成float型
(int)x+y //只将x转换成整型,然后与y相加int a;float x,y;double b;
a=(int)x //进行强制类型运算(int)x后得到一个int类型的临时值,它的值等于x的整数部分,把它赋给a,注意x的值和类型都未变化,仍为float型。该临时值在赋值之后就不再存在了。
3.6.2关系运算符和关系表达式
1.关系运算符、表达式
在C语言中,用来进行比较的符号称为关系运算符(或称比较运算符,它用来比较运算符两侧的数据),由关系运算符将两个表达式(可以是算术表达式或关系表达式、逻辑表达式、赋值表达式、字符表达式)连接起来的式子就是关系表达式
关系运算符及其优先次序
优先级 |
---|
算术运算符(高) |
↓ |
关系运算符 |
↓ |
赋值运算符(低) |
关系运算符
1、< (小于)
2、<= (小于等于)
3、> (大于)
4、>= (大于等于)
5、== (等于)
6、!= (不等于)
- 前4种关系运算符的优先级别相同,后两种也相同。前4种高于后2种
- 关系运算符的优先级低于算术运算符。
- 关系运算符的优先级高于赋值运算符。
- c>a+b 等效于c>(a+b)(关系运算符的优先级低于算术运算符)
- a>b==c 等效于(a>b)==c(大于运算符>的优先级高于等于运算符= =)
- ab<c *等效于a(b<c)(小于运算符<的优先级高于相等运算符= =)*
- a=b>c 等效于a=(b>c)(关系运算符的优先级高于赋值运算符)
2.关系表达式
- 用关系运算符将两个表达式连接起来的式子,称为关系表达式。
- 关系表达式的值是一个逻辑值,即“真”或“假”。
- 在C的逻辑运算符中,以“1”代表“真”,以“0”代表“假”。
若a=3,b=2,c=1,则:
关系表达式,“a>b"的值为“真”,表达式的值为1.
关系表达式“(a>b)==c”的值为"真"(因为a>b的值为1,等于c的值),表达式的值为。
关系表达式“b+c<a”的值为“假”,表达式的值为0。
3.6.3逻辑运算符和逻辑表达式
1.逻辑运算符
用逻辑运算符将关系表达式或其他逻辑量连接起来的式子就是逻辑表达式。
逻辑运算符及其优先次序
运算符 | 含义 | 举例 | 说明 |
---|---|---|---|
! | 逻辑非(NOT) | !a | 如果a为假,则!a为真;如果a为真,则!a为假 |
&& | 逻辑与(AND) | a&&b | 如果a和b都为真,则结果为真,否则为假 |
| | | 逻辑或(OR) | a||b | 如果a和b有一个以上为真,则结果为真,二者都为假时,结果为假 |
“&&”和“|”是双目运算符,要求有两个运算对象(操作数);“!”是单目运算符,只要有一个运算对象
优先次序:!(非)→&&(与)→|(或),即“!”为三者中最高的;逻辑运算符中的“&&”和“||”低于关系运算符,“!”高于算术运算符
逻辑运算结果不是0就是1,不可能是其他数值。而在逻辑表达式中作为参与逻辑运算的运算对象可以是0(“假”)或任何非0的数值(按“真”对待)
a | b | !a | !b | a&&b | a||b |
---|---|---|---|---|---|
真(非0) | 真(非0) | 假(0) | 假(0) | 真(1) | 真(1) |
真(非0) | 假(0) | 假(0) | 真(1) | 假(0) | 真(1) |
假(0) | 真(非0) | 真(1) | 假(0) | 假(0) | 真(1) |
假(0) | 假(0) | 真(1) | 真(1) | 假(0) | 假(0) |
2.逻辑表达式
在逻辑表达式的求解中,并不是所有的逻辑运算符都被执行,只是在必须执行下一个逻辑运算符才能求出表达式的解时,才执行该运算符
a&&b&&c。只有a为真(非0)时,才需要判别b的值。只有当a和b都为真时才需要判别c的值。
a||b||c。只要a为真(非0),就不必判断b和c。只有a为假,才判别b。a和b都为假才判别c。
3.6.4位运算符及表达式
- 位运算的作用:直接对变量的二进制按位进行操作。
注意:位运算只适合于整型和字符型变量。
位运算符及其含义和优先级如下:
位运算符 | 含义 | 优先级 |
---|---|---|
~ | 按位取反 | 高(14) |
& | 位与 | 低 (8) |
^ | 位异或 | 低(7) |
| | 位或 | 低(6) |
<< | 位左移 | 中(11) |
>> | 位右移 | 中(11) |
位运算规则
A | B | A|B | A^B | A&B | ~A | ~B |
---|---|---|---|---|---|---|
1 | 1 | 1 | 0 | 1 | 0 | 0 |
1 | 0 | 1 | 1 | 0 | 0 | 1 |
0 | 0 | 0 | 0 | 0 | 1 | 1 |
0 | 1 | 1 | 1 | 0 | 1 | 0 |
3.6.5赋值运算符和赋值表达式
1、赋值运算符“=”
“=”的作用是将一个数据赋给一个变量。
例如:a=5的作用是执行一次赋值操作(或称赋值运算)。把常量5赋给变量a。也可以将一个表达式的值赋给一个变量。
2、赋值表达式:变量 赋值运算符 表达式
赋值表达式的作用是将一个表达式的值赋给一个变量,因此赋值表达式具有计算和赋值的双重功能。
对赋值表达式求解的过程是:
①求赋值运算符右侧的"表达式"的值。
②赋给赋值运算符左侧的变量。既是一个表达式,就应该有一个值,表达式的值等于赋值后左侧变量的值。
赋值运算符左侧应该是一个可以修改值的“左值”(lefe value,简写为lvalue)。
能出现在运算符右侧的表达式称为“右值”(right value,简写为rvalue)
注意:
并不是任何形式的数据都可以作为左值的,左值应该当为存储空间并可以被赋值。变量可以作为左值,而算术表达式a+b就不能作为左值,常量也不能作为左值。
a=(b=5)
括号内的b=5是一个赋值表达式,它的值等于5.执行表达式“a=(b=5)”,就是执行b=5和a=b两个赋值表达式。因此a的值等于5,整个赋值表达式的值也等于5,赋值运算符按照“自右而左”的结合顺序,因此,(b=5)外面的括号可以不要,即a=(b=5)和a=b=5等价,都是先求b=5的值(得5),然后再赋给a。
a=b=c=5 //表达式值为5,a,b,c的值均为5
a=5+(c=6) //表达式值为11,a值为11,c值为6
a=(b=4)+(c=6) //表达式值为10,a值为10,b等于4,c等于6
a=(b=10)/(c=2) //表达式值为5,a等于5,b等于10,c等于2
a=(b=3*4) //将3*4的值先赋给b,再把b的值赋给a,a、b的值均为12
赋值表达式使得赋值操作不仅可以出现在赋值语句中,而且可以出现在其他语句中(如输出语句、循环语句等)如:printf("%d",a=b)
如果b的值为3,则输出a的值(也是表达式a=b的值)为3。在一个printf函数中完成了赋值和输出双重功能。
3、复合赋值运算符※
在赋值符=之前加上其他运算符,可以构成复合运算符
a+=3 //等价于a=a+3
x*=y+8 //等价于x=x*(y+8)
x%=3 //等价于x=x%3
凡是二元(二目)运算符,都可以与赋值符一起组合成复合赋值符。有关算术运算的复合赋值运算符有+=,-=,*=,/=,%=
注意
如果赋值符右边是包含若干项的表达式,则相当于它有括号,例如:
x%=y+3等价于x=x%(y+3),切勿错写为x=x%y+3
4、赋值过程中的类型转换※(不重要)
如果赋值运算符两侧的类型一致,则直接进行赋值。
int i;
i=54321
如果赋值运算符两侧类型不一致,但都是基本类型时,在赋值时要进行类型转换。类型转换是由系统自动进行的,转换的原则是:
①将浮点型数据(包括单、双精度)赋给整型变量时,先对浮点数取整,即舍弃小数部分,然后赋予整型变量
②将整型数据赋给单、双精度变量时,数值不变,但以浮点数形式存储到变量中。
③将一个double型数据赋给float变量时,先将双精度数转换为单精度,即只取6~7位有效数字,存储到float型变量的4个字节中。应注意双精度数值的大小不能超出float型变量的数值范围;将一个float型数据赋给double型变量时,数值不变,在内存中以8个字节存储,有效位数扩展到15位
④字符型数据赋给整型变量时,将字符的ASCII码赋给整型变量。
⑤将一个占字节多的整型数据赋给一个占字节少的整型变量或字符变量时,只将其字节原封不动地送到被赋值的变量(即发生“截断”)。
⑥将有符号整型变量赋给长度相同的无符号整型变量时,按字节原样赋值(连原有表示符号的最高位也作为数值一起传送)。将无符号整型变量赋给长度相同的有符号整型变量时,应注意不要超出有符号整型变量的数值范围,否则会出错。
总结:整型数据间赋值,按存储单元中的存储形式直接传送。实型数据间及整型与实型间赋值,先转换(类型)后赋值。
5、赋值表达式和赋值语句
C语言的赋值语句属于表达式语句,由一个赋值表达式假一个分号组成。
在一个表达式中可以包含另一个表达式
if ((a=b)>0)max=a;
/*先进行赋值运算(将b的值赋给a),然后判读a是否大于0,如大于0,执行max=a。
请注意,在if语句中的a=b不是赋值语句,而是赋值表达式。*/
注意:
区分赋值表达式和赋值语句。
赋值表达式的末尾没有分号,而赋值语句的末尾必须有分号。在一个表达式中可以包含一个或多个赋值表达式,但绝不能包含赋值语句。
6、变量赋初值
可以用赋值语句对变量赋值,也可以在定义变量时对变量赋以初值。
int a=3; //指定a为整型变量,初值为3;相当于int a;a=3;
float f=3.56; //指定f为浮点型变量,初值为3.56
char c='a'; //指定c为字符变量,初值为'a'
int a,b,c=5; //指定a,b,c为整型变量,但只对c初始化,c的初值为5;//相当于int a,b,c;c=5;
对几个变量赋予同一个初值
int a=3,b=3,c=3; //正确
int a=b=c=3; //错误,可以先定义,再用赋值语句,即
int a,b,c;a=b=c=3;
【例3.5】有两个整型变量a和b,要求把它们的值互换
解题思路:
假设关键是想出把两个变量的值互换的方法。不能把两个变量之间互相赋值:
a=b; //把变量b的值赋给变量a,a的值等于b的值
b=a; //再把变量a的值赋给变量b,变量b值没有改变
#include<stdio.h>
int main()
{int a=3,b=4,temp;temp=a;a=b;b=temp;printf("a=%d,b=%d\n",a,b);return 0;
}
//为了实现两个变量的值互换必须借助第三个变量
3.6.6条件运算符和条件表达式
- 条件运算符由“?”和“:”组成的。
- 条件表达式的一般形式:
表达式1? 表达式2:表达式3; - 条件表达式的语法规则
当表达式1的值为1(真)时,其结果为表达式2的值;
当表达式1的值为0(假)时,其结果为表达式3的值。
注意:
表达式1通常是关系表达式或逻辑表达式,也可以是其他表达式。
条件运算符又称为三目运算符,"三目"指的是操作数的个数有3个。
3.6.7逗号运算符和逗号表达式
- 由逗号运算符“,”将两个表达式连接起来:
表达式1,表达式2; - 逗号表达式的语法规则:
先计算表达式1,再计算表达式2;
最后结果为表达式2的结果。
说明:
1.逗号表达式可以扩充到具有n个表达式的情况:
表达式1,表达式2,…,表达式n:
整个逗号表达式的结果为表达式n的值。
2.通常是都逗号表达式来分别求逗号表达式内各表达式的值,并不是为了求整个逗号表达式的值。
3.变量定义中出现的逗号和在函数参数表中出现的逗号不构成逗号表达式。
4.逗号表达式有可能降低程序的可读性,请谨慎使用。
C语言程序设计(理论课)第二章(理解)算法和第三章数据类型及其运算相关推荐
- java程序语言设计第三章答案_java语言程序设计课后习题解答张思民第三章
java语言程序设计课后习题解答张思民第三章 1 第3章 面向对象程序设计基础 [1]什么是 Java 程序使用的类?什么是类库? [解答]:Java 程序的基本单位是类.对象是对事物的抽象,而类是对 ...
- C++语言程序设计第五版 - 郑莉(第三章课后习题)
第3章 函数 3-8 编写函数把华氏温度转换为摄氏温度,公式为:C = (F - 32) * 5/9 在主程序中提示用户输入一个华氏温度,转化后输出相应的摄氏温度. #include<iost ...
- 《Python语言程序设计》王恺 机械工业出版社 第三章课后习题答案
第三章 函数 3.7 课后习题 (1)在Python语言中,使用函数分为两个步骤:定义函数和调用函数 (2)在Python语言中,函数定义需要使用def关键字 (3)形参是在定义函数时函数后面 ...
- C语言程序设计第五版谭浩强 第七章答案
C语言程序设计第五版谭浩强著 第七章答案 第七章 用函数实现模块化程序设计 1.写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数,并输出结果.两个整数由键盘输人. 题目解析: ...
- C语言程序设计第五版 谭浩强 第四章 课后习题 答案
谭浩强C语言程序设计第五版 第4章 课后习题 答案 点我看视频讲解+可运行源码 记得一键三连哦 第四章 选择结构程序设计 1. 什么是算术运算?什么是关系运算?什么是逻辑运算? [答案解析] 算熟运算 ...
- c语言程序设计一维数组教案,《C语言程序设计》-任正云-电子教案 第7章数组
1.第七章 数组,The C Programming Language Chapter 7 Arrays,构造数据类型; 有序数据的集合; 可以看成是具有相同名字不同下标的同一数据类型的简单变量的集合 ...
- c语言程序设计江宝钏第九章,C语言程序设计 (江宝钏 著) 清华大学出版社 第9章习题答案1...
C语言程序设计 (江宝钏 著) 清华大学出版社 第9章习题答案1 一.程序阅读题 习题 9 答案 1.B2. C 二.编程题 1. #include #defineM 10 structstudent ...
- c语言程序设计曾怡课件,谭浩强 C语言程序设计教程(由曾怡视频修改) 第8章 函数课件...
谭浩强 C语言程序设计教程(由曾怡视频修改) 第8章 函数课件 一般搬家时转盘与大梁间是固定的,开钻前应根据转盘对井架进行校正,如果中途换转盘,则要在空负荷下根据井架对转盘进行校正 一般搬家时转盘与大 ...
- 深入理解java虚拟机gc_jvm GC收集器与内存分配(深入理解java虚拟机第三章)
jvm GC收集器与内存分配(深入理解java虚拟机第三章) 本篇是<深入理解java虚拟机第三章>的笔记记录. 一 为什么要关注GC和内存分配? 需要排查各种内存溢出.内存泄漏问题时,或 ...
- 算法复习第三章分治法
算法复习第三章分治法 循环日程表 最近点对 快速排序: 循环日程表 最近点对
最新文章
- Ubuntu Linux配置Nginx+MySQL+PHP+phpMyAdmin详细步骤
- MySQL使用规范_心得总结
- C语言返回文件大小的功能(fseek和ftell的使用)
- ECSHOP设置默认配送方式和默认支付方式
- hibernate one2one 唯一外键关联(双向关联)
- 来来来!2021最新Java面经分享
- 家庭路由器设置以及win10链接无线不显示登录密码 直接提示链接出错问题解决...
- 我看了全部文件的字符串资源
- 黑苹果驱动_黑苹果目前已可以完美驱动内置intel WiFi
- 《Java进阶学习+面试宝典》分享给大家
- QQ牧场接口协议分析
- linux ogv格式转换,使用OGV转换将OGV转换为Linux中的AVI | MOS86
- 不引入外部文件也可以显示图片
- 2020第三届微软Project用户大会暨年终项目管理专业化与信息化论坛
- python培训班大概多少钱
- 数字PAM信号功率谱密度推导
- SSL证书配置(https访问接口, 单向认证和双向认证)
- dump文件,windbg
- 【微服务实战】什么是微服务,微服务怎么实施?
- 什么是循环依赖以及解决方式