Last Updated:

Alphabet and basic concepts of the C++

Alphabet and basic concepts of the C++

Introduction

Among modern programming languages, the C language is one of the most common. The C language is universal, but its most effective use in the tasks of system programming - the development of translators, operating systems, tools. The C language has proven itself well with efficiency, conciseness of writing algorithms, logical harmony of programs. In many cases, programs written in C are comparable in speed to programs written in Assembler, and they are more visual and easy to maintain.

The C language has a number of significant features that distinguish it from other programming languages. To a large extent, the formation of the ideology of the language was influenced by the goal set by its creators - to provide the system programmer with a convenient instrumental language that could replace Assembly. The result is a high-level programming language that provides unusually easy access to computer hardware. On the one hand, like other modern high-level languages, the C language supports a full set of structured programming constructs, modularity, and the block structure of the program. On the other hand, the C language has a number of low-level features.

Let's list some of the features of the C language.

  • C implements a number of low-level operations. Some of these operations correspond directly to machine commands, such as bitwise operations or ++ and --.
  • The basic data types of the C language reflect the same objects that you have to deal with in an Assembly program - bytes, machine words, etc. Despite the presence in the C language of developed means of constructing composite objects (arrays and structures), it has practically no means to work with them as a single whole.
  • The C language supports a mechanism for pointing to variables and functions. A pointer is a variable designed to store the machine address of a variable or function. Pointer arithmetic is supported, which allows direct access and work with memory addresses almost as easily as in Assembler. The use of pointers allows you to create highly effective programs, but requires special care from the programmer.
  • Like no other high-level programming language, the C language "trusts" the programmer. Even in such an essential matter as data type conversion, only minor restrictions are imposed. However, it also requires caution and self-control from the programmer.
  • Despite the efficiency and power design of the C language, it is relatively small in volume. It does not have built-in I/O operators, dynamic memory allocation, process control, etc., but the C system environment includes a library of standard functions that implements such actions.

The C++ language is a general-purpose programming language whose goal is to make the work of serious programmers more enjoyable. Except for non-essential details, C++ is a superset of C. In addition to the capabilities provided by C, C++ provides a flexible and efficient means of defining new types.

The programming language serves two interrelated purposes: it provides the programmer with a tool for describing the actions to be performed and a set of concepts that the programmer operates when thinking about what can be done. The first goal ideally requires a language close to the computer so that all the important elements of the computer are managed simply and efficiently in a way that is sufficiently obvious to the programmer. Language C was created on the basis of this idea. The second goal ideally requires language close to the problem being solved so that the concepts of the solution can be expressed clearly and directly. This idea led to the addition of the With Properties language, which turned it into the C++ language.

The key concept in C++ is class. Classes provide information hiding, guaranteed data initialization, implicit conversion of user-defined types, dynamic type detection, user control over memory management, and operator overloading. C++ provides much better tools than C for type checking and modular programming support. In addition, the language contains improvements not directly related to classes, such as: symbolic constants, embedding functions in the place of call, default function parameters, overloaded function names, free memory management operators, and references. The C++ language preserves the ability of the C language to work effectively with the hardware at the level of bits, bytes, words, addresses, etc. This allows you to implement user types with a sufficient degree of efficiency.

1. Alphabet

Many C characters include:

  • uppercase letters of the Latin alphabet;
  • lowercase letters of the Latin alphabet;
  • Arabic numerals;
  • separators: , . ; : ? ! ' " | / \ ~ _ ^ ( ) { } [ ] < > # % & - = + *

Other characters can only be used in character strings, character constants, and comments. The C++ language distinguishes between large and small letters, so name and Name are different identifiers.

2. Literals

Literals in C++ can be integer, real, symbolic, and string.

  • Integers (you can use the apostrophe as a separator of groups of discharges):
    • decimal: 10132-321792'147'483'647;
    • binary (preceded by "0b"): 0b110b1010b0b1111'0011;
    • octal (preceded by "0"): 0100204-076663;
    • hexadecimal (preceded by "0x"): 0xA0x840x7db3.
  • Materials: 15.751.575e1.75-.125
  • Symbolic: 'a''e''.''?''2'.
  • String: "string".

3. Comments

A comment is a sequence of characters that is ignored by the C++ compiler. The comment is as follows: /*< characters>*/. Comments can span multiple lines, but cannot be nested. In addition, the part of the string that follows the characters , is also treated as a comment.

Judicious use of comments (and consistent use of indentation) can make reading and understanding the program a more enjoyable experience. If comments are used incorrectly, the readability of the program can, on the contrary, be seriously affected. The compiler doesn't understand the meaning of comments, so there's no way to verify that a comment:

  1. meaningful;
  2. has something to do with the program;
  3. not outdated.

A well-chosen and written set of comments is an essential part of a good program. Writing the "right" comments can be just as challenging as writing the program itself.

At the level of libraries/programs/functions, comments answer the question "WHAT?": "What do these libraries/programs/functions do?". For example: This function uses Newton's method to calculate the root of the function. Such comments allow you to understand what the program is doing without having to look at the source code.

Inside libraries/programs/functions, comments answer the question "HOW?": "How does the code perform the task?". For example: To get a random element, we do the following: ...

At the single-line code level, comments answer the "WHY?" question: "Why does the code perform the job the way it does?" A bad comment at the operator level explains what the code does. If you've ever written code that was so complex that you needed a comment to explain what it was doing, then you should not write a comment, but rewrite that code.

4. C++ Data Types

NameSizeRepresented valuesRange
bool1 bytesLogicalfalse, true
(signed) char1 bytescharacters
integers
 
from –128 to 127
wchar_t2 bytesUnicode charactersfrom 0 to 65535
(signed) short int2 bytesIntegers-32768 to 32767
(signed) intdepends on the
implementation (the latest compilers usually have 4 bytes)
Integers 
(signed) long int4 bytesIntegers-2147483648 to 2147483647
(signed) long long int
(signed) __int64 (MS)
8 bytesIntegers–9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
unsigned char1 bytescharacters
integers
 
from 0 to 255
unsigned short int2 bytesIntegers0 to 65535
unsigned intdepends on the
implementation (the latest compilers usually have 4 bytes)
Integers 
unsigned long int4 bytesIntegersfrom 0 to 4294967295
(unsigned) long long int
(unsigned) __int64 (MS)
8 bytesIntegers0 to 18,446,744,073,709,551,615
float4 bytesreal numbers1.175494351e–38
to 3.402823466e+38
double8 bytesreal numbersFrom 2.2250738585072014e–308
to 1.7976931348623158e+308
long doubledepends on the implementationreal numbers 
 

In C++, there is also an enumerable type, enum, which is a subset of an integer type, and an empty type, void, which has a special purpose. It is used to declare functions that return no value, and to declare pointers to a void value. Such pointers can be converted to pointers of any other type.

In C++, you can declare structures and so-called unions.

In C++, there are no special types for arrays and strings that are represented by an array of characters.

There was no logical type in the C language. Boolean values were represented by data of an integer type, with a value of 0 corresponding to the Boolean value of false, and all other integer values corresponding to the Logical value of true. The C++ language retains this logic. By definition, true is a value of 1 when converting to an integer type, and false is a value of 0. Conversely, integers can be implicitly converted to Boolean values, converting non-zero integers to true and zero to false. Anywhere where a Boolean value is required, there can be an integer expression. In arithmetic and boolean expressions, logical values are converted into integers, operations are performed on the converted quantities.

You can implicitly convert a pointer to a Boolean value, with a non-zero pointer being true and a null pointer being set to false.

This approach allows you to declare only an integer variable instead of a logical and integer variable, while the value of the variable equal to 0 indicates the absence of some feature in the object, and the remaining values indicate its presence, and at the same time carry any additional information.

