表达式和语句

本文介绍了C语言中的基本元素,包括表达式的概念和示例,如算术和比较表达式,以及语句的类型,如表达式语句、迭代语句。文章详细讨论了复合语句(块)的作用,以及在没有花括号的情况下如何影响代码执行。此外,还讲解了类型转换的规则,包括自动类型提升和强制类型转换。最后,文章提供了带参数函数的定义和调用示例,以及函数参数的类型匹配原则。
摘要由CSDN通过智能技术生成

表达式和语句

本文主要介绍一下内容

  • 语句和表达式的含义
  • 复合语句、自动类型转换和强制类型转换
  • 如何编写带有参数的函数

1. 表达式

表达式是由运算符和运算对象组成的(运算对象可以是常量、变量或者二者的组合)。一些表达式由子表达式组成(子表达式即较小的表达式)

//表达式:
-4+6
c=3+8
5 > 3
6+ (c==3+8)
//值
2
11
1
17

2. 语句

语句是c程序的基本构建快。一条语句相当于一条完整的计算机指令。在c中,大部分语句都以分号结尾

//--几种常见语句
#include <stdio.h>
int main (void) //计算前20个整数的和
{
    int count,sum; //声明
    count = 0;
    sum = 0; //表达式语句
    while (count++ < 20) // 表达式语句
    sum = sum +count; //迭代语句
    printf("sum = %d\n",sum); //表达式语句
    return 0; //跳转语句
}
sum = 210
  • 声明创建了名称和类型,并为其分配内存
  • while语句是一种迭代语句,有时也被称为结构化语句,因为它的结构比简单的赋值表达式语句复杂
  • c语言副作用是对数据对象或文件的修改
  • 序列点是程序执行的点,在该点上,所有的副作用都在进入下一步之前发生
  • 完整表达式就是指这个表达式不是另一个更大的表达式的子表达式
