C++ - Tutorial 003. Constants

C++, const, constexpr

C =++ supports two notations of immutability:

  1. const - which implies that the value will not change. First of all, this is used to specify interfaces, for data that is passed to functions and methods so that they are not afraid that they will be changed. The compiler monitors the presence of the const qualifier;
  2. constexp - which involves calculating the constant at compile time. Used to store data in memory where they will not be damaged, and to improve performance.

For example:

const int dmv = 17;                      // Constant with the name dmv
int var = 17;                            // Var is not a constant
constexpr double max1 = 1.4∗square(dmv); // OK, since square (17) is a constant expression
constexpr double max2 = 1.4∗square(var); // Error, because var is not a constant
const double max3 = 1.4∗square(var);     // OK, because the expression can be evaluated in runtime
double sum(const vector<double>&);       // sum will not modify its arguments
vector<double> v {1.2, 3.4, 4.5};        // v is not a constant
const double s1 = sum(v);                // OK, it will be calculated in runtime
constexpr double s2 = sum(v);            // Error, sum (v) is not a constant expression.

In order for the function to be used in a constant expression, that is, it was computed by the compiler, it is necessary to define it with the constexpr qualifier.

constexpr double square(double x) { return x∗x; }

The constexpr function must be simple enough to compute by the compiler, and also return the computed value. Constexpr functions can be called by non-constants arguments in the context of which constant expressions are not required.

const

Objects with the const qualifier can not be changed, and must also be initialized.

const int model = 90;           // model is a constant
const int v[] = { 1, 2, 3, 4 }; // v[i] is a constant
const int x;                    // Error: value not initialized

Since objects with const qualifiers can not be changed, the following code will be incorrect:

void f()
{
    model = 200; // Error: model is a constant
    v[2] = 3;    // Error: v[i] is a constant
}

Note that const changes the type of the object, not an indication of how the variable should be assigned. const limits the way the object works.

void g(const X∗ p)
{
    // Can not change p here
}

void h()
{
    X val;  // But we can modify the value here
    g(&val);
    // ...
}

When using a pointer, two objects are involved: the pointer itself and the object pointed to. A prefix declaration of a pointer with const makes the object constant, not a pointer. To declare const as the pointer itself, and not the object to which it points, you must place const after the pointer character. For example:

void f1(char∗ p)
{
    char s[] = "Gorm";

    const char∗ pc = s;        // Pointer to constant
    pc[3] = 'g';               // Error: the value of the object is a constant
    pc = p;                    // OK

    char ∗const cp = s;        // Constant pointer
    cp[3] = 'a';               // OK
    cp = p;                    // Error: cp is a constant

    const char ∗const cpc = s; // Constant pointer to a constant object
    cpc[3] = 'a';              // Error: the object is a constant
    cpc = p;                   // Error: pointer is a constant
}

The location of const relative to the base type is not important, since there is no data type const *. Principle is the position of const relative to the symbol *. Therefore, the following entries are possible:

char ∗const cp;  // const pointer to char
char const∗ pc;  // pointer to const char
const char∗ pc2; // pointer to const char

An object that is a constant when accessed through one pointer can be changed when accessed in other ways. This is especially useful for function arguments. Declaring a pointer argument as a const, a function is not allowed to change the object it points to. For example:

const char∗ strchr(const char∗ p, char c);
char∗ strchr(char∗ p, char c);

The first version is used for strings whose elements should not be changed by the function and returns a pointer to const that does not allow changing the result. The second version is used for mutable lines.

You can assign a non-constant variable address to a pointer to a constant, because it can not do any harm. However, you can not assign a constant address to a non-constant pointer, since this will change the value of the object. For example:

void f4()
{
    int a = 1;
    const int c = 2;
    const int∗ p1 = &c; // OK
    const int∗ p2 = &a; // OK
    int∗ p3 = &c;       // Error: initialization int* with const int*
    ∗p3 = 7;            // Attempt to change the value of c
}

constexpr

A constant expression is an expression that is evaluated at compile time. Constant expressions can not use values and variables that are not known at compile time.

There are many reasons why someone might need a named constant, not a letter or value stored in a variable:

  1. Named constants simplify understanding and code support.
  2. A variable can be changed (so we must be more careful in our reasoning than with a constant).
  3. The language requires constant expressions for array sizes, case labels, and template value arguments.
  4. Embedded programmers like to put immutable data in a persistent storage device. Because read-only memory is cheaper than dynamic memory (in terms of cost and energy consumption) and often more numerous. In addition, the data in the permanent memory is protected from most system failures.
  5. If initialization is performed at compile time, there can not be any discrepancies in the multithreaded program.
  6. Performing compilation at the compilation stage improves program performance.

