[CPP] Variables

Type Conversion

A simple example:
bool b = 42; //b is true
int i = b;              // i has value 1
i = 3.14;               // i has value 3
double pi = i;          // pi has value 3.0
unsigned char c = -1;   // assuming 8-bit chars, c has value 255
signed char c2 = 256;   // assuming 8-bit chars, the value of c2 is undefined

Expressions Involving Unsigned Types

For example, if we use both unsigned and int values in an arithmetic expression, the int value ordinarily is converted to unsigned. Converting an int to unsigned executes the same way as if we assigned the int to an unsigned(see the 32bits)
example:
enter image description here
enter image description here
Why in the first code, it is correct but in the second one “u+i” become so strange?!
This is because int will always convert to unsigned int.
  • In the first program, -9 convert to a relatively big number and add 10, then overflow appears again and it change to a positive value 1 instead.
  • In the second program, there is no overflow, so it is the biggest unsigned int “value - 1”

Unsigned value will never be smaller than 0 even if you minus it.

enter image description here
Because the unsigned value will never be smaller than 0, so the following loop will be dead loop.
for( unsigned int i = 10; i>=0; i--){
    //do something
}

Initialization

List initialization

we can use any of the following four different ways to define an int variable named units_sold and initialize it to 0:
int units = 0;
int units = {0};
int units(0);
int units{0};

Compounded types

A compound type is a type that is defined in terms of another type. C++ has several compound types, two of which—references and pointers

Reference

A reference defines an alternative name for an object. A reference type “refers to” another type. We define a reference type by writing a declarator of the form &d, where d is the name being declared:
int ival = 1024;
int &refVal = ival;  // refVal refers to (is another name for) ival
int &refVal2;        // error: a reference must be initialized

Why reference should be initialized?

When we define a reference, instead of copying the initializer’s value, we bind the reference to its initializer. Once initialized, a reference remains bound to its initial object. There is no way to rebind a reference to refer to a different object. Because there is no way to rebind a reference, references must be initialized.

examples of mistake

initializer must be an object
the type of a reference and the object to which the reference refers must match exactly.
int &refVal4 = 10;   // error: initializer must be an object
double dval = 3.14;
int &refVal5 = dval; // error: initializer must be an int object
enter image description here
  • if the reference changes, the original value also changes.

Pointers

A pointer is a compound type that “points to” another type. Like references, pointers are used for indirect access to other objects.
  • Unlike a reference, a pointer is an object which can be assigned and copied.
  • A single pointer can point to several different objects over its lifetime.
  • A pointer need not be initialized at the time it is defined.
    double dval;
    double *pd = &dval;  // ok: initializer is the address of a double
    double *pd2 = pd;    // ok: initializer is a pointer to double
    int *pi = pd;  // error: types of pi and pd differ
    pi = &dval;    // error: assigning the address of a double to a pointer to int
    

using a pointer to access an object

enter image description here
At here p = 11; is used as a dereference operator.

Const again

share const between files

To share a const object among multiple files, you must define the variable as extern.

reference to const

Because const can not be changed, so the reference to const still can not be changed, so we need to use const reference instead of normal reference.
const int ci = 1024;
const int &r1 = ci; // correct!
r1 = 42; //wrong! This intended to change r1, which changes the const value
int &r2 = ci; // wrong, r2 is not a const reference but a normal reference

initialization and reference to const

It is mentioned before that the type of reference must be matched with the type with the object being referenced.
The first exception is that we can initialize a reference to const from any expression that can be converted to the type of the reference. In particular, we can bind a reference to const to a non const object, a literal, or a more general expression:
int i = 42;
const int &r1 = i; //we can bind const int reference to a plain int object
const int &r2 = 42; // correct
const int &r3 = r1 * 2; // correct
int &r4 = r1 * 2; //wrong! r4 is a normal reference, but 

But do not change the value through const reference

int i = 42;
int &r1 = 1; 
const int &r2 = i; //correct, as above explanation
r1 = 0; //correct, i change to 0, because r1 is normal reference
r2 = 0; //wrong, r2 is a const reference

Pointer to const

Like a reference to const, a pointer to const may not be used to change the object to which the pointer points. We may store the address of a const object only in a pointer to const:
const double pi = 3.14
double *ptr = π //wrong, ptr is a normal pointer
const double *cptr = π //correct
*cptr = 42; //wrong, can not change the value of the const pointer
double dval = 3.14;
cptr = &dval; //correct; although the type of pointer is const but value is not const, but it is a exception too.
Remember, in pointer to const or reference to const, there is a exception for two types of things matched together, which is a const pointer/reference to a normal value.
Also , in this situation, we still can not change the value of const pointer/reference because essentially, they are “const”

const pointer

int num = 0;
int *const cur = # //cur will always points to num(can not change)
const double pi = 3.1415;
const double *const pip = π// pip is a const pointer to a const object

constexpr and const expression

A constant expression is an expression whose value cannot change and that can be evaluated at compile time.
for example:
const int max_files = 20; //constant expression
const int limit = max_files + 1; //constant expression
int staff_size = 27; //no
const int sz = get_size(); //no, because can not be evaluated at compile time

constexpr variable

Variables declared as constexpr are implicitly const and must be initialized by constant expressions
constexpr int mf = 20; //20 is a constant expression
constexpr int limit = mf + 1; //mf + 1 is a constant expression
constexpr int sz = size(); //ok only if size() is also a constexpr function

评论

此博客中的热门博文

[MLE] Linear Classification

[AIM] MetaHeuristics

[CS231] Neural Networks