1.1循环简介
#include <stdio.h>
#define ADJUST 7.31 //字符常量
int main()
{
const double SCALE = 0.333; //const变量
double shoe, foot;
printf("Shoe size (men's) foot length\n");
shoe = 3.0;
while (shoe < 18.5)
{
foot = SCALE * shoe + ADJUST;
printf("%10.1f %15.2f inches\n", shoe, foot);
shoe = shoe + 1.0;
}
printf("If the fits,wear it.\n");
return 0;
}
程序结果:
while循环,程序第一次到达while循环,检查括号中的条件是否为真,若条件为真,进入块中继续执行,当执行完块中最后一条语句,程序返回程序入口部分检查条件。若条件为假,跳出循环执行。花括号以及被花括号括起来的部分被称为块。
1.2基本运算符
1.2.1赋值运算符:=
a=111;
意思是,把111的值赋给a。=号左边是一个变量名,右边是赋给变量的值,读作:将值111赋给a。赋值行为从右往左进行。
语句i=i+1;在数学中无意义,在C中,意思是:找出变量i的值,把该值加1,然后把新值赋值给i。赋值运算符左侧必须引用一个存储位置,即:C使用可修改的左值标记那些可赋值的实体。
注:
数据对象:用于存储数据存储区域统称为数据对象。
左值:用于标识特定数据对象的名称或表达式。
对象指的是实际的数据存储,左值是用于标识或定位存储位置的标签。
可修改的左值:用于标识可修改的对象。
右值:能赋值给可修改左值的量,且本身不是左值。
1.2.2加法运算符:+
用于加法运算,使两侧的值相加。
例:printf("%d", 4 + 20);
1.2.3减法运算符:-
使左侧的数减去右侧的数。
+和-都是二元运算符。即:需要两个运算对象才能完成操作。
1.2.4符号运算符:-和+
是一元运算符,只需要一个操作对象,称为负和正。
1.2.5乘法除法运算符:*、/
整数除法的结果是整数,结果有小数的部分会被丢弃,这一过程被称为截断,不会进行四舍五入。
整数和浮点数相除,结果是浮点数。
1.2.6运算符优先级
优先级决定了求值的顺序
1.3其他运算符
1.3.1sizeof运算符和size_t类型
//sizeof.c --使用sizeof运算符
#include <stdio.h>
int main()
{
int n = 0;
size_t intsize;
intsize = sizeof (int);
printf("n=%d, n has %zd bytes; all ints have %zd bytes.\n", n, sizeof n, intsize);
return 0;
}
程序结果:
sizeof返回size_t类型的值,无符号整数类型,size_t是语言定义的标准类型。
C头文件系统可以使用typedef把size_t作为unsigned int或unsigned long别名。%zd显示size_t的值
1.3.2求模运算符:%
只能用于整数,不能用于浮点数。
第一个运算对象是负数,求模的结果为负数,第一个运算对象是正数,求模结果为正数。
1.3.3递增运算符:++
前缀模式:++a;后缀模式:a++
/*add_one.c --递增:前缀和后缀*/
#include <stdio.h>
int main()
{
int ultra = 0, super = 0;
while (super < 5)
{
super++;
++ultra;
printf("super = %d, ultra = %d \n", super, ultra);
}
return 0;
}
程序结果:
区别:a++:使用a值之后,递增a
++a:使用a的值之前,递增a
递减运算符和递增运算符类似。
规定:(1)如果一个变量出现在一个函数的多个参数中,不要对该变量使用递增或递减运算符。
(2)如果一个变量多次出现在一个表达式中,不要对该变量使用递增或递减运算符。
1.4表达式和语句
1.4.1表达式
由运算符和运算对象组成。最重要的一个特性是,每个表达式都有一个值。
1.4.2语句
是C程序的基本构建块,一条语句相当于一条完整的计算机指令,大部分以分号结尾。
声明创建了名称和类型,并为其分配内存位置。声明不是表达式语句,即去掉分号后不是一个表达式。
赋值表达式语句的结构是,一个变量名,后面一个赋值运算符,再跟着一个表达式,加个分号。
函数表达式语句会引起函数调用。while语句有三个部分:关键字;圆括号中的待测试条件;判断。
while语句是一种迭代语句,也叫结构化语句。
副作用和序列点
副作用是数据对象或文件的修改。
序列点是程序的点,在该点上,所有副作用都在进入下一步之前发生。
完整表达式是指这个表达式不是另一个更大表达式的子表达式。
1.4.3复合语句(块)
复合语句是用花括号括起来的一条或多条语句,复合语句也称为块。
1.5类型转换
1.当类型转换出现表达式时,无论时unsigned还是signed的char和short都会被自动转换成int。从较小类型转换成较大类型,所有这些转换被称为升级。
2.涉及两种类型的运算,两个值会被分别转换成两种类型的更高级别。
3.从高至低:long double、double、float、unsigned long long、long long、unsigned long、long、unsigned int、int
4.赋值表达式语句中,计算结果最终被转换成被赋值变量类型。降级是把一种类型转换成更低级别类型。
5.函数参数传递时,char和short被转换成int,float转换成double。
当待转换类型的值与目标类型不匹配时,规则:
1.目标类型时无符号整型,且待赋的值是整数时,额外的位被忽略。
2.如果目标类型时一个有符号整型,且待赋的值是整数,结果因实现而异。
3.如果目标类型时一个整型,且待赋的值是浮点数,行为是未定义的。
/*convert.c --自动类型转换*/
#include <stdio.h>
int main(void)
{
char ch;
int i;
float f1;
f1 = i = ch = 'C';
printf("ch = %c, i = %d, f1 = %2.2f\n", ch, i, f1);
ch += 1;
i = f1 + 2 * ch;
f1 = 2.0 * ch + i;
printf("ch = %c, i = %d, f1 = %2.2f\n", ch, i, f1);
ch = 1107;
printf("Now ch = %c\n", ch);
ch = 80.89;
printf("Now ch = %c\n", ch);
return 0;
}
程序结果:
1.5.1强制类型转换运算符
在某个量的前面放置用圆括号括起来的类型名,该类型名即是希望转换成目标类型。
圆括号和它括起来的类型名构成了强制类型转换运算符
通用形式:
(type)
用实际需要的类型替换type
1.6带参数的函数
/*pound.c --定义一个参数的函数*/
#include <stdio.h>
void pound(int n); //ANSI函数原型声明
int main(void)
{
int times = 5;
char ch = '!'; //ASCII码是33
float f = 6.0;
pound(times); //int类型的参数
pound(ch); //和pound((int)ch);相同
pound(f); //和pound((int)f);相同
return 0;
}
void pound(int n) //表明该函数接受一个int类型的参数
{
while (n-- > 0)
printf("#");
printf("\n");
}
程序结果:
声明参数就创建了形式参数。形式参数,简称形参,是变量;实际参数,简称实参,是函数调用提供的值,实参被赋给相应的形参。
变量名是函数私有的,即在函数中定义的变量名不会和别处的相同名称发生冲突。
原型即是函数的声明,描述了函数的返回值和参数,函数声明只指明了函数名和返回类型,没有指明参数类型。