There are just too many operators in C. There are four ways of incrementing a variable by 1.
++x; x++; x+=1; x=x+1;
They all do the same thing, although int some circumstances, the ones using prefix/postfix operators can lead to issues. I imagine that the latter two likely produce the same machine instructions.
The other problem lies with the fact that the operator set is quite compact, with many operators doing more than one thing. For example, * is used both as the multiplication operator, and as the dereference operator. && is used as the AND operator, and in singular form as the bitwise AND. The operator ^ is used for bitwise OR, where in most other languages it is used as the exponentiation operator. Maybe the most confusing is = and ==. The former is used for assignment, and the latter equality. This leads to logical errors in C programs, because pieces of code like that shown below are valid.
if (x = 2) printf("two");
Regardless of the value of x, the word “two”, will always be printed, because x is assigned the value 2, which as it is not zero, is always true. The = should have been replaced with the == operator, however C does not check for this. Sometimes the placement of operators without an added space can cause issues. For example, consider the following statements:
int x=3, y, q; *q=2; y=x/*p;
When an attempt is made to compile the program, it will generate an error, “error: unterminated comment”, because it interprets /* as the start of a compound comment. Alternatively, writing the last line with spaces in between operators, e.g. “y = x / *p” will allow the program to compile. There are also weird operators like the comma operator, which acts both as a separator, and an operator. For example, consider the following code below.
int x=11, y=17; x = 2,4,6; y = (2,4,6); printf("%d %d\n", x,y);
The value of x is 2, and the value of y is 6. In the first line of code, the comma acts as a separator, whereas in line 2 and 3 it acts as an operator. The difference is that within brackets (), the priority of the variables is given from right to left, as opposed to without (), where it is left to right. Confusing right? It is even more confusing when used in the context of array subscripts, where it can be misinterpreted as accessing a multidimensional array. For example:
int i, z; z[1,2] = 6;
This would assign element 3, i.e. z the value 6.