这两个题有什么不一样?为什么一个是3,5,一个却是9,9?为什么一个一样,,一个不一样?
第一题中f()
函数里语句s = &k;
是让局部变量指针s
指向全局变量k
,它不会影响main()
函数中的m
,然后*s = k;
其实把k
的值赋给k
自己。因此m
和k
的值都没有变化。
第二题中,ptr
指向a
,然后*ptr = 8;
,即向a
赋值8。a = (*ptr)++;
等价于a=a++;
,这个语句的行为C及C++17之前的标准里是未定义的。因为表达式中,对a
自增的操作和对a
赋值的操作的先后顺序是不确定的,依赖编译器实现。上面代码在MSVC编译器得到结果是a=9
,但是在GCC/Clang编译上得到结果是a=8
。
C++17标准对赋值表达式加了一条规则,即表达式E1=E2
,E2
的计算一定在E1
计算之前完成,这样的话,表达式a=a++;
先计算a++
,a自增并返回a自增前的值,即a++
返回8,a
的值变成9;然后再进行赋值a=8
,最终结果是a
等于8.。当MSVC编译器打开c++17编译选项时,上面代码运行结果也是8,就和GCC/Clang一致了。
https://en.cppreference.com/w/cpp/language/eval_order
- In every simple assignment expression E1=E2 and every compound assignment expression E1@=E2, every value computation and side-effect of E2 is sequenced before every value computation and side effect of E1
哪里有问题了?f(&m)函数里的参数int s只是一个指向m的指针,s=&k后,s指向k了,然后s=k即k=k,结局是m和k都没变。
而ptr=&a,ptr指向a了,对ptr或a进行操作,同时影响ptr和a。
两者不同之处是,一个是对指针s操作修改了指向,另一个只是修改ptr所指的值。
第一个,形参不改变实参