1 条
LOGO
Yutuo

在C语言或者C++中,Side effect(负效应)表示对变量文件进行更改,比如c#i = i + 1;c#i++;等。Sequence point(序列点)表示对该时间点而言,之前的处理必须要完全完成,比如c#func(func1(), func2())在调用func函数之前就是一个序列点,在这之前c#func1()c#func2()必须执行完成。下面来介绍C语言中的Sequence point(序列点)。

C语言中Sequence point(序列点)

1.函数调用之前

在函数调用之前是一个序列点,在这个序列点前,函数的参数必须先执行完。

比如:c#func(func1(), func2()),在调用func函数之前c#func1()c#func2()必须执行完成,至于c#func1()c#func2()这两个函数哪个先执行是不一定的。

2.条件运算符?:、逗号运算符、逻辑运算符

条件运算符?:的问号之前表达式执行完之后有一个序列点。
逗号运算符之前表达式执行完之后有一个序列点。
逻辑运算符的第一个值后有一个序列点。

比如 c#a > b ? func1() : func2();,在执行完c#a > b,再决定执行c#func1()或者c#func2()
比如 c#func1() && func2(),在执行完c#func1()后,再判断是否需要再执行c#func2()

3.一个完整的声明后

这个比较容易理解,比如c#int a[10], b[20];。在c#a[10]后是一个序列点,c#b[20]后是一个序列点。

4.一个完整的表达式后

这个是很明显的,比如 c#func1(); func2();c#func1();c#func2();是两个完整的表达式,c#func1()一定在c#func2()之前执行。

5.库函数完成后

这个本来不需要单独放出来的,不过有些库函数不是以函数形式定义的,而是以宏形式定义的。

Sequence point(序列点)和Side effect(负效应)对程序的影响

因为在同一个序列点类,负效应的执行顺序是不确定的,所在在写程序时一定要注意。

一般来说,要做运算时,不要对变量的值有两次或者两次以上的修改(负效应)操作。
在调用函数时,函数的参数里不要对同一个全局变量进行修改(负效应)操作。

比如:

int a = 0;
a = a++;

c#a = a++;里,对变量a有两次修改,把c#a++的结果0赋值给a,把a加1,哪一个先执行不知道,所以最后a可能是0,也可能是1。

再比如:

int ga = 0;

int func1() {
    ++ga;
    return ga;
}

int func2() {
    return ga;
}

int add(int a, int b) {
    return a + b;
}

int main() {
    int cnt = add(func1(), func2());
    printf("%d", cnt);
}

这里c#func1()c#func2()的执行顺序不确定,有可能结果是1或者2。

发表我的评论

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

网友最新评论(1)