while (guests++<10)
printf("%d \n",guests);
/*
guest++<10是一个完整的表达式,因为它是while循环的测试条件,所以该表达式的结束就是一个序列点。因此保证在程序转至执行printf()之前的发生副作用(即,递增guests)。同时,使用后缀形式保证了guests在完成与10的比较后才进行递增
*/
y = (4+ x++)+(6+ x++);
/*
表达式4+ x++不是一个完整的表达式,所以c无法保证x在子表达式4+x++求值后立即递增x
完整表达式是整个赋值表达式,分号标记了序列点
所以c保证程序在执行下一条语句之前递增x两次
c并未指明是在对子表达式求值以后递增x,还是对所有表达式求值后在递增x

3. 复合语句

复合语句是用花括号括起来的一条或多条语句,复合语句也被称为块

//程序段1
index =0;
while(index++<10)
sam = 10*index +2;
printf("sam = %d\n",sam);
//程序段2
index = 0;
while(index++<10)
{
sam = 10*index +2;
printf("sam = %d\n",sam);

}
  • 程序段1,while循环中只有一条赋值表达式语句。没有花括号,while语句从while这行运行至下一个分号。循环结束后,printf()函数只会被调用一次
  • 程序段2,花括号确保两条语句都是while循环的一部分,每执行一次循环就调用一次printf()函数。根据while语句的结构,整个复合语句被视为一条语句

在这里插入图片描述

注:

  • 注意循环体中的缩进。缩进对编译器不起作用,编译器通过花括号和while循环的结构来识别和解释指令,这里缩进是为了看出程序是如何组织的
  • 使用缩进可以为读者指明程序的结构

4. 类型转换

一些基本的类型转换规则

  • 当类型转换出现在表达式时,无论unsigned 还是signed的char和short都会被自动转换成int,如果必要会被转换成unsigned int(如果 short与int的大小相同,unsigned short就会被自动转换成double。由于都是从较小类型转换成较大类型,所以这些转换被称为升级
  • 设计两种类型的运算,两个值会被分成两种类型的最高级别
  • 类型的级别从高至低依次是long double、double、float、unsigned long long、long long、 unsigned long 、long、unsigned int、int(例外的情况是,当long和int的大小相同时,unsigned int比long的级别高。子所以short和char类型没有列出,是因为它们已被升级到int或unsigned int
  • 在赋值表达式语句中,计算的最终结果会被转换成赋值变量的类型。这个过程可能会导致类型升级或降级。所谓降级是指把一种类型转换成更低级别的类型
  • 当做为函数参数传递时,char和short被转换成int 和float被转换成double

待赋值的值与目标类型不匹配时,规则

  • 目标类型是无符号整型,且待赋值是整数时,额外的位将被忽略
  • 如果目标类型是一个有符号的整型,且待赋的值是整数,结果因实现而异
  • 如果目标类型是一个整数,且待赋的值是浮点数,该行为是未定义的
//--自动转换类型
#include <stdio.h>
int main (void)
{
    char ch ;
    int i;
    float f1;

    f1=i =ch='C';  //第9行
    printf("ch = %c ,i =%d ,f1=%2.2f\n",ch ,i ,f1);  //第10行
    ch =ch+1;  //第11行
    i= f1+2*ch;  //第12行
    f1= 2.0*ch+i;  //第13行
    printf("ch =%c,i=%d,f1 = %2.2f\n",ch,i,f1);  //第14行
    ch= 1107;  //第15行
    printf("Now ch=%c\n",ch);  //第16行
    ch = 80.89;  //第17行
    printf("Now ch =%c\n",ch);  //第18行
    return 0;
}
ch = C ,i =67 ,f1=67.00
ch =D,i=203,f1 = 339.00
Now ch=S
Now ch =P 

4.1强制类型转换运算符

  • 应该避免主动类型转换,尤其是类型转换(有时候需要小心转换,自动转换都是自动进行的)
  • 有时需要进行精确的类型转换,或者在程序中使用类型转换的意图。这种情况要用到强制类型转换,即使某个量的前面放置用圆括号括起来的类型名,该类型名即是希望转换成的目标类型。圆括号和它括起来的类型名构成了强制类型转换运算符
mice = 1.6+1.7;
mice = int (1.6)+ int (1.7);

5. 带参数的函数

//--定义一个带一个参数的函数
#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)  //ANSI风格函数头
{                 //表明该函数接受一个int类型的参数
    while (n-->0)
    printf("#");
    printf("\n");
}
#####
#################################
######

如果函数不接受任何参数,函数头的圆括号中应该写上关键字void。由于该函数接受一个int类型的参数,所以圆括号中包括一个int类型变量n的声明。

声明参数就创建了被称为形式参数(简称形参)

我们称函数调用传递的值称为实际参数(实参)

原型既是函数的声明,描述了函数的返回值和参数

pound()函数的原型说明了两点

  • 该函数没有返回值(函数名前面有void关键字)
  • 该函数有一个int类型的参数
//--A useful program for runners
#include <stdio.h>
const int S_PER_M =60 ;//1分钟的秒数
const int S_PER_H =3600; //1小时的秒数
const double M_PER_K = 0.62137;  //1公里的英里数
int main (void)
{
    double distk,distim;//跑过的距离(分别以公里和英里为单位)
    double rate;//平均速度(以英里/小时为单位)
    int min,sec;
    int time ;
    double mtime;
    int mmin ,msec;
    printf("This program converts your time for a metric race\n ");
    printf("to a time for running a mile and to your average ");
    printf("speed in milesw per hour.\n ");
    printf("Please enter, in kilometers ,the distance run.");
    scanf("%lf",&distk);
    printf("Next enter the time in minutes and seconds.\n");
    printf("Begin by entering the minutes.\n");
    scanf("%d",&min);
    printf("Now enter the seconds.\n");
    scanf("5d",&sec);
    time = S_PER_M*min +sec;  //把时间转换成秒
    distim = M_PER_K*distk;  //把公里转换成英里
    rate = distim / time * S_PER_H ;  //英里/秒/*秒/小时=英里/小时
    mtime = (double)time /distim; //时间/距离=跑一英里所用时间
    mmin = (int) mtime /S_PER_H;  //求出分钟数
    msec = (int) mtime % S_PER_M;  //求出剩余的秒数
    printf("You ran %1.2f km (%1.2f miles ) in %d min ,%d sec.\n",distk ,distim ,min ,sec);
    printf("That pace corresponds to running a mile in %d min,",mmin);
    printf("%d sec.\nYour acerage speed was %1.2f mph.\n ",msec,rate);
    return 0;

}
This program converts your time for a metric race
 to a time for running a mile and to your average speed in milesw per hour.
 Please enter, in kilometers ,the distance run.
56
Next enter the time in minutes and seconds.
Begin by entering the minutes.
30
Now enter the seconds.
You ran 56.00 km (34.80 miles ) in 30 min ,0 sec.
That pace corresponds to running a mile in 0 min,51 sec.
Your acerage speed was 69.59 mph.

6. 小结:

  • 表达式由运算符和运算对象组成(每个表达式都有一个值,包括赋值表达式和比较表达式。运算符优先级规则决定了表达式中各项的求值顺序,但两个运算符共享一个运算对象时,先进性优先级高的运算。如果运算符的优先级相等,由结合律(从左往右,从右往左)决定求值顺序
  • 大部分语句都以分号结尾。最常用的语句是表达式语句。用花括号括起来一条或多条语句构成了复合语句(或称为块)。while语句是一种迭代语句,只要测试条件为真,就重复执行循环体中的语句
  • c语言中,许多类型转换都是自动进行的。
    • 当char和short出现在表达式里或作为函数的参数时,都会被升级为int类型
    • float类型在函数参数时,会被升级为double类型,在K&R C(不是ANSIC)下,表达式中的float也会被升级为double类型
    • 当把一种类型的值赋给另一种类型的变量时,值将会被转换成与变量的类型相同
    • 当把较大类型转换成较小类型时(如,long转换成short,或double转换成float),可能会丢失数据
      要测试条件为真,就重复执行循环体中的语句
  • c语言中,许多类型转换都是自动进行的。
    • 当char和short出现在表达式里或作为函数的参数时,都会被升级为int类型
    • float类型在函数参数时,会被升级为double类型,在K&R C(不是ANSIC)下,表达式中的float也会被升级为double类型
    • 当把一种类型的值赋给另一种类型的变量时,值将会被转换成与变量的类型相同
    • 当把较大类型转换成较小类型时(如,long转换成short,或double转换成float),可能会丢失数据
  • 定义一个带参数的函数时,便在函数定义中声明了一个变量(形式参数)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值