第三章表达式
表达式
?作用
在C源程序中表示对数据进行运算或判断的操作。
表达式是语句的基本组成要素。
?表达式的组成
–操作数 (operand)
–运算符 (operator)
第一节操作数
一、操作数的类型
1、数据的类型与类型说明符
2、操作数在表达式中的表现形式
?基本类型常量(int,float,double,char,枚举型)
?基本类型变量的直接引用( int,float,double,char,枚举型)
?基本类型变量的间接引用( int,float,double,char,枚举型)
?构造类型变量成员的直接引用(数组,结构,联合)
?构造类型变量成员的间接引用(数组,结构,联合)
?指针型常量
?指针型变量的直接引用
?指针型变量的间接引用
?表达式(包括:函数调用)
3、系统预定义的类型说明符
?作用
用于声明变量的类型、函数参数的类型、函数返回值的类型等。
?种类(5个)
int,float, double, char, void
? int
整型,用16位/32位二进制补码表示和存储
例:int a; (声明变量a为整型)
? float
单精度实型,用32位二进制浮点数表示和存储,有效数位数7位(十进制数) 例:float a; (声明变量a为单精度实型)
?double
双精度实型,用64位二进制浮点数表示和存储,有效数位数可达16位(十进制数) 例:double a; (声明变量a为双精度实型)
?char
字符型,用8位二进制ASCII码表示和存储
例: char a; (声明变量a为字符型)
?void
无值型
例:void f ( void)
{ printf(”ok”); }
(声明函数f为无形式参数并且无返回值的函数)
void a; (错误)
4、系统预定义的类型修饰符
?位置与作用
出现在系统预定义类型说明符之前,
对类型作进一步的说明和扩充。
?种类(4个)
signed,unsigned
short, long
?signed ,unsigned
可修饰 int 和 char
signed:该类型数的最高位作为符号位使用
unsigned:该类型数的最高位作为数值位使用
缺省时为signed
例:
signed int a; 等同 int a;
(声明a为有符号int型变量)
unsigned int a; (声明a为无符号int型变量)
signed char b; 等同 char b;
(声明b为有符号char型变量)
unsigned char b; (声明b为无符号char型变量)
?short
可修饰 int
short int为16位(数据位少于或等于int的位数)。
TC系统: int a ;(a占用16位存储空间)
short int a;( a占用16位存储空间)
VC系统: int a;( a占用32位存储空间)
short int a;(a占用16位存储空间)
?long
(1) 可修饰 int, long int为32位(数据位大于或等于int的位数)。
例:
TC: int a;( a占用16位存储空间)
long int a;( a占用32位存储空间)
VC: int a;( a占用32位存储空间)
long int a;( a占用32位存储空间)
(2) 可修饰 double,long double 数据位大于或等于double的位数。
例:double b; (b占用64位存储空间)
long double b; (b占用128位存储空间)
5、类型说明符与修饰符的组合及可表示值域(P43,P46)
[signed] int (TC系统 16位)-32768 ~ 32767
(VC系统32位) -2147483648 ~ 2147483647
unsigned int ( TC系统16位) 0 ~ 65535
( VC系统32位) 0 ~ 4294967295
[signed] short [int] (16位)-32768 ~ 32767
unsigned short [int](16位)0 ~ 65535
[signed] long [int] (32位) -2147483648 ~ 2147483647 unsigned long [int](32位) 0 ~ 4294967295
[]部分可缺省
float (32位) ± 10-38 ~ 10 38
double (64位) ± 10-308 ~ 10 308
long double (Tc: 80位) ± 10-4931 ~ 10 4932
[signed] char (8位) -128 ~ 127
unsigned char (8位) 0 ~ 255
二、常量(constant)
1、常量的含义
在程序运行期间其值不改变的操作数。
2、常量的类型
整型常量
实型(浮点型)常量(分为:float型,double型)
字符型常量
枚举型常量
字符串常量
3、常量在表达式中的表示形式(2种)
(1)直接常量 (2)符号常量(代表常量的标识符)
#include
#define PI 3.14159 符号常量PI的宏定义,无分号
main()
{ float r;
double area,peri;
r = 1.5f; 直接常量 1.5 , float型,f是后缀 area = PI*PI*r; 符号常量 PI,double型
peri= 2*PI*r; 直接常量2,int型
printf(“area=%f , perimeter=%f ”,area,peri);
}
?符号常量宏定义一般形式
#define 符号常量名常量字符序列
例,有宏定义如下:
#define SIZE 80
#define END ’\0’
#define FORMAT ”%d%d%d”
#define NULL 0 (stdio.h中出现)
在程序中使用已定义的符号常量:
int a=SIZE;
printf(FORMAT, x,y,z);
?使用符号常量的优点
提高程序可读性,保持数据一致性,便于修改常量的值
?符号常量命名规则
应遵守标识符命名规则
?符号常量命名约定
通常用大写字母(以区别变量)
选取有意义的单词
4、常量的存储
保存常量的内存单元位置不确定。
常量的存储字节数(C89标准):
int型常量: 2~4字节, 补码表示
float型常量: 4字节,浮点表示
double型常量: 8~16字节,浮点表示
char型常量: 1字节,字符编码
5、常量在程序中的作用
在表达式中做操作数参加计算
在函数调用中做实际参数传给被调函数的形式参数
6、整型常量在程序中的表示
?整型常量的特点
不含小数点的数字字符串
?整型常量的在程序中的表示形式(3种)
十进制表示,八进制表示,十六进制表示
?整型常量的类型
(低级)signed short int (2字节存储)
unsigned short int (2字节存储)
int (2字节/ 4字节存储)
unsigned int (2字节/4字节存储)
signed long int (4字节存储)
(高级) unsigned long int (4字节存储)
(1) 整型常量的十进制表示
?整型常量十进制表示的语法规则
非0开始的数字字符串。可带后缀u、U(unsigned int型)或l、L(long int型)。?signed short int 型常量表示( TC系统int型)
–值在-32768 ~ 32767 内不带后缀的数字字符串
例:printf(“%d”, 4000 ); 4000是signed short int型
?unsigned shore int型常量表示(TC系统unsigned int型)
–值在32768 ~ 65535内不带后缀的数字字符串
–值在0 ~ 32767 内带后缀u或U的数字字符串
例:
printf(“%u”, 40000 ); 40000是unsigned shore int型
printf(“%u”, 5u ); 5是unsigned shore int型
?signed long int 型 (VC系统int型)
–值在-32768 ~ 65535 外,但在
-2147483648 ~2147483647 内不带后缀的数字字符串
–值在-32768 ~ 65535 内带后缀l或L的数字字符串
例:printf(“%ld”, 400000 ); 400000是signed long int 型
printf(“%ld”, 5L ); 5是signed long int 型
?unsigned long int型 (VC系统unsigned int型)
–值在2147483647~4294967295内不带后缀的数字字符串。例:3000000000
–值在65536 ~ 2147483647 内带后缀u或U的数字字符串。例: 40000U
–值在0~32767 内带后缀u或U和l或L的数字字符串。例: 5UL
不带后缀的十进制表示int型常量的数据类型是自低向高能够表示该常量的第一个int型类型。 30000 / 40000 / 300000 / 3000000000
short int /unsigned short int / long int / unsigned long int
TC的int / TC的unsigned int / VC的int / VC的unsigned int
?十进制表示整型常量存储举例
10 : 0000 0000 0000 1010 (二进制补码表示)
(在TC中被看作int型常量)
-10 : 1111 1111 1111 0110 (二进制补码表示)
(在TC系统中被看作int型常量)
32768: 1000 0000 0000 0000
(在TC系统中被看作unsigned int型常量)
?将某一类型的整型常量赋值给低于它的整型变量时,将发生溢出。
?例如,在TC2.0系统中运行如下程序:
int x;
unsigned int y;
x=32768; 赋值溢出,但编译系统不报告
y=32768; 正确
printf (“%d, %u”, x , y );
输出: -32768(溢出后的结果),32768
(2) 整型常量的八进制表示
?整型常量八进制表示的语法规则
以0开始的数字字符串。可带后缀U或L 。
int x;
x=0123; 等同于 x=83;
?八进制表示整型常量存储举例
0123: 0000 0000 0101 0011 (TC系统)
(3) 整型常量的十六进制表示
?整型常量十六进制表示的语法规则
以0x开始的数字字符串 ,可带后缀U或L 。
int x ;
x=0xffff;等同于 x= -1 ;
?十六进制表示整型常量存储举例
0xffff:1111 1111 1111 1111 (TC系统)
源程序中出现的int型常量的类型取决于常量的进制表示形式、常量的值和常量所带的后缀
7、实型常量在程序中的表示
实型数又称浮点数(floating point number)
?实型常量的特点
含有小数点、数字和字母e的字符串,小数部分可省略
?实型常量的在程序中的表示形式(2种)
十进制小数形式,十进制指数形式
?实型常量的类型
float型常量:
带后缀f或F的十进制小数形式或十进制指数形式(4字节存储)
例如:1.5f 或 1.5F, 1e-2f 或 1e-2F
double型常量:
不带后缀的十进制小数形式或十进制指数形式(8字节存储)
long double型常量:
带后缀l或L的十进制小数形式或十进制指数形式(一般16字节,TC系统10个字节 ) 例如:1.5l 或 1.5L , 1e-2l 或 1e-2L
(1)实型常量的十进制小数形式
例: 12.3 , -12.3 , .123 , -1. , -.2
?一般形式
± a.b
?省略规则
当a或b中一个为0时可省略,a与b不能同时省略
小数点不能省略
(2)实型常量的十进制指数形式
例:1.23e2 (代表 1.23?102 )
-1.23e-2 (代表 -1.23 ? 10 –2 )
1E-6 (代表 1.0 ? 10 –6)
?一般形式
± a.b e ± c 或± a.b E ± c
?省略规则
a为0时可省略
b为0时可省略并可同时省略小数点
c不能省略且必须为整型常量
?规范化指数形式
小数点前只有一位非0整数。例:1.23 e-2
?错误的实型常量表示
e10 .e5 2e 1e3.5 2e(4/2)
8、字符型常量
?字符型常量的特点
放入一对单引号中的一个或多个字符。
例:‘A’, ’\n’
?字符型常量在程序中的表示形式(2种)
一对单引号中只出现一个字符
一对单引号中出现以“\”开始的多个字符
?一对单引号中只出现一个字符的形式
表示能输入和输出的字符。
例: char c1,c2;
c1=‘A’, c2=‘0’+1;
‘A’和‘0’均是char型常量
printf(“%c,%c,%d,%d”,c1,c2,c1,c2);
输出:A , 1 , 65 , 49
(2)一对单引号中出现以“\”开始的多个字符形式
例:‘\n’, ’\b’, ’\101’, ’\x41’
?转义序列
以“\”开始的字符序列。
?转义序列的作用
–表示控制字符
\n : 表示“Enter”(ASCII编码:13和10)
\b : 表示”Backspace” (ASCII编码:8)
\t : 表示“Tab”(跳到下一制表符位置)
–表示ASCII编码表中出现的任意字符
既可以输入也可以输出的字符
无法从键盘输入但可以输出的字符
\ooo: 1~3个o (o代表数字字符0~7)
表示其ASCII编码的八进制表示为ooo的字符
例:‘\101’ 中101是A的ASCII编码的八进制表示
\xhh: 1~2个h(h代表数字字符0~9及字母a~f)
表示其其ASCII编码的十六进制表示为hh的字符
例:‘\x41’中41是A的ASCII编码的十六进制表示
char c1,c2;
c1=‘\101’ ; 或c1=‘A’; A既可以由键盘输入也能输出
或scanf(“%c”,&c1); 键盘输入:A
c2=‘\5’; 字符?不能键盘输入但可以输出
printf(“%c,%d”,c1,c1); 输出字符A及编码: A, 65
printf(“%c,%d”,c2,c2); 输出字符?及编码:?, 5
char c1,c2;
c1=‘\x41’ ; 或c1=‘A’;
c2=‘\x5’;
printf(“%c,%d”, c1, c1) ; 输出: A, 65
printf(“%c,%d”, c2, c2) ; 输出: ?, 5
以上程序中‘\101’,‘A’,‘\5’,‘\x41’,‘\x5’均是字符型常量
?字符型常量和整型常量在C源程序中可以互换使用
例:
int a;
char c;
a=‘1’; 或 a=49;
c= 65; 或c=‘A’;
限于采用ASCII编码表示字符的计算机系统
?系统头文件limits.h 包含了当前使用的编译系统下char、int类型的最大值和最小值。
9、字符串常量(简称:字符串string)
放入一对双引号中的字符序列。
例:“A”, “good”, ”x=%d”
?字符串的存储
–系统预定义数据类型中没有字符串类型,因此不能用基本类型变量存储字符串
–一般用char型数组存储字符串。存储时,必须在存储了字符串包含的有效字符之后多存储一个0 (0是字符串结束标记,表示为‘\0’ ,使程序在处理时能找到字符串的结束位置)
例:将字符串“good”存储到一维数组的操作
char a[5]=“good” , b[5];
b=“good”; (错) b[5]=“good”; (错)
b[0]=‘g’; b[1]=‘o’; b[2]=‘o’; b[3]=‘d’; b[4]=‘\0’;
?字符串常量的值(指针类型)
字符串存储时第一个字符所在存储单元的首地址
char c;
c=“a”;(错误)c=‘a’;(正确)
注意字符型常量与字符串常量的区别(‘a’和”a”)
?字符串常量中可出现多个转义序列
printf(“ abc\tde\rf\tg\n”);
输出:f ge ( f和g之间有7个空格)
?字符串常量中需要出现字符“\”时必须用“\\”表示
fp=fopen(“d:\\tc\\f.out”,”w”);
三、基本类型变量(变量variable)
1、变量的含义
在程序运行期间其值可以改变的操作数。
变量通常在内存中建立,有些变量也可以在CPU寄存器中建立。
2、变量在程序中的作用
保存数值(初始值,运算结果值)
在表达式中引用变量的值做操作数参加表达式计算
在函数调用表达式中的值做实参传给被调用函数的形参
3、变量的类型(按作用域分类)
?全局变量
在函数外任何位置声明的变量
?局部变量
在函数内或块内(一对花括号内)开始位置声明的变量
?形参变量
在函数定义的形式参数表中声明的变量
4、变量的属性
?操作属性
变量名,变量类型,变量的值,变量的指针
变量的作用域
?存储属性(第七章介绍)
?变量名
用于标识和直接引用一个变量。
命名规则:应遵守标识符命名规则。
命名习惯:全部用小写字母或第一个字符用小写字母,选用有意义的单词。
匈牙利命名法。
?变量类型
可以是任何已定义的类型(基本类型,构造类型,指针类型)
变量类型决定变量占用内存的单元数量
?变量的值
变量所标识的内存单元中当前保存的数值。
变量存在期间必有一个值(确定的,不确定的)
变量值的类型取决于变量类型。
可以给一个变量多次赋值,但变量所代表的存储单元中只保存最近一次所赋的值。
一个变量的值可以被多次引用做各类运算或被传递,其值不变。
?变量的指针
变量在内存中占用的存储区是确定的
变量的指针是变量存储区的起始地址
通过取地址运算符&可以得到变量的指针
例:int a, b;
scanf(“%d,%d”, &a, &b);
printf(“%p,%p”, &a, &b);
输入:15,16
输出:FF00 , FF02(TC系统)
FFFFFF00 , FFFFFF02(VC系统)
?变量的作用域
源程序中允许直接引用变量的区域范围
全局变量作用域:
变量声明位置至源程序文件结束的区域内。
局部变量作用域:
变量声明所在函数体内或块内。
形参变量作用域:
变量声明所在函数体内。
?三类变量的作用域举例
float x; x: 全局变量
main( )
{ int a, b; a,b: 局部变量
a=x;
a=b;
a=k; (引用变量k错误)
x= f (a,b); … …
}
int f ( int k, int m) k,m: 形参变量
{ x=k;
a= m; (引用变量a错误)
}
5、变量声明
?语法规则
任何变量必须在其作用域开始时先声明后引用。
?全局变量声明格式
[存储类型] 数据类型变量名 [=初值常量表达式],
变量名 [=初值常量表达式],… ;
可缺省:
存储类型、初值常量表达式(缺省时变量初值为0)
float x=1 , y ; y初值为0
main( )
{ x=y; .. . }
?局部变量声明格式
[存储类型] 数据类型变量名 [=初值表达式],
变量名 [=初值表达式],… ;
可缺省:
存储类型、初值表达式(缺省时变量初值不确定)
例: float x=1.5, y=sin(x),z=x+y , w;
int x=y=z=0; (语法错误)
若存储类型是static,初值表达式必须是常量表达式
例: static float x=1.5, y=1.5+1 ; (正确)
static float x=1.5, y=x+1 ; (错误)
?形参变量声明格式(第七章介绍)
?注意变量声明的位置
main()
{ printf(“input a number:”);
int a; ←语法错(C89标准)
. . .
}
Error: Expression syntax in function main
6、变量的直接引用
?直接引用变量的含义
在变量声明以外的其它地方用变量名引用该变量。
?直接引用变量的形式
(1) 给变量赋值(改变变量的值)
(2) 使用变量的值(不改变变量的值)
?给变量赋值
( assignment , 有时也称为definition)
通过表达式赋值 y = x+1 ; (直接引用y,x)
调用输入函数赋值scanf ( “%d”, &z ); (直接引用z)
注意:避免溢出
例: Tc系统
int y=32768 ; y的初值溢出,y ← -32768
int x; long y;
x=32767;
y=x+1; x+1结果溢出,y -32768
(2) 使用变量的值(use)
在表达式中做操作数: 2*x; (直接引用x)
在函数调用中做实参:sqrt(x); printf(“%f ”,x);
?规则
变量应先赋值(definition)后使用(use)
只能在变量的作用域内直接引用该变量。
一个变量可以被多次直接引用。
例1:
#include
main( )
{ int a,b;
b=2*a; 变量a的值在使用时不确定
scanf(“%d”,&a); …
}
Warning:possible use of “a” before definition in main
例2:
#include
main()
{ char c,d;
c='a';
printf("hello");
}
Warning:
? 'd' declared but never used in function main
d被声明但从未被使用
? 'c' is assigned a value which is never used function main c被赋了一个值但从未被使用7、变量的间接引用(初步)
?变量的间接引用的含义
通过变量的指针和间接引用运算符*或[ ]引用该变量
int x, y, *p;
p=&x; 将x的指针保存到指针型变量p
*p=1; *p 间接引用了变量x,因此*p等同x
y=*p+1;
scanf(“%d”, p); p 等同 &x
printf(“%d”, *p); *p 等同 x
?规则
在变量作用域的内外均可间接引用该变量。
一个变量可以被多次间接引用。
第二节运算符与表达式
一、表达式概述
1、表达式的含义
用运算符和圆括号将操作数连接起来的符合语法规则的字符序列。
2、表达式的三种形式
设:op代表运算符
x,y,z代表任意合法形式的操作数
? op x ,x op 例:++c , c++ , -x
? x op y 例:a+b , c<=10 , a=1, sqrt(4), x[0]
? x op y op z 例:a>0 ? a : -a
3、表达式的值
每个表达式都会产生一个确定的值或引用一个存储区。
?有些表达式的值是运算的结果,保存其值的存储区不确定,占用的存储单元数量由表达式值的类型决定。例:double a;
a=1.5+2; (表达式1.5+2代表一个运算结果值,double 类型)
?有些表达式的值是引用确定的存储区。
例: int x,*p;
p=&x;
*p = 1;(表达式*p引用变量x)
?表达式的值可能影响程序的执行流程
int c=0;
while(c<=10)
{ printf(“%d”,c);
c=c+2;
}
“c<=10”的值决定后面的语句(循环体)是否被再次执行
4、表达式的类型
基本表达式,算术表达式,赋值表达式,
类型转换表达式,逗号表达式,函数调用表达式
关系表达式,逻辑表达式,条件表达式
指针表达式,位运算表达式
二、基本表达式
?特点
不含运算符,只有一个操作数的表达式。
例:float x=1.4;
以下均为基本表达式:
10, 1.5, 1.5f,‘a’,“good”,x
三、算术表达式
?特点
含算术运算符,有1~2个操作数。
?算术运算符(10个)
二目: +、–、*、/、%
单目: +、–、++、––、sizeof
1、包含二目+、–、*、/、%运算符的算术表达式
?一般形式: e1 op e2
op: +、–、*、/、%
e1,e2:表达式
(1) e1,e2可以是不带运算符的基本表达式
基本类型常量(int,float,double,char,枚举)
基本类型变量、构造类型变量的直接引用
指针类型常量(仅限+、-运算)
指针类型变量的直接引用(仅限+、-运算)
(2) e1,e2也可以是带运算符的表达式
基本类型变量的间接引用
构造类型变量成员的直接引用和间接引用
指针类型变量的间接引用(仅限+、-运算)
其他表达式
?运算功能及表达式的值(与数学运算相同)
?e1%e2 表达式值的符号
e1、e2同号时结果为正, e1、e2异号时结果为负。
例: -30%-7的值为2 , -30%7的值为-2
?二目+、–、*、/、%运算符的优先级
*、/、% : 高
+、-: 低
?二目+、–、*、/、%运算符的结合性
自左向右
?加圆括号时提高括号内运算符的优先级
出现嵌套圆括号时内括号优先级高于外括号
例:int r=1,q=2 ,p=1,; float w=2.3;
double y=3; long x=1;
表达式:p * r % q + w / x – y
x + y / x – y
(x+y) /(x – y)
?表达式中操作数的类型转换
?两个操作数类型相同才能做+、–、*、/、%运算。类型不相同时,编译系统自动提升较低类型的操作数为较高类型后再做运算(%除外)。表达式值的类型为操作数的最终类型。
数据类型的等级:
高: long double
double ← float
unsigned long int
long int
unsigned int
低: int ← short int ,char
(2) char和short int型被自动提升为int型后再运算
float型被自动提升为double型后再运算
例:1/5 的类型是int
1./5 的类型是double
已知double y=1; y+1的类型是double
(3)运算符%的两个操作数必须均为整数型(整数型:int,char), 如不是必须做强制转换。
例:double x=1; int a;
a= (int) x%2;
2、包含单目+、–运算符的算术表达式
?一般形式: +e ,– e
e: 表达式
例:-1,– x , +x,– ( x+1)
?+e表达式的值:取e的原值
– e表达式的值:取e的负值
?单目+、–运算符优先级:高于所有二目运算符
?单目+、–运算符结合性:自右向左
例: int a=25, b=4, c=4;
a* – b的值:
– 100
a* ––b的值:
100 等同“a*(–(–b))”
3、包含单目++,--运算符的算术表达式
?一般形式:++v , v++, --v, v--
v: 左值表达式(简称:左值,Lvalue)
例:int x=0;
++x, x++, --x, x--
?左值表达式的含义
引用一个确定存储区域的表达式。常见左值表达式:
基本类型变量的直接引用
基本类型变量的间接引用
构造类型变量成员的直接引用
构造类型变量成员的间接引用
指针类型变量的直接引用
指针类型变量的间接引用
例:
int x ,*p; p=&x;
++x;
正确:操作数直接引用变量x
(*p) --;
正确:操作数间接引用变量x
p++ ;
正确:操作数直接引用变量p
3++;
报错信息:Lvalue required in function …
错误原因:操作数(常量)引用的存储区不确定.
++(x+1); 错误:原因同上
sqrt(x)--; 错误:原因同上
? ++,--运算符的运算功能及表达式的值
++v :等同 v=v+1 , 表达式的值: v+1之后的值
v++:等同 v=v+1 , 表达式的值: v+1之前的值
-- v :等同 v=v –1 , 表达式的值: v 1之后的值
v -- :等同 v=v –1 , 表达式的值: v-1之前的值?++、 --运算符的优先级
与单目+、-相同,高于所有二目运算符
?++、 --运算符的结合性
自右向左
例1:判断以下四组语句执行后变量d、b的值
int a, b, c, d;
(1) a=1, b=2, c=3 ;d=a+b++;
d←3, b←3
(2) a=1, b=2, c=3 ; d=a+(++b);
d←4, b←3
(3) a=1, b=2, c=3 ; d= --b+a;
d←2, b←1
(4) a=1, b=2, c=3 ; d= b-- +a;
d←3, b←1
例2:判断正误,若正确则计算b的值
int a,b;
(1) a=1,b=0; b = -a++;
正确,b←- 1 (++优先于-)
(2) a=1,b=0; b = (-a)++;
错误,-a非左值
(3) a=1,b=0; b = -++a;
正确,b←- 2 (++优先于-)
(4) a=1,b=0; b = ++-a;
错误,-a非左值
(5) a=1,b=0; b=++a++ ;
错误, a++非左值
?注意
(1) 避免++、--、+、–组合时的二义性理解。
a+++b
两种理解:(a++)+b 或 a+(++b)
编译系统采用第一种方式处理
a+--b
两种理解: a+(--b) 或 a+ -(- b)
编译系统采用第一种方式处理
4、包含单目sizeof 运算符的算术表达式
?一般形式: sizeof (e)
e: 类型说明符,表达式(可缺省圆括号)
例:int a;
sizeof (int) , sizeof (a) , sizeof a+1 ?运算功能:得到某一类型数据长度的信息。
?表达式的值: 存储e类型的数据时所占用的字节数。例:表达式表达式的值
sizeof(int) 2 或 4
sizeof(long) 4
sizeof(double) 8
sizeof(2.5) 8
四、赋值表达式
?特点
包含赋值运算符,有两个操作数。
?赋值运算符: =
复合赋值运算符: +=、– =、*=、/=、%= 、 <<=、>>=、&=、|=、^= 1、包含赋值运算符=的表达式
?一般形式: v = e
v: 左值表达式
e: 表达式
例:x=1
?运算功能:将e的值保存到v所引用的存储区。
?表达式的值:赋给v的值
例:
已知int x=1, y=2, z; 判断正误。
z=x+y , x+y=z , y=sin(x) , sin(x)=y
正确,错误,正确,错误
?赋值运算符优先级:低于所有算术运算符
?赋值运算符结合性:自右向左
例1 :
int a,b,c,d=1; 表达式a = b = c = d+5的值?
c=d+5的值:6
b=c=d+5的值:6
a=b=c=d+5的值:6
例2 :
int a,b,c,d; 判断以下表达式的正误。
a=b=4+c=6 ,a=b=4+(c=6) , a=(b=4)=(c=6)
错误(4+c非左值),正确,错误(b=4非左值)
2、包含复合赋值运算符的表达式
?表达式一般形式: v op= e
op: 二目算术运算符或位运算符
+=、– =、*=、/=、%=:算术运算+ 赋值
<<=、>>=、&=、|=、^=:位运算 + 赋值
v:左值
e: 表达式
例如: x+=1
?运算功能: v = v op e
?表达式的值:赋给v的值
例1:
int x=1, y=2, z=3;
x+=1 等同 x = x+1 等同 x++ 或 ++x
y – = z+5 等同 y = y –(z+5)
不等同 y = y – z+5
z /=x – 1 等同 z = z /(x – 1)
不等同 z = z /x – 1
例2:
int a=2;
计算表达式 a += a – = a*a 后,a的值= ?
a = a +( a = a – ( a*a ) )
a ←– 4
?赋值运算语法限制
对于v = e 或 v op= e, e的数据类型与v的数据类型必须赋值兼容。
赋值兼容:
v、e: 均为基本类型
类型不相同时系统自动将e值的类型转换为v的类型后再赋值给v存储。
例:int a=1; double b=1.5;
a=b; int ←double a ← 1
b=a; double ← int b ← 1.0
赋值不兼容的几种常见情况:
(1) v、e中一个是基本类型,另一个是指针类型
例:int a,b,*p;
a=&b; (错) a = “a”; (错) p=a; (错)
Warning : Non-portable pointer assignment in function main
(2) v、e中一个是基本类型,另一个是构造类型
(3) v、e中一个是指针类型,另一个是构造类型
五、类型转换表达式
?特点
包含类型转换运算符,有1个操作数。
?一般形式:(类型说明符)e
(类型说明符):类型转换运算符
e : 表达式
例: (int) x (正确), int(x) (错)
?运算功能
将e值的类型转换为指定类型的数据后保存,不改变e自身的数据类型。?表达式的值:将e 转为指定类型后的值。
?类型转换运算符优先级
高于所有二目、三目运算符
?类型转换运算符结合性
自右向左
例1:
float x=1,y=2; int z=3;
(int)x % (int)y x, y自身仍是float型
(int)(x+y) 区别 (int)x+y
(float)1/z
例2:
float x=1.5, y;
y=(float)(int)x ; y ← ?
y ← 1.0
六、逗号表达式
?特点
包含逗号运算符“,”,有2个操作数。
?一般形式: e1,e2
e1 、e2: 表达式
例:x=1, y=x+1
?运算功能: 自左向右依次计算e1和e2的值
?表达式的值: e2的值
?逗号运算符优先级:最低
?逗号运算符结合性:自左向右
例:
int a=1,b=2,c=3;
a=5+5, b=b*b+c a ←?
a ← 10
a=(5+5, b=b*b+c) a ←?
a ←7
区别以下两段程序的不同:
?第一段程序:if ( y>1)x = y+2, y++ ;
?第二段程序:if ( y>1) x = y+2 ;y++ ;
七、函数调用表达式
?一般形式:函数名(实参表)
例: y = sqrt (4)
?表达式的值:被调用函数返回的值
?数学库函数的原型(函数声明)
例:double sqrt(double x);
double pow(double x , double y);
包含函数原型的必要性:
调用库函数时若实参类型与对应的形参变量类型不一致但“形参变量←实参”赋值兼容时,系统自动将实参类型转为对应的形参变量类型。
?数学库函数的调用
实参应为基本类型(算术型)。
例:double y; float x=4.0;
y=sqrt(4); y=sqrt(x); y=sqrt( x+1);
?调用数学库函数注意事项
(1) 实参允许的取值范围(域Domain)
acos(x) x 在[-1,1]
asin(x) x在[-1,1]
log(x) x ≥ 0
sqrt(x) x ≥ 0
pow(x,y) x<0时y 取整数,x=0时y>0
?abs( ) 与fabs( )的区别
abs( ):计算并返回整数的绝对值
fabs( ) :计算并返回浮点数的绝对值
八、浮点数的舍入误差
?舍入误差
浮点数在存储和计算时,当数据的位数大于所能表示的有效位时所产生的误差。随着计算步骤的增加,舍入误差会不断累积。例:
#include
main()
{ double a=1000000000000000.5;(15个0)
double b=10000000000000000.5 ;(16个0)
printf(“a=%f\nb=%f”,a,b);
}
输出:a=1000000000000000.500000
b=10000000000000000.000000
原因: double型数据的二进制形式有效数字位是有限制的
?涉及实型数的计算通常要给出对结果误差的要求
例:
对结果的误差要求<0.000001(即:允许十进制形式的实数小数部分的第6位存在误差)。
九、浮点数的运算溢出
?上溢
在表达式中出现浮点数时,当计算结果大于该浮点数类型所能表示的最大值时,出现上溢。例:
main( )
{ double big= 1.797693E308 ;
big *= 2 ;
printf( “%e ” , big) ;
}
运行时输出:Floating point error: Overflow.
原因:1.797693E308是double型的最大值(在values.h中可查到), 1.797693E308 ?2的运算结果出现上溢
main( )
{ double big;
big = 1.797693E308 *2 ;
printf( “%e ” , big) ;
}
运行时输出: +INF ( 无穷大infinity)
原因: 1.797693E308 ? 2的值大于double型的最大值,赋给big的是一个代表无穷大的值。
?下溢
在表达式中出现浮点数时,当计算结果小于该浮点数类型所能表示的最小值时,发生下溢。
例:
main( )
{ double small= 2.225074E-308;
small =small-1 ;
printf( "%e" , small) ;
}
运行时输出:-1.00000e+00
原因:2.225074E-308是double型的最小值(values.h)
2.225074E-308 -1 的结果值出现下溢
十、操作数的数据类型转换(conversion)
?操作数类型转换的两种方式
隐式转换:
无转换说明,编译系统根据转换规则自动转换
显式转换:
有转换说明,编译系统根据转换说明强制转换
?操作数类型转换的几种场合
表达式计算(隐式转换、显式转换)
赋值(隐式转换)
函数调用(隐式转换)
函数返回(隐式转换)
字符输入(显式转换)
字符输出(显式转换)
float f (int a, int b);
main()
{ float x,y;
int z,w;
scanf (“%f%f ”,&x,&y); 字符输入(显式转换)
z = f (x,y); 函数调用(隐式转换) ,赋值(隐式转换)
w=(int)x%(int)y; 表达式运算(显式转换)
printf (“%f ”,z); 字符输出(显式转换)
}
float f (int a, int b)
{ double c;
if (a>b) c = 1.0/a; 表达式运算(隐式转换)
else c = 1.0/b; 表达式运算(隐式转换)
return c; 函数返回(隐式转换)
}
(1) 表达式计算隐式转换
二目运算符(%、指针运算符除外)的两个操作数类型不一致时,其中一个操作数的类型将被自动转换。
转换规则:
char型和short int型操作数自动转为int型
float型操作数自动转为double型
其它情况:类型提升(低级类型→高级类型)。
数据类型优先级:
int → unsigned int → long int → double
例:
已知 char c; int x; long xx; float y; double z;
表达式 x + xx * z
int + long→double * double
int → double + double
运算结果类型: double
表达式 xx * c + y
Contest - 2011级C语言课程大作业 Start Time: 2012-02-19 16:25:00 End Time: 2012-03-01 22:00:00 Current Time: 2012-2-23 15:51:18 Status:Running Public
写在最前: 本文档中的题目;在不不同的编译器中可能会有提示错误,呵呵,小小的动动手改下变量的定义就可以运行了……………….. 由于能力不足..有题目未解决的…或者有错误的我会…认真听取大家的..意见的…. 呵呵……..有一两个….偷了下懒哦……… 提供原题目还有本人自己的解答的源代码。感谢大家的。。。。建议……………. 问题A: 趣味程序设计_狼追兔子 时间限制: 1 Sec 内存限制: 128 MB 提交: 341 解决: 63 [提交][状态][讨论版] 题目描述 一只兔子躲进了n个环形分布的洞的某一个中。狼在第一个洞没有找到兔子,就隔一个洞,到第三个洞去找;也没有找到,就隔两个洞,到第六个洞去找。以后每次多一个洞去找兔子……这样下去,如果一直找不到兔子,请问兔子可能在哪个洞中? 输入 有多组测试数据,读取到文件结尾符为止。每组测试数据输入n(2≤n≤100),即洞穴个数。输入到文件结尾符为止。 输出 兔子可能藏匿的洞。如果不止一个,按从小到大的顺序输出。如果不存在,输出空行。
样例输入 10 8 15 样例输出 2 4 7 9 2 4 5 7 8 9 11 12 14 提示 用一个数组a[10],对应的元素a[0],a[1],a[2]……a[9]对应表示10个洞,初值均置1。通过一个循环用“穷举法”找兔子,第n次查找对应第(n-1)%10个洞,如果在第(n-1)%10个洞中没有找到兔子,因此将数组元素a[(n-1)%10]置0值。循环完成后,检查a数组各元素(各个洞)的值,若其值仍为1,则兔子可能藏身该洞中。 #include
1、编程序求5X+2Y+Z=50 的所有非负整数解。 #include
猴子吃桃 1、题目:猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少。 1.程序分析:采取逆向思维的方法,从后往前推断。 2.程序源代码: main() { int day,x1,x2; day=9; x2=1; while(day>0) {x1=(x2+1)*2;/*第一天的桃子数是第2天桃子数加1后的2倍*/ x2=x1; day--; } printf("the total is %d\n",x1); } 回文数问题 题目:给一个不多于5位的正整数,要求:一、求它是几位数,二、逆序打印出各位数字。 1. 程序分析:学会分解出每一位数,如下解释:(这里是一种简单的算法) 2.程序源代码: main( ) { long a,b,c,d,e,x; scanf("%ld",&x); a=x/10000;/*分解出万位*/ b=x%10000/1000;/*分解出千位*/ c=x%1000/100;/*分解出百位*/ d=x%100/10;/*分解出十位*/ e=x%10;/*分解出个位*/ if (a!=0) printf("there are 5, %ld %ld %ld %ld %ld\n",e,d,c,b,a); else if (b!=0) printf("there are 4, %ld %ld %ld %ld\n",e,d,c,b); else if (c!=0) printf(" there are 3,%ld %ld %ld\n",e,d,c); else if (d!=0) printf("there are 2, %ld %ld\n",e,d); else if (e!=0) printf(" there are 1,%ld\n",e); } 杨辉三角 题目:打印出杨辉三角形(要求打印出10行如下图) 1.程序分析: 1 1 1
C-C++语言趣味程序设计编程百例精解() ?81.角谷猜想 日本一位中学生发现一个奇妙的“定理”,请角谷教授证明,而教授无能为力,于是产生角谷猜想。猜想的内容是:任给一个自然数,若为偶数除以2,若为奇数则乘3加1,得到一个新的自然数后按照上面的法则继续演算,若干次后得到的结果必然为1。请编程验证。 *问题分析与算法设计 本题是一个沿未获得一般证明的猜想,但屡试不爽,可以用程序验证。题目中给出的处理过程很清楚,算法不需特殊设计,可按照题目的叙述直接进行证。 *程序说明与注释 #include<stdio.h> int main() { int n,count=0; printf("Please enter number:"); scanf("%d",&n); /*输入任一整数*/ do{ if(n%2)
n=n*3+1; /*若为奇数,n乘3加1*/ printf("[%d]:%d*3+1=%d\n",++count,(n-1)/3,n); } else { n/=2; /*若为偶数n除以2*/ printf("[%d]: %d/2=%d\n",++count,2*n,n); } }while(n!=1); /*n不等于1则继续以上过程*/ } 82.四方定理 数论中著名的“四方定理”讲的是:所有自然数至多只要用四个数的平方和就可以表示。 请编程证此定理。 *问题分析与算法设计 本题是一个定理,我们不去证明它而是编程序验证。 对四个变量采用试探的方法进行计算,满足要求时输出计算结果。 *程序说明与注释 #include<stdio.h> #include<stdlib.h> int main()
一、单项选择题(每小题2分,共50分) 1、一个C程序的执行是从___A__。 A、本程序的main函数开始,到main函数结束 B、本程序的main函数开始,到本程序文件的最后一个函数结束 C、本程序文件的第一个函数开始,到本程序文件的最后一个函数结束 D、本程序文件的第一个函数开始,到本程序main函数结束 2、C语言程序的基本单位是___C___。 A、程序行 B、语句 C、函数 D、字符 3、请选出可用作C语言用户标识符的一组标识符___B___。 A、void B、a3_b3 C、For D、2a define_123-abcDO WORDIFasesizeof 4、假定x和y为double型,则表达式(x=2,y=x+5/2)的值是__C__。 A、、4 C、、 5、下列可以正确表示字符型常量的是___D__。 A、297 B、"a" C、"\n" D、'\t' 6、在C语言中,要求运算数必须是整型的运算符是__D__。 A、/ B、++ C、*= D、% 7、C语言中,复合语句的构成是将一系列语句置于__C__。 A、begin与end之间 B、方框号“[]”之间 C、花括号“{}”之间 D、圆括号“()”之间 8、有如下程序段,对应正确的数据输入是___A___。 floatx,y; scanf(”%f%f”,&x,&y); printf(”a=%f,b=%f”,x,y); A、<回车> B、,<回车> <回车> C、A=,B=<回车> D、回车> 9、以下程序段的输出结果是___D__。 inta=5678; printf(”%2d\n”,a); A、提示出错、无结果 B、56 C、78 D、5678 10、已知:charch='A';则下列表达式的值是__B__。 ch=(ch>='A'&&ch<='Z')?(ch+32):ch; A、A B、a C、Z D、z
趣味 c 语言编程100 例 【程序 1】 题目:有 1、2、3、4 个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 1.程序分析:可填在百位、十位、个位的数字都是1、 2、3、4。组成所有的排列后再去 掉不满足条件的排列。 2.程序源代码: main() { int i,j,k; printf("\n"); for(i=1;i<5;i++) / *以下为三重循环 */ for( j=1;j<5;j++) for (k=1;k<5;k++) { if (i!=k&&i!=j&&j!=k) /* 确保 i 、 j、 k 三位互不相同 */ printf("%d,%d,%d\n",i,j,k); } } 程序 2】 题目:企业发放的奖金根据利润提成。利润 (I) 低于或等于 10 万元时,奖金可提 10% ;利润高于 10 万元,低于 20 万元时,低于 10 万元的部分按 10% 提成,高于 10 万元的部分,可可提成 7.5% ; 20 万到 40 万之间时,高于 20 万元的部分,可提成 5% ; 40 万到 60 万之间时高于
40 万元的部分,可提成 3% ;60 万到 100 万之间时,高于 60 万元的部分,可提成 1.5% ,高于 100万元时,超过100万元的部分按1%提成,从键盘输入当月利润I,求应发放奖金总 数? 1. 程序分析:请利用数轴来分界,定位。注意定义时需把奖金定义成长整型。 2. 程序源代码: main() { long int i; int bonus1,bonus2,bonus4,bonus6,bonus10,bonus; scanf("%ld",&i); bonus1=100000*0.1;bonus2=bonus1+100000*0.75; bonus4=bonus2+200000*0.5; bonus6=bonus4+200000*0.3; bonus10=bonus6+400000*0.15; if(i<=100000) bonus=i*0.1; else if(i<=200000) bonus=bonus1+(i-100000)*0.075; else if(i<=400000) bonus=bonus2+(i-200000)*0.05; else if(i<=600000) bonus=bonus4+(i-400000)*0.03;
第七章函数 第一节软件的分层模块化 一、分层模块化主要思想 1、按功能将程序划分若干独立模块,模块之间具有层次关系,上层模块可调用下层模块。例: 一个简单学籍管理程序,经过需求调查和分析后,设计出如下模块结构: 2、对于模块的基本要求 ?每个模块功能单一。用三种基本结构构造模块内的程序代码段。 ?每个模块有名字 ?每个模块的接口参数应尽量简单 ?模块之间尽可能互相隔离(没有数据依赖性) ?除主模块由操作系统调用外,其它模块的调用一般应遵守:上级模块调用下级模块 3、模块化程序的开发 逐个模块进行设计、编码和调试 开发团队分工合作 4、c语言实现模块结构程序的支持机制(函数) 函数定义——模块 函数名——模块名 函数的形式参数——模块接口 函数调用——模块调用 第二节 C 语言函数简介 一、函数分类 1、根据定义分类 ?系统预定义函数(库函数) 不需用户定义,可多次调用 ?用户自定义函数 需要用户一次定义,可多次调用 2、根据参数分类 ?无参函数 定义和调用时均不带参数 ?有参函数 定义和调用时带一个以上的参数 3、根据返回值分类 ?有返回值函数 函数调用结束时带值返回到主调函数 ?无返回值函数
函数调用结束时不带任何值返回到主调函数 二、函数一般特性 1、函数的定义 在一个源程序中: 必须有一个也只能有一个main函数定义(函数名是规定的,函数体是自定义的)。 可以有多个相互独立的其它函数定义。 在一个函数定义的函数体中不允许出现另一个函数定义(嵌套定义)。 2、函数的调用 发出运行程序命令后操作系统调用执行main函数。在一个函数定义的函数体中可以调用另一个函数(嵌套调用),也可以调用函数自身(直接递归调用)。main函数也可以被其它函数调用(间接递归调用),但一般不这样做。 3、函数的返回 一个函数被调用后,一旦执行到return语句或函数体的最后一个“}”时,自动返回到主调函数处继续执行后续指令。函数返回时可以带值或不带值。 第三节函数的定义、调用和声明 一、函数定义(function definition) 1、函数定义格式 [存储类型] [函数类型] 函数名([const] [存储类型] 数据类型形参变量名1, . . .) { 变量声明序列 语句序列 } 下划线部分为形式参数表 特殊情况: 无参函数:形式参数表中只放一个void,或者为空 无返回值函数:函数类型为void 缺省情况: 函数类型缺省时为int,形参缺省时为void 2、函数类型 代表函数返回值类型。 允许:5种基本类型,指针类型,构造类型,void(无值) 3、形式参数(formal argument) ?所有形式参数都是变量,简称形参变量 ?形参变量的类型可以是:5种基本类型、指针类型、构造类型(结构,联合) ?函数体内不能再声明与形参变量同名的其他局部变量 ?形参变量的作用域为所在函数的函数体 ?形参变量只有在所在函数被调用期间才存在
湖北省计算机二级C 语言考试
1、计算机在实现工业自动化中的应用主要是进行(A) A、实时控制 B、数据处理 C、数值计算 D、人工智能 2、计算机的主频指的是(D) A、硬盘读写速度,用Hz表示 B、软盘读写速度,用Hz表示 C、显示器输出速度,用MHz表示 D、时钟频率,用MHz表示 3、复制活动窗口的信息到剪贴版,只需按下(C)键即可 A、[Alt+Esc] B、[Ctrl+Shift] C、[Alt+Print Screen] D、[Print Screen] 4、计算机中ROM的意思是(B) A、磁盘存储器 B、只读存储器 C、随机存储器 D、光盘存储器 5、在运行某程序时,如果存储器容量不够,可通过(D)来解决。 A、把软盘换成硬盘 B、把磁盘换成高密度磁盘 C、扩大硬盘容量 D、增加一个扩充存储卡(内存条) 6、在Windows,控制面板是以(B)的形式存在的 A、一个普通文件 B、一个系统文件夹 C、一个系统文件 D、几个系统文件集合在一起 7、微型计算机存储器系统中的Cache是(B) A、只读存储器 B、高速缓冲存储器 C、可编程只读存储器 D、可檫除可再编程只读存储器 8、一般主存储器和外存储器的区别在于(C) A、主存储器容量大,速度快,造价高;外存储器容量小,速度慢,造价低 B、主存储器容量小,速度慢,造价低;外存储器容量大,速度快,造价高 C、主存储器容量小,速度快,造价高;外存储器容量大,速度慢,造价低 D、区别仅仅是因为一个在计算机里,一个在计算机外 9、在智能ABC输入法中,将“计算机”编码输入为“jsuanj”,这属于(C) A、全拼输入 B、简拼输入 C、混拼输入 D、智能输入 10、在Windows 98的MS-DOS窗口中,按(B)键,可以在全屏幕与窗口方式之间切换。 A、[Alt+Shift] B、[Alt+Enter] C、[Alt+F8] D、[Ctrl+Shift] 11、二进制数1010100.100对应的十六进制数为(C) A、52.8 B、52.6 C、54.8 D、54.6 12、在3.5英寸软盘上有一个可移动滑块的透光孔是用于(B) A、防霉保护 B、写保护 C、读保护 D、驱动定位 13、在Windows 98中,不同驱动器之间的文件移动,应使用的操作为(C)
狼追兔子 1 巧夺偶数 2 五猴分桃 3 高次方数 4 借书方案 5 过桥问题 6 数制转换7 打渔晒网8 喝酒问题9 哥德巴赫猜想10 打印日历11 抓交通肇事逃逸犯12 反序数13 新郎新娘14 称重砝码15 求车速16 谁是窃贼17 出售金鱼18 百钱百鸡19 谜语博士20 猜牌术(-)21 舍罕王的失算22 怎样存钱利最大23 猜牌术(二)24 爱因斯坦的数学题25 取火柴游戏26 平分鱼和筐27 可逆素数28 三色球问题29 抢n游戏30 问题A: 趣味程序设计_狼追兔子 时间限制: 1 Sec 内存限制: 128 MB 提交: 341 解决: 63 [提交][状态][讨论版] 题目描述 一只兔子躲进了n个环形分布的洞的某一个中。狼在第一个洞没有找到兔子,就隔一个洞,到第三个洞去找;也没有找到,就隔两个洞,到第六个洞去找。以后每次多一个洞去找兔子……这样下去,如果一直找不到兔子,请问兔子可能在哪个洞中? 输入 有多组测试数据,读取到文件结尾符为止。每组测试数据输入n(2≤n≤100),即洞穴个数。输入到文件结尾符为止。 输出 兔子可能藏匿的洞。如果不止一个,按从小到大的顺序输出。如果不存在,输出空行。 样例输入 10 8 15
样例输出 2 4 7 9 2 4 5 7 8 9 11 12 14 提示 用一个数组a[10],对应的元素a[0],a[1],a[2]……a[9]对应表示10个洞,初值均置1。通过一个循环用“穷举法”找兔子,第n次查找对应第(n-1)%10个洞,如果在第(n-1)%10个洞中没有找到兔子,因此将数组元素a[(n-1)%10]置0值。循环完成后,检查a数组各元素(各个洞)的值,若其值仍为1,则兔子可能藏身该洞中。 #include
第一章 C语言概述 本章要求: (1)C语句概述; (2)程序的三种基本结构; (3)赋值语句; (4)数据的输入与输出。 教学重点: 1.C语言的特点。 2.C语言的编程环境。 教学难点: 掌握编程环境的使用方法 教学方法: 采用多媒体教学的方法进行讲授,学生在教师指导下通过计算机进行操作练习。 课时数:4(讲授2节课,上机练习2节课) 1.1C语言的发展及特点 C语言的发展过程 1、C语言是国际上流行的、很有发展前途的计算机高级语言。C语言适合于作为“系统描述语言”。它既可以用来编写系统软件,也可以用来编写应用程序。 以前操作系统等系统软件主要采用汇编语言编写。汇编语言依赖于计算机硬件,程序的可读性、可移植性都比较差。为了提高可读性和可移植性,人们希望采用高级语言编写这些软件,但是一般的高级语言难以实现汇编语言的某些操作,特别是针对硬件的一些操作(如:内存地址的读写-直接硬
件、二进制位的操作)。人们设法寻找一种既具有一般高级语言特性,又具有低级语言特性的语言,C语言就在这种情况下应运而生。 2、C语言的发展见下图: ALGOL60 -> CPL -> BCPC -> B -> C -> 标准 C -> ANSI C -> ISO C ALGOL60:一种面向问题的高级语言。ALGOL60离硬件较远,不 适合编写系统程序。 CPL(Combined Programming language,组合编程语言):CPL 是一种在ALGOL60基础上更接近硬件的一种语言。CPL规模大, 实现困难。 BCPL(Basic Combined Programming language,基本的组合编 程语言):BCPL是对CPL进行简化后的一种语言。 B语言:是对BCPL进一步简化所得到的一种很简单接近硬件的 语言。B语言取BCPL语言的第一个字母。B语言精练、接近硬 注:最初Unix操作系统是采用汇编语言编写的,B语言版本的Unix是第一个用高级语言编写的Unix。在C语言诞生后,Unix很快用C语言改写,C语言良好的可移植性很快使Unix从PDP计算机移植到其它计算机平台,随着Unix的广泛应用,C语言也得到推广。从此C语言和Unix像一对孪生兄弟,在发展中相辅相成,Unix和C很快风靡全球。 3、从C语言的发展历史可以看出,C语言是一种既具有一般高级语言特性(ALGOL60带来的高级语言特性),又具有低级语言特性(BCPL带来的接近硬件的低级语言特性)的程序设计语言。C语言从一开始就是用于编写大型、
C/C++语言经典、实用、趣味程序设计编程百例精解(1) 1.绘制余弦曲线 在屏幕上用―*‖显示0~360度的余弦函数cos(x)曲线 *问题分析与算法设计 如果在程序中使用数组,这个问题十分简单。但若规定不能使用数组,问题就变得不容易了。关键在于余弦曲线在0~360度的区间内,一行中要显示两个点,而对一般的显示器来说,只能按行输出,即:输出第一行信息后,只能向下一行输出,不能再返回到上一行。为了获得本文要求的图形就必须在一行中一次输出两个―*‖。 为了同时得到余弦函数cos(x)图形在一行上的两个点,考虑利用cos(x)的左右对称性。将屏幕的行方向定义为x,列方向定义为y,则0~180度的图形与180~360度的图形是左右对称的,若定义图形的总宽度为62列,计算出x行0~180度时y点的坐标m,那么在同一行与之对称的180~360度的y点的坐标就应为62-m。程序中利用反余弦函数acos计算坐标(x,y) 的对应关系。 使用这种方法编出的程序短小精炼,体现了一定的技巧。 *程序说明与注释 #include 有趣的C语言笔试题 1.gets()函数 问:请找出下面代码里的问题: #include int main(void) { char buff[10]; memset(buff,0,sizeof(buff)); gets(buff); printf(" The buffer entered is[%s] ",buff); return 0; } 答:上面代码里的问题在于函数gets()的使用,这个函数从stdin接收一个字符串而不检查它所复制的缓存的容积,这可能会导致缓存溢出。这里推荐使用标准函数fgets()代替。 2.strcpy()函数 问:下面是一个简单的密码保护功能,你能在不知道密码的情况下将其破解吗? #include int main(int argc,char*argv[]) { int flag=0; char passwd[10]; memset(passwd,0,sizeof(passwd)); strcpy(passwd,argv[1]); if(0==strcmp("LinuxGeek",passwd)) { flag=1; } if(flag) { printf(" Password cracked "); } else { printf(" Incorrect passwd "); } return 0; } 答:破解上述加密的关键在于利用攻破strcpy()函数的漏洞。所以用户在向“passwd”缓存输入随机密码的时候并没有提前检查“passwd”的容量是否足够。所以,如果用户输入一个足够造成缓存溢出并且重写“flag”变量默认值所存在位置的内存的长“密码”,即使这个密码无法通过验证,flag验证位也变成了非零,也就可以获得被保护的数据了。例如: $./psswd aaaaaaaaaaaaa Password cracked 虽然上面的密码并不正确,但我们仍然可以通过缓存溢出绕开密码安全保护。 要避免这样的问题,建议使用strncpy()函数。 作者注:最近的编译器会在内部检测栈溢出的可能,所以这样往栈里存储变量很难出现栈溢出。在我的gcc里默认就是这样,所以我不得不使用编译命令‘-fno-stack-protector’来实现上述方案。 3.main()的返回类型 问:下面的代码能编译通过吗?如果能,它有什么潜在的问题吗? #include void main(void) { char*ptr=(char*)malloc(10); if(NULL==ptr) { 一、(01)在while(x)中的(x)与下面条件等价的是( D ) A) x==0 B)x==1 C) x!=1 D)x!=0(02)C语言中,运算对象必须是整型数的运算符是( A )A)%B)/ C)< D)! (03)以下选项中合法的用户标识符是( B ) A)long B)_2Test C)3Dmax D)A.dat (04)以下选项中属于C语言的数据类型的是( C ) A)复数型B)逻辑型 C)双精度型D)集合型(05)设x,y,z和k都是int型变量,则执行表达 式:x=(y=4,z=16,k=32)后,x的 值为(C ) A)4 B)16 C)32D)52 (06)设x、y、t均为int型变量,则执行语句:x=y=3;t=++x||++y; 后,y的值为( C ) A)不定值B)4 C)3D)1 (07)以下程序的输出结果是( C )main( ) { int a = 1,b = 2,m = 0,n = 0,k; k = (n = b>a) || (m = a (10)以下程序的输出结果是(小数点后只写一位) ( A ) main ( ) { double d ; float f ; long l ; int i ; i = f = l = d = 20 / 3 ; printf ( “%d %ld %f %f \n”, i , l , f , d );} A) 6 6 6.0 6.0 B) 6 6 6.7 6.7 C) 6 6 6.0 6.7 D) 6 6 6.7 6.0 (11)有以下程序,程序运行后的输出结果是( D ) main() 韩信点兵 在中国数学史上,广泛流传着一个“韩信点兵”的故事:韩信是汉高祖刘邦手下的大将,他英勇善战,智谋超群,为汉朝建立了卓越的功劳。据说韩信的数学水平也非常高超,他在点兵的时候,为了知道有多少兵,同时又能保住军事机密,便让士兵排队报数: 按从1至5报数,记下最末一个士兵报的数为1; 再按从1至6报数,记下最末一个士兵报的数为5; 再按从1至7报数,记下最末一个士兵报的数为4; 最后按从1至11报数,最末一个士兵报的数为10; 你知道韩信至少有多少兵?()z谁结婚呢? 魔术师的秘密 在一次晚会上,一位魔术师掏出一叠扑克牌,取出其中13张黑桃,预先洗好后,把牌面 朝下,对观众说:“我不看牌,只数一数就能知道每张牌是什么?”魔术师口中念一, 将第一张牌翻过来看正好是A;魔术师将黑桃A放到桌上,继续数手里的余牌,第二次数 1,2,将第一张牌放到这叠牌的下面,将第二张牌翻开,正好是黑桃2,也把它放在桌 子上。第三次数1,2,3,前面二张牌放到这叠牌的下面,取出第三张牌,正好是黑桃3, 这样依次将13张牌翻出,准确无误。现在的问题是,魔术师手中牌的原始顺序是怎样的? 约瑟夫问题 这是17世纪的法国数学家加斯帕在《数目的游戏问题》中讲的一个故事:15个教徒和15 个非教徒在深海上遇险,必须将一半的人投入海中,其余的人才能幸 免于难,于是想了一个办法:30个人围成一圆圈,从第一个人开始依次报数,每数到第九个人就将他扔入大海,如此循环进行直到仅余15个人为止.问怎样排法,才能使每次投入大海的都是非教徒. 求车速 一辆以固定速度行驶的汽车,司机在上午10点看到里程表上的读数是一个对称数(即这个数从左向右读和从右向左读是完全一样的),为95859.两小时后里程 表上出现了第二个新的对称数.问该车的速度是多少新的对称数是多少? 常胜将军 现有21根火柴,两人轮流取,每人每次可以取走1至4根,不可多取,也不能不取,谁取最后一根火柴谁输.请编写一个程序进行人机对弈,要求人先取,计算机后取;计算机一方为"常胜将军". 十进制转换成N进制(N=2 8 16 ) 定义一个方法Trans(int num, int regx) 实现将一个输入十进制数num转换成regx 进制 Eg: Trans(100, 16) 表示将 100 转成 16进制数输出 求100到1000之间有多少个其数字之和为5的整数. (答案:104,113,122,131,140,203,212,221,230,302,311,320,401,410,500) 打鱼还是晒网scanf(“%d%d%d”,&year ,&month,&day); 中国有句俗语叫"三天打鱼两天晒网".某人从1990年1月1日起开始"三天打鱼两天晒网",问这个人在以后的某一天中是"打鱼"还是"晒网". *思考题:请打印出任意年份的日历 *运行结果 Enter year/month/day:1991 10 25 第1章 C 程序概述 人与计算机交换信息是要用语言来交流的,这种语言称为计算机 语言。用计算机语言编写的代码称为程序。计算机的工作是受程 序控制的,而从计算机角度来说,程序是用某种计算机能理解并 执行的计算机语言来描述解决问题的方法步骤。 程序设计语言经历了从机器语言、汇编语言到高级语言这样一个 发展过程。 1.机器语言:计算机刚诞生时,还没有可以用来方便地指 挥计算机工作的程序,计算机程序是直接用它能识别的二进 制指令来书写的。这种程序设计语言就是机器语言。它直接 以计算机硬件产生作用的,所以不同型号的计算机的“机器 语言”又不一样,因此它被称为低级语言,很难被人掌握, 只有少数专业人员能使用。 2.汇编语言:实际上是一种符号化的机器语言。在汇编语 言中每条机器指令对应一个符号化的指令。如:用ADD代表 机器二进制的加法运算。因为加法用二进制的10110110的机 器语言代表,而用英文单词更简捷且好记多了。不过,用汇 编语言编写的程序要翻译成机器语言才能被计算机执行。且 也依赖于机器。 3.高级语言:由于汇编语言和机器语言都是面向机器的语 言,而且在程序的书写形式上很难直观地反映出程序设计者 的思路,因此人们发明了与人类的自然语言非常接近的高级 程序设计语言。高级语言不仅易学,易用,而且写出的程序 更加简练,同一个程序还可以用在不同型号的机器上。比如 说,我们要求两个数的和,在高级语言中可以用一个很简单 的语句C=A+B;来表示,但在汇编语言或者机器语言中,这 可能就是几条甚至几十条机器指令构成的一个实现加法的程 序,常人要读懂它也不是那么容易。 但是,用高级语言编写的程序不能被计算机直接理解和执行,而 必须先由这种语言的编译程序或者解释程序翻译成机器指令,然 后再让计算机执行机器指令。 C语言的历史 20世纪70年代初期出现的FORTRAN,ALGOL和PASCAL 语言是反映了结构化程序设计思想的高级语言,PASCAL它在 大学和研究所中流传较广曾为国内外计算机(应用)专业学生的 入门语言。 几乎同时与之诞生的C语言在美国的贝尔实验室中诞生,与 其它语言不同的是,C语言诞生之时,没有什么研究报告和语言 报告,而是在设计Unix操作系统时不断地得到更新和完善。因 此,人们把C语言程序称为程序员设计的语言,而把FORTRAN, ALGOL和PRASCAL语言称为计算机科学家设计的语言。 Unix的早期版本是用汇编语言写的,而用C编写的Unix原 先的版本更易于理解、修改的扩充,更重要的是,具有良好的可 移植性。作为一个优秀的操作系统,Unix在世界范围内得到了 C语言程序设计复习资料 一、选择题 下列各题ABCD四个选项中,只有一个选项是正确的,请将正确选项涂在答题卡的相应位置上,答在试卷上不得分。 1、不合法的整数是(B )。 A)0x35 B)43.6 C)0532 D)-346 2、下列合法的字符常量是(D )。 A)“f”B)x C)65 D)‘\Xab’ 3、设有整型变量x,单精度变量y=5.5,表达式x=float(y*3+((int)y%4))执行后,x的值为(A )。 A)17B)17.500000 C)17.5 D)1.5 4、在C语言中,负整数在内存中以( A )形式释放。 A)补码B)BCD码C)反码D)十进制数 5、在C语言中,要求参加运算的数必须是整数的运算符是(C )。 A)/ B)!C)%D)= = 6、(D)是C语言中非法的数据类型关键字。 A)float B)singed C)integer D)Char 7、现已定义整形变量int i=1;执行循环语句while(i++<5);后i的值为(b)。 A)1 B)5 C)6 D)以上三个答案都不正确 8、下列语句的输出结果是(D )。 printf(“%f\n”,(float)(2+4)/2); A)有语法错误不能通过编译B)3 C)3.0 D)3.000000 12、定义a为整型,下列表达式a=3>6的运行后,a的值为(A )。 A)0 B)1 C)3 D)表达式错误 13、如果a=1,b=2,c=3,d=4,则条件表达式a>b?a:c>d?c:d的值为(D )。 A)1 B)2 C)3 D)4 14、对于条件表达式(M)?(a++):(a--),其中的表达式M等价于(C )。 A)M= =0 B)M= =1 C)M!=0 D)M!=1 15、在x值处于-2到2,4到8时值为“真”,否则为“假”的表达式是(D )。 A)(2>x>-2)||(4>x>8) B)((x<=-2)||(x>=2)||((x>4)||(x>=8)) C)(x<2)&&(x>=-2)&&(x>4)&&(x<8) D)(x>-2)&&(x>4)||(x<8)&&(x<2) 16、已知字母a的ASC||的十进制代码为97,则执行下列语句后输出为(C )。 Char a=‘a’; a--; printf(“%d,%c\n”,a+‘2’-‘0’,a+‘3’-‘0’); A)a,c B)a—运算不合法,故有语法错误C)98,c D)格式描述和输出项不匹配,输出无定值 18、C语言中,逻辑“真”等价于(C )。 A)大于零的数B)大于零的整数C)非零的数D)非零的整数 19、下列语句中,符合语法的语句式(D )。 A)a+b=3 B)a=7 C)a=c+b+3=6; D)a=8,b=a+7; 20、若x为float型变量,则以列程序段结果是(B )。 x=1234.6789; c语言趣味程序 导读:就爱阅读网友为您分享以下“c语言趣味程序”的资讯,希望对您有所帮助,感谢您对https://www.docsj.com/doc/ca11179306.html,的支持! 每个数都是质数。完全可以采用穷举的方法对乘数和被乘数进行穷举,经过判断后找出答案。但是这种方法给人的感觉是“太笨了”,因为组成的数字只是质数(4个),完全没有必要在那么大的范围内进行穷举,只需要试探每一位数字为质数时的情况即可。采用五重循环的方法实现对于5个数字的穷举,前面的许多例题中都已见过。循环实现简单易行,但嵌套的层次太多,需要穷举的变量的数量直接影响到循环嵌套的层数,这种简单的实现方法缺少技巧性。本例的程序中给出了另外一种同样功能的算法,该算法的实现思想请阅读程序。程序中并没有直接对质数进行穷举,而是将每个质数与1到4顺序一一对应,在穷举时为处理简单仅对1到4进行穷举处理,待要判断产生的乘积是否满足条件时再利用一个数组完成向对应质数的转换。请体会程序中的处理方法。程序中使用的算法实际上是回朔法。*程序说明与注释#include<stdio.h>#define NUM 5 /*需要穷举的变量数 目*/#define C_NUM 4 /*每个变量的值的变化范围*/int a[NUM+1]; /*为需要穷举的变量开辟的数组*//*a[1]:被乘数的百位,a[2]:十位,aa[3]:个位a[4]:被乘数的十位a[5]:个位*/int b[]={0,2,3,5,7}; /*存放质数数字的数组,不使用第0号元素*/int f(long sum);int main(){int i,not_finish=1;i=2; /*i:将要进行处理的元素的指针下标。设置初始值*/a[1]=1; /*为第1号元素设置初始值*/while(not_finish) /*not_finish:程序运行没结束标记*/{while(not_finish&&i<=NUM)/*处理包括第i 个元素在内的后续元素,找出当前条件下的一种各个变量的一种可能的取值方法*/if(a>=C_NUM) /*当要处理的元素取超过规定的C_NUM时*/if(i==1&&a[1]==C_NUM)not_finish=0; /*若1号元素已经到C_NUM,则处理全部结束*/else a[i–]=0; /*将要处理的元素置0,下标-1(回退一个元素)*/else a[i++]++; /*当前元素值加1后下标指针加1*/if(not_finish){long int sum1,sum2,sum3,sum4; /*定义临时变量*/sum1=b[a[1>*100+b[a[2>*10+b[a[3>; /*计算被乘数*//*利用数组的下标与质数的对应关系完成序号1到4向质数的转换*/sum2=sum1*b[a[5>; /*计算乘数个位与被乘数的部分积*/sum3=sum1*b[a[4>; /*计算乘数十位与被乘数的部分积 C语言迭代法详细讲 解 迭代法 迭代法也称辗转法,是一种不断用变量的旧值递推新值的过程,跟迭代法相对应的是直接法(或者称为一次解法),即一次性解决问题。迭代法又分为精确迭代和近似迭代。“二分法”和“牛顿迭代法”属于近似迭代法。 迭代算法是用计算机解决问题的一种基本方法。它利用计算机运算速度快、适合做重复性操作的特点,让计算机对一组指令(或一定步骤)进行重复执行,在每次执行这组指令(或这些步骤)时,都从变量的原值推出它的一个新值。 利用迭代算法解决问题,需要做好以下三个方面的工作: 一、确定迭代变量。在可以用迭代算法解决的问题中,至少存在一个直接或间接地不断由旧值递推出新值的变量,这个变量就是迭代变量。 二、建立迭代关系式。所谓迭代关系式,指如何从变量的前一个值推出其下一个值的公式(或关系)。迭代关系式的建立是解决迭代问题的关键,通常可以使用递推或倒推的方法来完成。 三、对迭代过程进行控制。在什么时候结束迭代过程?这是编写迭代程序必须考虑的问题。不能让迭代过程无休止地重复执行下去。迭代过程的控制通常可分为两种情况:一种是所需的迭代次数是个确定的值,可以计算出来;另一种是所需的迭代次数无法确定。对于前一种情况,可以构建一个固定次数的循环来实现对迭代过程的控制;对于后一种情况,需要进一步分析出用来结束迭代过程的条件。 例 1 :一个饲养场引进一只刚出生的新品种兔子,这种兔子从出生的下一个月开始,每月新生一只兔子,新生的兔子也如此繁殖。如果所有的兔子都不死去,问到第 12 个月时,该饲养场共有兔子多少只? 分析:这是一个典型的递推问题。我们不妨假设第 1 个月时兔子的只数为 u 1 ,第 2 个月时兔子的只数为 u 2 ,第 3 个月时兔子的只数为 u 3,……根据题意,“这种兔子从出生的下一个月开始,每月新生一只兔子”,则有 u 1 = 1 , u 2 = u 1 + u 1 × 1 = 2 , u 3 = u 2 + u 2 × 1 = 4,…… 根据这个规律,可以归纳出下面的递推公式: u n = u n -1 × 2 (n ≥ 2) 对应 u n 和 u n - 1 ,定义两个迭代变量 y 和 x ,可将上面的递推公式转换成如下迭代关系: y=x*2 x=y 让计算机对这个迭代关系重复执行 11 次,就可以算出第 12 个月时的兔子数。参考程序如下: cls x=1 for i=2 to 12 y=x*2 x=y next i print y end有趣的C语言笔试题
c语言复习题讲课讲稿
趣味C语言题
C语言讲稿
C语言程序设计复习资料讲课讲稿
c语言趣味程序
C语言迭代法详细讲解讲课讲稿