When performing binary operations, default transformations are performed to bring operands to the same type, which is then used as the result type:

  1. if one of the operands is of type long double the other is also converted to long double;
    • otherwise, if one operand is of type double, then the second operand is converted to type double;
    • otherwise, if one operand is of type float, then the second operand is converted to float type;
    • otherwise, both operands are integrally promoted, namely: values of types charsigned charunsigned charshort int and unsigned short int are converted to int, if int can represent all values of the original types, otherwise they are converted to unsigned intthe bool is converted to int.
  2. then if one operand is of type unsigned long the second operand is converted to unsigned long;
    • otherwise, if one of the operands is of type long int and the other is of type unsigned int, then if long int can represent all values of type unsigned intunsigned int is converted to long int, otherwise both operands are converted to unsigned long int;
    • otherwise, if one operand is of type long int, then the second operand is converted to type long int;
    • otherwise, if one operand is of type unsigned int, then the second operand is converted to type unsigned int;
    • otherwise both operands are of type int.

In the C++ language, there are no conversion operations between the symbol and the symbol code, because in RAM the symbol is already stored as its code. Therefore, you can add 1 to the variable that stores the symbol and get the next character.

5. C++ Language Operations

This table describes the operations of the C++ language. Operations are divided into groups, arranged in descending order of priority for operations.

Transaction markNameAssociativity
::Scope resolutionFrom left to right
( )    [ ]    .    ->
++    --
static_cast
dynamic_cast
reinterpret_cast
const_cast
Primary
Postfix Increment and Decrement
Compile-Time
Validated Conversion Transformation With Validation During Execution Conversion Without Checking

Constant Transformation
From left to right
-    ~    ! * &
++ --
sizeof
(<type>)<expression>
new
delete
Unary
Prefix Increment and Decrement
Size
Calculation Type Conversion Memory
Allocation
Memory Release
From right to left
.*    ->*Selecting a Class MemberFrom left to right
*    /    %MultiplicativeFrom left to right
+    -AdditiveFrom left to right
<<    >>ShiftFrom left to right
<    >    <=    >=AttitudeFrom left to right
==    !=AttitudeFrom left to right
&Bit-by-bit andFrom left to right
^Bit-by-bit exclusive ORFrom left to right
|Bitwise ORFrom left to right
&&Logical &From left to right
||Logical ORFrom left to right
? :Conditional operationFrom right to left
=    *=    /=    %=    +=    -=    <<=    >>=    &=    ^=    |=Simple and composite assignmentsFrom right to left
throwException generationFrom left to right
,Sequential calculation operationFrom left to right
 
  • :: – Scope resolution operation. When you re-declare a name in a nested block or class, the previous declarations are hidden. However, you can use the hidden name of a class member to qualify it with a class name by using a scope resolution operation. You can use a hidden global name if you qualify it as a unary scope resolution operation.
  • ( ) is an expression in parentheses (used to change the order of the calculation) or a function call.
  • [ ] is an index expression used to work with arrays.
  • . and ->, an element selection, are used when working with classes, structures, and unions.
  • Operations static_cast (compile-time validation conversion), dynamic_cast (run-time validation conversion), reinterpret_cast (unchecked conversion), const_cast (constant transformation) perform various type conversions. They have the following syntax: operation<new type>(expression). Angle brackets are an element of syntax. The static_cast operation converts related types, such as a pointer to one type to a pointer to another type from the same class hierarchy, an integer type to an enumeration, or a floating-point type to an integral type. The reinterpret_cast operation manages conversions between unrelated types, such as integers into pointers or pointers into other (unrelated) pointers. This distinction allows the compiler to perform minimal type checking when using static_cast, and it is easier for the programmer to detect dangerous transformations represented by reinterpret_cast. The dynamic_cast conversion is performed and validated at run time. The const_cast transform cancels the action of the const modifier.
  • - - Unary minus.
  • ~ – reverse code (see Lecture 8).
  • ! - Logical negation.
  • * – indirect addressing (see Lecture 5).
  • & – addressing (see Lecture 5).
  • The ++ and -- operations increment (increase by 1) and decrement (decrease by 1) their operand. The operand must have an integer, real type, or be a pointer. Increment and decrement operations can be recorded both before their operand (prefix form of recording) and after it (postfix form of recording). In the prefix form of the record, the operand is first incremented or decremented, and then its new value participates in the further evaluation of the expression containing the operation. In the postfix form of the record, the operand is incremented or decremented only after its old value is involved in the evaluation of the expression. Thus, the result of the increment and decrement operations is either a new or an old operand value. For example, if the variable = 0, then the expression [++] = 1 changes the element [1], and the expression [++] = 1 changes the element [0]. In both cases, the variable receives a new value of 1. iaiaaiai
  • sizeof – Calculate the size in bytes of a variable or type.
  • The type casting operation is written as follows: (<new type>)<expression>. For example, (long int)n casts a variable to type long int. When converting types, keep in mind that errors may occur when converting between signed/unsigned values and when converting from a type with a higher dimension to a type with a lower dimension. A safer way to convert types is to use static_castdynamic_castreinterpret_cast, and const_cast operationsn
  • % is the remainder of the division.
  • In C++, there is one ternary operation, a conditional operation. It has the following syntax: <operand 1> ? <operand 2> : <operand 3>. If <operand 1> has a nonzero value, then the <operand 2> is calculated and the result of the conditional operation is its value. If the <operand 1> is zero, then the <operand 3> is calculated and the result is its value. In either case, only one of the operands <operand 2> or <operand 3> is calculated, but not both.
  • Easy assignment. The simple assignment operation is indicated by the "=" sign. The value of the right operand is assigned to the left operand. The operation produces a result that can be further used in the expression. The result of the operation is the assigned value. For example, the expression = = = 0 assigns all variables a value of 0, and as a result of evaluating the expression = ( = 3) + ( = 5), the variable will have a value of 5, the variable will have a value of 3, and the variable will have a value of 8. abcabccba
  • Compound assignment. A compound assignment operation consists of a simple assignment operation combined with some other binary operation. Compound assignment first performs the action specified by the binary operation, and then assigns the result to the left operand. The operator += 5 is equivalent to the operator = + 5, but the first operator is easier to understand and faster. nnn
  • The sequential calculation operation "," is typically used to evaluate multiple expressions in situations where only one expression is allowed by syntax. However, the comma separating the parameters of the function is not a sequential calculation operation.

The order in which subexpressions within expressions are evaluated is not defined. In particular, do not assume that expressions are evaluated from left to right.

int x = f(2) + g(3); // It is not known which function will be called first - f() or g()

If there are no restrictions on the order of calculations, you can generate better code. However, the absence of restrictions on the order of calculations can lead to uncertain results.

Logical operations "AND" and "OR", conditional operation and sequential operation guarantee a certain order of calculation of their operands. A conditional operation calculates first its first operand and then, depending on its value, either a second or a third operand. Logical operations also provide a calculation of their operands from left to right, with logical operations calculating the minimum number of operands required to determine the result of an expression. Thus, the second operand of the expression may not be evaluated at all. A sequential calculation operation calculates its operands in turn, from left to right. Note that the comma as a sequence pointer is logically different from the comma used as a parameter separator when calling functions.

f1(v[i], i++); // Two parameters f2((v[i], i++)); // One parameter

The f1 function is called with two parameters v[i] and i++, and the order in which the parameters are calculated is not defined. Counting on a certain order of calculation of parameters is an exceptionally bad style and leads to unpredictable behavior of the program. A call to the f2 function has one parameter, a sequence of expressions separated by a comma. The calculation order is guaranteed, and the call is equivalent to f2(i++)..