Explain the use of binary complement operator and subscript operator in C++

  • 2020-05-07 20:10:36
  • OfStack

2 base complement operator: ~  
grammar


~ cast-expression

note
The base 2 inverse operator (~) (sometimes called the "bitwise inverse" operator) generates the base 2 inverse of its operands. That is, each bit of 1 in the operand is 0 in the result. In contrast, each bit that is 0 in the operand is 1 in the result. The operands of the base 2 inverse operator must be integer.
The operator keyword of ~
The compl operator is the text equivalent of ~. The compl operator in the program can be accessed in two ways: by including the header file iso646.h, or by compiling with /Za.


// expre_One_Complement_Operator.cpp
// compile with: /EHsc
#include <iostream>

using namespace std;

int main () {
  unsigned short y = 0xFFFF;
  cout << hex << y << endl;
  y = ~y;  // Take one's complement
  cout << hex << y << endl;
}

In this example, the new value assigned to y is the 2-base inverse of the unsigned value 0xFFFF or 0x0000.
An integer promotion is performed on an integer operand, and the resulting type will be the type to which the operand will be promoted.

subscript operator: []


 postfix-expression [ expression ]

note
The suffix expression followed by the subscript operator [], which can also be the main expression, specifies the array index.
Typically, postfix-expression represents one pointer value (such as a group identifier) and expression is one integer value (including enumerated types). However, syntactically, you only need one expression to be of pointer type and one to be of integer type. Therefore, the integer value can be in the postfix-expression position, and the pointer value can be in the square bracket or subscript position of expression. Consider the following code snippet:


  int nArray[5] = { 0, 1, 2, 3, 4 };
  cout << nArray[2] << endl;      // prints "2"
  cout << 2[nArray] << endl;      // prints "2"

In the previous example, the expression nArray[2] is the same as 2[nArray]. The reason is that the result of the subscript expression e1[e2] is given as follows:


*( ( e2 ) + (e1) )

The address generated by this expression is not e2 bytes in the e1 address. Instead, the address is scaled to generate the next object in the array e2. Such as:


double aDbl[2];

The addresses of aDb[0] and aDb[1] are 8 bytes apart - the size of an object of type double. Scaling by object type is done automatically by the C++ language, which discusses the addition and subtraction operators of operands of pointer types.
Subscript expressions can also have multiple subscripts, as shown below:


expression1 [expression2] [expression3]...

The subscript expression is associated from left to right. First, the leftmost subscript expression expression1[expression2] is evaluated. The address obtained by adding expression1 and expression2 constitutes a pointer expression. expression3 will then be added to this pointer expression to form a new pointer expression, and so on, until the last subscript expression is added. After the final subscripted expression is evaluated, the indirection operator (*) is applied, unless the final pointer value will be addressed for the array type.
An expression with multiple subscripts refers to the elements of a multidimensional array. A multidimensional array is an array whose elements are arrays. For example, the first element of a 3-dimensional array is an array with two dimensions. The following example declares and initializes a simple 2-dimensional array of characters:


// expre_Subscript_Operator.cpp
// compile with: /EHsc
#include <iostream>

using namespace std;
#define MAX_ROWS 2
#define MAX_COLS 2

int main() {
  char c[ MAX_ROWS ][ MAX_COLS ] = { { 'a', 'b' }, { 'c', 'd' } };
  for ( int i = 0; i < MAX_ROWS; i++ )
   for ( int j = 0; j < MAX_COLS; j++ )
     cout << c[ i ][ j ] << endl;
}

Positive and negative
The first element of the array is element 0. The C++ array ranges from array[0] to array[size]. However, C++ supports positive and negative indices. The negative index must be in the bounds of the array; Otherwise the outcome is unpredictable. The following code shows the positive array and negative group subscripts:


#include <iostream>
using namespace std;

int main() {
  int intArray[1024];
  for (int i = 0, j = 0; i < 1024; i++)
  {
    intArray[i] = j++;
  }

  cout << intArray[512] << endl;// 512
  
  int *midArray = &intArray[512]; // pointer to the middle of the array

  cout << midArray[-256] << endl;  // 256

  cout << intArray[-256] << endl; // unpredictable
}

The negative subscript in the previous line can cause a runtime error because it points in memory to an address 256 bytes below the origin of the array. The pointer midArray is initialized to the midpoint of intArray; So you can use positive arrays and negative group indexes on them. Array index errors do not cause compile-time errors, but they can produce unpredictable results.
The subscript operator is commutative. Therefore, the expressions array[index] and array[array] are definitely 1 equivalent as long as there is no overloaded subscript operator (see overloaded operator). The first form is the most common coding practice, but they all work.


Related articles: