C_Primer_Plus05.Operators

运算符,表达式,语句

  • 要点

while, typedef
=, -, *, /, %, ++, --, (类型名), sizeof
各种运算符
运算符优先级,语句和表达式
while 循环
复合语句、自动类型转换和强制类型转换
编写带参数的函数

基本运算符

+, -, *, /, %, ++, --, pow()

  • 数据对象
    • 赋值表达式执行时,会把值存储到内存位置上,用于存储值的数据区域统称为 数据对象(data object)
    • 数组的元素,结构的成员,指针表达式
  • 左值(lvalue)
    • 指定一个对象,引用内存中的地址
      • const (初始化除外)
    • 可用在赋值运算符的左侧
      • 可修改的左值(对象定位值, object locator value)

其他运算符

sizeof 运算符和 size_t 类型

sizeof-(负号) 都是一元运算符

#include <stdio.h>

int main(void){
    int n = 0;
    size_t size;

    size = sizeof(n);
    printf("n:%d, sizeof(n):%zd, all ints have %zd bytes.\n", n, size, sizeof(int));

    return 0;
}

output:

n:0, sizeof(n):4, all ints have 4 bytes.

sizeof 返回 size_t 类型的值,它是一个无符号整数类型,但它不是新类型。C 有一个 typedef 机制,允许对类型起别名,C 头文件系统可以使用 typedef 把 size_t 作为 unsigned int 或 unsigned long 的别名。size_t 类型可以用 %zd 转换符打印(C99),如果系统不支持,可用 %u 或 %lu 代替。

typedef unsigned long size_t;

关于 ++

n = 0;
while (n < 20){
    printf("%10d %10d\n", n, n*n++);
}

n++++n 的区别是 n++ 先取值在自加,后者是先自加再取值。上面打印的语句可能在某些系统中打印异常。因为不同的编译器传递参数的顺序不一样,编译器可自行选择对函数中哪个参数求值,这样做提高了编译器的效率。所以,有些编译器会先计算 n*n++,再计算第二个参数 n。甚至有的编译器从右往左计算,先计算 n++,再计算 n*n++。以n=5为例,上述打印语句可能的执行结果有:

5 25
6 25
6 30

再比如:

num = 5;
ans = num/2 + 5*(1 + num++);

编译器不一定会从左往右执行,也有可能会从右往左执行。结果可能是:

32
33

还有一种情况也不确定:

n = 3;
y = n++ + n++;

在执行完后n的值增加2是确定的,但y值不一定。y可能的结果有:

7
6  # 先返回了 + 两侧的值,再对 n 进行两次自加

为避免以上问题,应遵循以下规则:

  • 如果一个变量出现在一个函数的多个参数中,不要对改变领使用递增或递减运算符
  • 如果一个变量多次出现在一个表达式中,不要对该变量使用递增或递减运算符

表达式和语句

类型转换

转换分为低位到高位和高位到低位。

低位到高位:
从高到低: 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。函数原型会覆盖自动升级(发生在函数传参时)。

高位到低位:
存在截断问题。

也可以使用强制类型转换运算符。

int a = (int)1.6;  // a=1

带参数的函数

  • 实参
    • (actual) argument
    • 函数调用时传递给函数的参数
  • 形参
    • (formal) parameter
    • 函数中传递进来的参数
#include <stdio.h>
void pound(int n);  // 函数原型声明

int main(void){
    int times = 5;
    char ch = '!';
    float f = 6.f;

    pound(times);
    pound(ch);
    pound(f);

    return 0;
}

void pound(int n){
    while (n-- > 0)
        printf("#");
    printf("\n");
}

output:

#####
#################################
######

在执行 pound(ch) 时,char(和 short 类型) 类型自动升级为 int 类型,即使缺少函数原型,C也会把 char 和 short 类型自动升级为 int 类型。
在执行 pound(f) 时,float 类型会被函数原型强制转换成 int 类型。如果没有定义函数原型,则 float 类型会转换为 double 类型,虽然程序不会报错,但输出内容不正确。在函数调用时显式调用强制转换也能解决这个问题: pound((int)f).但如果 f 值太大,超过 int,也会产生不正确的结果。


ex01:
Write a program that requests the user to enter a Fahrenheit temperature. The program should read the temperature as a type double number and pass it as an argument to a user-supplied function called Temperatures() . This function should calculate the Celsius equivalent and the Kelvin equivalent and display all three temperatures with a precision of two places to the right of the decimal. It should identify each value with the temperature scale it represents. Here is the formula for converting Fahrenheit to Celsius:

Celsius = 5.0 / 9.0 * (Fahrenheit - 32.0)

The Kelvin scale, commonly used in science, is a scale in which 0 represents absolute zero, the lower limit to possible temperatures. Here is the formula for converting Celsius to Kelvin:

Kelvin = Celsius + 273.16

The Temperatures() function should use const to create symbolic representations of the three constants that appear in the conversions. The main() function should use
a loop to allow the user to enter temperatures repeatedly, stopping when a q or other nonnumeric value is entered. Use the fact that scanf() returns the number of items read, so it will return 1 if it reads a number, but it won’t return 1 if the user enters q . The == operator tests for equality, so you can use it to compare the return value of scanf() with 1 .

#include <stdio.h>

void Temperature(float t);

int main(void){
    float ft;
    printf("Enter a Fahrenheit temperature:\n");
    scanf("%f", &ft);

    Temperature(ft);

    return 0;
}

void Temperature(float ft){
    float ct = 5./9.*(ft-32.);
    float kt = ct + 273.16;

    printf("Celsius temperature is %.3f.\n", ct);
    printf("Kelvin temperature is %.3f.\n", kt);
}

output:

Enter a Fahrenheit temperature:
67
Celsius temperature is 19.444.
Kelvin temperature is 292.604.
posted @ 2020-05-24 21:51  keep-minding  阅读(74)  评论(0)    收藏  举报