The value of constexpr is evaluated at compile time, and if it can not be computed, the compiler will generate an error.

int x1 = 7;
constexpr int x2 = 7;
constexpr int x3 = x1;     // Error: initializer is not a constant expression
constexpr int x4 = x2;     // OK

void f()
{
    constexpr int y3 = x1; // Error: initializer is not a constant expression
    constexpr int y4 = x2; // OK
    // ...
}

The possibilities of constant expressions are quite large, since it is possible to use integer data types, floating-point data, enums, and operators that do not change the values of variables (such as +,? And [] , but not = or ++ )

constexpr int isqrt_helper(int sq, int d, int a)
{
    return sq <= a ? isqrt_helper(sq+d,d+2,a) : d;
}

constexpr int isqrt(int x)
{
    return isqrt_helper(1,3,x)/2 − 1;
}

constexpr int s1 = isqrt(9);
constexpr int s2 = isqrt(1234);

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.
Support the author Donate

Отличное описание и примеры!

Comments

Only authorized users can post comments.
Please, Log in or Sign up
Donate

Hello, Dear Users of EVILEG!!!

If the site helped you, then support the development of the site financially, please.

You can do it by following ways:

Thank you, Evgenii Legotckoi

VL
Jan. 20, 2020, 12:42 p.m.
Vova Lebedev

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:60points,
  • Rating points-1
VL
Jan. 20, 2020, 12:33 p.m.
Vova Lebedev

C++ - Test 001. The first program and data types

  • Result:80points,
  • Rating points4
AP
Jan. 20, 2020, 5:48 a.m.
Anastassiya Polyakova

C++ - Тест 003. Условия и циклы

  • Result:57points,
  • Rating points-2
Last comments
Jan. 17, 2020, 2:31 a.m.
Andrej Jankovich

Выглядит как ошибка библиотеки. Расскажите подробно на какой платформе вы собираете проект (MinGW или MSVC) их версии и версии Qt.
D
Jan. 16, 2020, 12:06 p.m.
DENIZ1819

Доброго времени суток, не подскажите, что делать в данной ситуации, после того, как я сделал все вышеуказанные инструкции для подключения библиотеки к проекту?
Jan. 14, 2020, 5:33 a.m.
Evgenij Legotskoj

Рекомендую Wt, достаточно мощная вещь. Этот фреймворк может использоваться для написания сайтов на C++, либо можно использовать только отдельный компоненты, например только ORM. Но я не знаю, ка…
a
Jan. 14, 2020, 5:29 a.m.
ayb

Спасибо за инфу. Поиск качественной ORM привел меня только к sqlite_orm, но не подходит из-за необходимости полноценной поддержки c++14. Про framework Wt не слышал, спасибо за наводку.
Jan. 14, 2020, 2:50 a.m.
Evgenij Legotskoj

Вы заблуждаетесь. Любая нормальная ORM позволяет выполнение сырых SQL запросов. А если хорошо разобраться в работе моделей данных в Qt, то не составит труда использовать ORM вместе с Qt, ту же с…
Now discuss on the forum
VZ
Jan. 20, 2020, 2:37 p.m.
Vladimir Zhitkovsky

Еще не очевидное поведение оказалось, что сигнал onVisibleChanged родительского элемента может вызваться раньше, чем вызовуться onCompleted дочерних компонентов.. как мне очень странно. А вот на…
Jan. 20, 2020, 1:49 p.m.
Evgenij Legotskoj

Добрый день, Касательно удаления строк. Любой QTableView класс, или наследованый от него имеет метод selectionModel() , который возвращает QItemSelectionModel . А эта…
Jan. 20, 2020, 1:38 p.m.
Evgenij Legotskoj

Добрый день, Я не работал с iOS, поэтому могу только догадываться, не может ли быть проблема в самом url? То есть не может ли быть какой-то другой путь в Qt, а не file:assets-lib…
Jan. 20, 2020, 1:35 p.m.
Evgenij Legotskoj

Добрый день. В Qt по сути используется MV шаблон проектирования. Поскольку контроллер и представление объединены в представлении. Так что да, вы понимаете правильно суть Qt. Насчёт тормозов…
m
Jan. 20, 2020, 11:14 a.m.
mihamuz

Совершенно верно. Только увидел Ваше сообщение:)
EVILEG
About
Services
© EVILEG 2015-2019
Recommend hosting TIMEWEB