运算,即指的对数据的操作,运算符+数据→表达式
假设在机器上,整数用内存中
最高位为符号位,0表示正数,1表示负数
则69和-69分别表示为
除
6910=(
-6910=(
正整数的表示与原码相同,负整数的表示对
以16位二进制原码表示69为6910=(
所以,反码表示为:
6910=(
-6910=(
正整数的表示与原码相同,负整数的表示对
以16位二进制原码表示69为6910=(
所以,反码表示为:
6910=(
-6910=(
| 原码 | 反码 | 补码 | |
|---|---|---|---|
| +0 | 0000 0000 0000 0000 | 0000 0000 0000 0000 | 0000 0000 0000 0000 |
| -0 | 1000 0000 0000 0000 | 1111 1111 1111 1111 | 0000 0000 0000 0000 |
| +1 | 0000 0000 0000 0001 | 0000 0000 0000 0001 | 0000 0000 0000 0001 |
| -1 | 1000 0000 0000 0001 | 1111 1111 1111 1110 | 1111 1111 1111 1111 |
| 32767(215-1) | 0111 1111 1111 1111 | 0111 1111 1111 1111 | 0111 1111 1111 1111 |
| -32767(-(215-1)) | 1111 1111 1111 1111 | 1000 0000 0000 0000 | 1000 0000 0000 0001 |
| -32768(-216) | 1000 0000 0000 0000 | ||
| 32768(2!6) | 0000 0001 0000 0000 0000 0000 | 0000 0001 0000 0000 0000 0000 | 0000 0001 0000 0000 0000 0000 |
32767+1=? -32768-1=? (溢出)
16个二进制位表示整数,表示范围分别为
将整数表示成科学计数法,如-123.45写成科学计算法为-1.2345×102,可记成
用32位浮点数表示,包含:符号位(1位),阶码(8位),尾数(23位)
用64位浮点数表示,包含:符号位(1位),阶码(11位),尾数(52位)
字符型数据的存储采用ASCII码,存储在一个字节中
如字符常量'A'的ASCII码值为65,表示成
0100 0001
| 类别 | 名称 | 类型名 | 数据长度 | 取值范围 |
|---|---|---|---|---|
| 整型 | [有符号]整型 | int | 32 bits | -231 ~ 231-1 |
| [有符号]短整型 | short[int] | 16 bits | -215 ~ 215-1 | |
| [有符号]长整型 | long[int] | 32 bits | -231 ~ 231-1 | |
| 无符号整型 | unsigned[int] | 32 bits | 0 ~ 232-1 | |
| 无符号短整型 | unsigned short[int] | 16 bits | 0 ~ 216-1 | |
| 无符号长整型 | unsigned long[int] | 32 bits | 0 ~ 232-1 | |
| 字符型 | 字符型 | char | 8 bits | 0 ~ 255 |
| 实型 (浮点型) |
单精度浮点型 | float | 32 bits | ±(10-38 ~ 10+38) |
| 双精度浮点型 | double | 64 bits | ±(10-308 ~ 10308) | |
| 类别 | 名称 | 类型名 | 数据长度 | 取值范围 |
|---|---|---|---|---|
| 整型 | [有符号]整型 | int | 32 bits | -231 ~ 231-1 |
| [有符号]短整型 | short[int] | 16 bits | -215 ~ 215-1 | |
| [有符号]长整型 | long[int] | 32 bits | -231 ~ 231-1 | |
| 无符号整型 | unsigned[int] | 32 bits | 0 ~ 232-1 | |
| 无符号短整型 | unsigned short[int] | 16 bits | 0 ~ 216-1 | |
| 无符号长整型 | unsigned long[int] | 32 bits | 0 ~ 232-1 | |
| 十进制 | 二进制 | 八进制 | 十六进制 | |
|---|---|---|---|---|
| 正、负号 0~9 首位非0 |
正、负号 0~7 首位为0 |
正、负号 0~9,A~F 前缀0x |
||
| 如1010 | 10 | 0000 1010 | 012 | 0xA |
| 如1610 | 16 | 0001 0000 | 020 | 0X10 |
| 如12310 | 123 | 0111 1011 | 0173 | 0x7B |
整数的取值不能超出整型数据的取值范围
比长整型数还要大的数用实数表示
用后缀表示整数类型,如123
字符具有数值特征,字符变量和整型变量的定义和赋值可以在ASCII码范围内互换
char c;
c='A'; //==>等价于 c=65;
int i;
i=65; //==>等价于 i='A';
字符常量用单引号表示,如'a', 'A', '9', '+', '$'
所有的字符定义在ASCII字符集中,'0'~'9', 'A'~'Z', 'a'~'z'
可对字符进行运算,注意区分数字1和字符'1'
char c;
c='A'; // c的值为65
printf("%d %c", c, c); // 输出 65 A
c=c+1; // c的值为66,对应字符'B'
printf("%d %c", c, c); // 输出 66 B
c=c+'1'; // c的值为115
printf("%d %c", c, c); // 输出 115 s
| 字符 | 含义 |
|---|---|
| \n | 换行 |
| \t | 横向跳格(用于输出若干个空格) |
| \b | 退格,用于显示输出时刷新左边一个字符 |
| \\ | 反斜杠字符'\' |
| \" | 双引号 |
| \' | 单引号 |
| \ddd | 1-3位八进制数ddd所代表的字符,如\007为“嘟”声,\40为空格 |
| \xhh | 1-2位十六进制数ddd所代表的字符,如\x41为'A',\20为空格 |
| 类别 | 名称 | 类型名 | 数据长度 | 取值范围 |
|---|---|---|---|---|
| 实型 (浮点型) |
单精度浮点型 | float | 32 bits | ±(10-38 ~ 10+38) |
| 双精度浮点型 | double | 64 bits | ±(10-308 ~ 10308) | |
float x=1234567.89; /* 数据在取值范围内,但无法精确表达 */
float y=1.2e55; /* 数据的精度不高,但超出取值范围 */
printf(格式控制, 输出参数1, ..., 输出参数n);
scanf(格式控制, 输入参数1, ..., 输入参数n);
| 类别 | 十进制 | 八进制 | 十六进制 |
|---|---|---|---|
| int | %d | %o | %x |
| long | %ld | %lo | %lx |
| unsigned | %u | %o | %x |
| unsigned long | %lu | %lo | %lx |
#include<stdio.h>
int main()
{
printf("%d, %o, %x\n", 10, 10, 10);
printf("%d, %d, %d\n", 10, 010, 0x10);
printf("%d, %x\n", 012, 012);
return 0;
}
#include<stdio.h>
int main()
{
int a, b;
printf("Input a, b:");
scanf("%x%d", &a, &b);
printf("%d%5d\n", a, b); /* %5d指定变量b的输出宽度为5 */
printf("%x, %d\n", a, b);
return 0;
}
#include<stdio.h>
int main()
{
double d=3.1415926;
printf("%f, %e\n", d, d);
printf("%5.3f, %5.2f, %.2f\n", d, d, d); /* 分别指明总位数和小数位数 */
return 0;
}
假设float的精度为7位,double的精度为16位
#include<stdio.h>
int main()
{
float f;
double d;
printf("Input f, d:");
scanf("%lf%lf", &f, &d);
printf("f=%f\n d=%f\n", f, d);
d=1234567890123.12;
printf("d=%f\n", d);
return 0;
}
Input f, d:
f=1234567954432.000000
d=1234567890123.123540
d=1234567890123.120120
char ch;
scanf("%c", &ch);
printf("%c", ch);
char ch;
ch=getchar();
putchar(ch);
#include<stdio.h>
int main()
{
char ch1, ch2;
ch1=getchar();
ch2=getchar();
putchar(ch1);
putchar('#');
putchar(ch2);
return 0;
}
#include<stdio.h>
int main()
{
char ch1, ch2, ch3;
scanf("%c%c%c", &ch1, &ch2, &ch3);
printf("%c%c%c%c%c", ch1, '#', ch2, '#', ch3);
return 0;
}
例6-1. 大小写英文字母转换
输入一行字符,将其中的大写字母转换为小写字母后输出,小写字母转换为相应的大写字母后输出,其它字符按原样输出
大小写英文字母转换
'b'-'a'='B'-'A'
......
'z'-'a'='Z'-'A'
'm'-'a'+'A'==>'M'
'M'-'A'+'a'==>'m'
数字字符和数字转换
'9'-'0'=9-0
'9'='0'+9
......
'1'='0'+1
#include<stdio.h>
int main()
{
char ch;
printf("Input characters:");
while((ch=getchar())!='\n'){
if(ch>='A' && ch<='Z')
ch=ch-'A'+'a';
else if(ch>='a' && ch<='z')
ch=ch-'a'+'A';
putchar(ch);
}
}
不同类型数据的混合运算,先要将数据转换成相同的类型,再运算
非赋值运算
自动转换类型:
char, short → int
unsigned short → unsigned
long → unsigned long
float → double
int → unsigned → unsigned long → double
计算表达式'A'+12-10.05的结果,类型是?
计算赋值运算符右侧表达式的值
将赋值运算符右侧表达式的值赋给左侧的变量(自动转换右侧表达式的类型)
double x;
x=1; /* x=? */
int ai;
ai=2.56; /* ai=? */
short a=1000;
char b='A';
long c;
c=a+b; /* c=? */
short bi;
bi=0X12345678L; /* bi=? */
强制类型转换运算符:
如
#include<stdio.h>
int main()
{
int i;
double x;
x=3.8;
i=(int)x;
printf("x=%.f, i=%d\n", x, i);
printf("(double)(int)x=%f\n", (double)(int)x);
printf("x mod 3=%d\n", (int)x%3);
return 0;
}
| 目数 | 单目 | 双目 | |||||||
| 运算符 | ++ | -- | + | - | + | - | * | / | % |
| 名称 | 自增 | 自减 | 正值 | 负值 | 加 | 减 | 乘 | 除 | 模(求余) |
int n, m;
n=2; m=++n; /* m=3, n=3 */
n=2; m=n++; /* m=2, n=3 */
双目运算符(+, -) → 双目运算符(*, /, %) → 单目运算符(+, -, ++, --)
-5+3%2=(-5)+(3%2)=-4
3*5%3=(3*5)%3=0
-i++=-(i++)
写出下列表达式
s(s-a)(s-b)(s-c) →
(x+2)e2x →
$\frac{-b+\sqrt{b^2-4ac}}{2a}$ →
int n;
double x, y;
x=3*4; /* 表达式的值为12,类型为浮点双精度 */
x=y=3; /* x=(y=3), y=3的值为3.0,类型为浮点双精度,x的值为3.0,类型为浮点双精度 */
n=3.14*2; /* n的值为6 */
x=10/4; /* x的值为2.0 */
复合赋值运算符包括:+=, -=, *=, /=, %=
赋值表达式更新为: 变量
x
x
关系运算符用于比较两个操作数,比较结果为
x<y x
<=y x==y
x>y x>=y x!=y
运算符优先级:
算术运算符 → 比较运算符(
运算符左结合
a>b==c →
d=a>b →
ch>'a'+1 →
d=a+b>c →
3<=x<=5 →
b-1==a!=c →
用
char c='w';
int a=2, b=3, c=1, d, x=10;
a>b==c → (a>b)==c
d=a>b → d=(a>b)
ch>'a'+1 → ch>('a'+1)
d=a+b>c → d=((a+b)>c)
3<=x<=5 → (3<=x)<=5
b-1==a!=c → ((b-1)==a)!=c
(ch>='a' && ch<='z') || (ch>='A' && ch
<='Z')
ch == ' ' || ch == '\n'
x >= 3 && x <= 5
逻辑运算符为:
逻辑运算结果:
逻辑运算对象: 关系表达式 或 逻辑量,如x>=3
逻辑量,非0为真,0为假
| a | b | a&&b | a||b | !a |
| 1 | 1 | 真(1) | 真(1) | 假(0) |
| 1 | 0 | 假(0) | 真(1) | 假(0) |
| 0 | 1 | 假(0) | 真(1) | 真(1) |
| 0 | 0 | 假(0) | 假(0) | 真(1) |
赋值运算符 → 逻辑运算符(|| &&) → 关系运算符 → 算术运算符 → 逻辑运算符
运算符左结合
a || b && c →
!a && b →
x >= 3 && x <= 5 →
!x == 2 →
a || 3 + 10 && 2 →
用
char c='w';
int a=2, b=0, c=0;
float x=3.0;
a && b →
a || b && c → a || (b && c)
!a && b → (!a) && b
a || 3 + 10 && 2 → a || ((3 + 10) && 2)
!x == 2 → (!x) == 2
!(x==2) →
ch || b →
例6-4. 写出满足要求的逻辑表达式
x==0
!x
x!=0
x
x!=0 || y!=0
!(x==0 && y==0)
x||y
等价于
if(exp1)
exp2;
else
exp3;
分析下列条件表达式
int n;
a=(n>0)?2.9;1;
n=10时, a=2.9
n=-10时, a=1
if(a>b)
z=a;
else
z=b;
z=(a>b)?a:b;
$$y=\begin{cases} x+2 & x>0\\ x^2 & x\leq 0 \end{cases} $$
y=(x>0)?x+2:x*x;
表达式1, 表达式2, ......, 表达式n
先计算表达式1,再依次计算表达式n的值 ,将表达式n的值作为逗号表达式的值
int a, b, c; (a=2), (b=3), (c=a+b);
逗号运算符的优先级最低,左结合
for(i=0, sum=0; i<=100; i++)
sum+=i;
| 运算符 | 名称 | 备注 |
| & | 按位"与" | 双目 |
| | | 按位"或" | 双目 |
| ^ | 按位"异或", 相同取0,不同取1 | 双目 |
| ~ | 按位"取反" | 单目 |
| <<< /td> | 左移位 | 双目 |
| >> | 右移位 | 双目 |
x = 0 00000000 00000000
y = 3 00000000 00000011
x & y 00000000 00000000
x | y 00000000 00000011
x ^ y 00000000 00000011
x && y 0
x || y 1
1010 ^ 0101 = 1111
<< 对操作数左移给出的位数,低位补零
>> 对操作数右移给出的位数,高位补零
x<<3 将x向左移3位,空出的位用零补足
00111010 <<3
11010000
x>>3 将x向右移3位,空出的位用零补足
00111010 >>3
00000111
复合位赋值运算符有:&= |= ^= >>=
<<=
a &= b 相当于 a = a & b
a <<= 2 相当于 a=a << 2
长度运算符(sizeof),是单目运算符,用于计算
int a;
sizeof(a); // 求整型变量a的长度,值为4(bytes)
sizeof(int); // 求整型的长度,值为4(bytes)
sizeof(double); // 求双精度浮点数的长度,值为8(bytes)
例6-5. 统计单词的个数
输入一行字符,统计其中单词的个数,其中,“单词”指的是连续不含空格的字符串,各单词之间用空格分隔,空格数可以是任意多个
#include<stdio.h>
int main()
{
int cnt, word; /* cnt记录单词的个数,word表示新单词标识 */
char ch;
word=cnt=0; /* word初值为0,表示还没有遇到新单词 */
printf("Input characters:");
while((ch=getchar())!='\n'){
if(ch==' ') /* 读入空格,表示不是单词 */
word=0; /* word赋0,表示没有遇到新单词 */
else if(word==0){ /* 读入非空格且word为0,此为单词首字母 */
word=1; /* word赋1,表示遇到新单词 */
cnt++; /* 累加单词计数器cnt */
}
}
printf("%d\n", cnt);
return 0;
}