++和 -
已知++(增量)和 - (减量)运算符通过鼓励过多的诡计来导致错误的代码.它们仅次于故障架构,可以实现病毒和其他安全威胁.有一个plusplus选项禁止使用这些运算符.
我知道像PHP这样的PHP结构$foo[$bar++]可能很容易导致一个错误,但是我无法找到一个更好的方法来控制循环而不是一个while( a < 10 ) do { /* foo */ a++; }或for (var i=0; i<10; i++) { /* foo */ }.
jslint是否突出显示它们是因为有些类似的语言缺少" ++"和" --"语法或者处理方式不同,还是有其他理由可以避免我可能会丢失的" ++"和" --"?
以下代码打印值为9.为什么?这里return(i++)将返回一个值11,由于--i该值应该是10本身,任何人都可以解释这是如何工作的?
#include<stdio.h>
main()
{
int i= fun(10);
printf("%d\n",--i);
}
int fun (int i)
{
return(i++);
}
Run Code Online (Sandbox Code Playgroud) 看看这些功能签名:
class Number {
public:
Number& operator++ (); // prefix ++
Number operator++ (int); // postfix ++
};
Run Code Online (Sandbox Code Playgroud)
前缀不带任何参数,但后缀确实如此.为什么?我认为我们可以用不同的返回类型识别它们.
c++ language-design operator-overloading prefix postfix-operator
今天,我偶然发现了一个谜语,这给我带来了新的惊喜。
我不认为下面的示例中的-1 [p]可以编译,但是可以。实际上,x最终为-3。
int x;
int array[] = {1, 2, 3};
int *p = &array[1];
x = -1[p]
Run Code Online (Sandbox Code Playgroud)
我在互联网上搜索了-1 [pointer]之类的东西,但找不到任何东西。好的,我承认很难输入正确的搜索查询。谁知道为什么-1 [p]编译而X变为-3?
可能重复:
_t(下划线-t)后面的类型代表什么?
在我的IDE(Xcode)中键入内容时,自动完成功能会弹出已定义的单词,当我在中途输入一些变量名称时.我偶尔会看到名字_t在他们的最后.
命名约定是什么,它意味着什么?
是否有参考文档来查找常用的修复前和修复后?
使用术语"postfix"进行搜索会给我很多关于同名邮件服务器的GoogleNoise.
我试图通过示例显示前缀增量比后缀增量更有效.
理论上这是有道理的:i ++需要能够返回未增加的原始值并因此存储它,而++我可以返回增量值而不存储先前的值.
但是有一个很好的例子可以在实践中证明这一点吗?
我尝试了以下代码:
int array[100];
int main()
{
for(int i = 0; i < sizeof(array)/sizeof(*array); i++)
array[i] = 1;
}
Run Code Online (Sandbox Code Playgroud)
我使用gcc 4.4.0编译它,如下所示:
gcc -Wa,-adhls -O0 myfile.cpp
Run Code Online (Sandbox Code Playgroud)
我再次这样做,后缀增量更改为前缀增量:
for(int i = 0; i < sizeof(array)/sizeof(*array); ++i)
Run Code Online (Sandbox Code Playgroud)
在两种情况下,结果都是相同的汇编代码.
这有些出乎意料.似乎通过关闭优化(使用-O0)我应该看到显示概念的差异.我错过了什么?有更好的例子来展示这个吗?
目前我正在教授一类C++程序员C#语言的基础知识.在我们讨论主题运算符时,我使用了C#标准类别的primary,unary等运算符.
其中一位与会者感到困惑,因为在C#标准中,"postfix ++/ - "已被归入主要运营商的类别,而不是"前缀++/ - ".她的这种混乱背后的理由是,她宁愿实现C++运算符"后缀++/- " 来讲运营商"前缀++/- ".换句话说,她宁愿将运算符"prefix ++/ - "视为主要运算符. - 我理解她的观点,但我不能给她一个理由.好吧,运营商"postfix ++/ - "的优先级高于"前缀++/ - ",但这背后的唯一理由是什么?
该规范在"14.2.1运算符优先级和关联性"一节中提到了它.
所以我非常中立的问题:为什么Postfix ++/ - 在C#中被归类为主要操作符?它有更深层次的真相吗?
在Perl文档中,有一个关于.postfix/.postcircumfix的部分,它说
在大多数情况下,可以在后缀或后缀之前放置一个点:
my @a;
@a[1, 2, 3];
@a.[1, 2, 3]; # Same
Run Code Online (Sandbox Code Playgroud)
从技术上讲,不是真正的运营商; 它的语法特殊于编译器.
我试过自己:
> my @a = 1,2,3,4,5
> @a[1] # 2
> @a.[1] # 2
> my %a = Perl => 6, Python => 3, PHP => 7
> %a<Perl> #6
> %a.<Perl> #6
> my @weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
> @weekdays.antipairs.hash{'Sunday'} # 6, I expected it to be syntax wrong, but it did work!
> @weekdays.antipairs.hash.{'Sunday'} # 6, seems …Run Code Online (Sandbox Code Playgroud) 我不明白为什么下面的代码没有按预期工作:
#include <stdio.h>
int main() {
int i = 0, size = 9, oneOrZero[] = {1,1,1,1,1,1,1,1,0};
while (i < size && oneOrZero[i++]);
if (i == size) printf("All ones"); else printf("Has a zero");
}
Run Code Online (Sandbox Code Playgroud)
Terminal: All ones.
Run Code Online (Sandbox Code Playgroud)
当增加循环内的索引时,代码按预期运行:
#include <stdio.h>
int main() {
int i = 0, size = 9, oneOrZero[] = {1,1,1,1,1,1,1,1,0};
while (i < size && oneOrZero[i]) {i++;}
if (i == size) printf("All ones"); else printf("Has a zero");
}
Run Code Online (Sandbox Code Playgroud)
Terminal: Has a zero.
Run Code Online (Sandbox Code Playgroud)
有人可以解释这两者之间的区别吗?
这样定义,我们既不做++x++也不做++x--.但另一方面,无论是(++x)++和(++x)--是有用的表达式:(++x)++增量x由两个并返回"中间"的价值,而(++x)--实质上等同于x+1而是完全避免了打电话operator+,这是非常有用的时候.
那么为什么没有定义的优先级++x++自动扩展到(++x)++而不是++(x++)?对于后者有一些隐藏的含义,我不明白,或者只是将优先级保持为一个简单的列表,所有前缀运算符组成一个单一的级别?
编辑好的,我没有明确说出来,但是:当然我的意思x是用户定义的类型.对于内置类型,(x+=2)-1当然比更好的(++x)++,并且x+1是一个很多好过(++x)--.我想到的情况是一个相当复杂的半关联容器的迭代器,其中运算符+=和+(为随机访问而设计)必须重建缓存才能有效地处理一般请求,因此是一个命令比...慢++.但是我当然可以将它们修改为总是首先检查参数是否是一个非常小的整数,并且在这种情况下只是operator++反复调用而不是执行随机访问过程.这应该可以正常工作,虽然我可以想象我可能在某种程度上有一种情况,我想operator+=总是采用随机访问方式,无论我呈现的数字有多少.
具有简单的和精心memorizeable优先列表,其中的优点所有之前来后缀运算符任何前缀运营商足以容忍的总是不必使用括号来构成前和后缀运算符的小缺点
++/--,因为该组合物是非常少用.
更简单的"C就是这样做的",虽然看起来可能是真正的原因,但对我来说远不那么令人满意,因为C中++x++根本不允许这样做,所以可以重新定义这个非常复杂的构图而不会损坏任何构图.现有代码.
无论如何,我会继续使用(++x)--,因为括号真的没有那么多伤害.
c++ increment operator-precedence prefix-operator postfix-operator
postfix-operator ×10
c ×4
c++ ×3
increment ×2
prefix ×2
arrays ×1
c# ×1
compilation ×1
grammar ×1
javascript ×1
jslint ×1
operators ×1
optimization ×1
perl6 ×1
pointers ×1
raku ×1
syntax ×1