References for variables.Clear variables. Usually the variable understands the recording. int a (instead int may be any other type except voidmeans a type which does not contain a reference or an index so that the type can be redefined. It's called Clear Activation of the variable type int♪ This variable always has size. A clear variable can have or have no address. If the compiler simplifys the code, the variable can enter the record of the processor - and be without the address (the attempt to get an address in the debager will show that there is no address). If the compiler sees that the variable is not being used, he may not give the address to the register at all or even give the name. See what happened to the variable, you can (a) debagger b) dissembler. For global variables, the address is permanent (reservation if the compiler has not simplified, if imagtbase permanent, etc.), for local areas, usually in the glass (if the compiler has not simplified). The conduct of the compiler may change, for example, without reference to the variable, the variable may not have an address, and the compiler will collect where the variable will have an address. There are additional clues to the compilator - I won't consider them. A clear variable may be of any size between 1 bayth and a sufficiently large number of bathytes that allows the compiler to be made (even 1 mb may be possible).Unbelievable variables. Non-resident variables can be obtained by malloc, GlobalAlloc and similar, by means of auxiliary libraries (if a cultivated), by means of assembler operations (both ordinary operations and SSE MMX, etc.), by direct use of the address. The non-bearing variable cannot be made clear, but there may be a lot of them. Non-identifiable variables to which access is available can only exist by reference or indicator. If there is no access to the address through the reference or indicator, it may be considered that the variable (a) is packed (or stored in memory), it can always be obtained by carrying out premeditated operations (b) lost. Lost-- those who were lost as a result of the mistakes-- missing and impossible to find them, which is how the memory leaks come out.Reference♪ Signature f(int & b) or record int & b = выражение; makes it possible to create a reference to the circumference. The reference cannot be uninitialized. The type of reference should be consistent with the type of encryption (without a reference to be more flexible), to which it refers, and in fact repetitive, to the object that it has originally been assigned, all transactions with a new name will have the same effect that would have occurred in transactions with the original cover. The object is starting to have a new name. It's safe to distinguish the link from the non-referencing, it won't work. An index may be inserted into the reference (int *& a; In view of the fact that, on the contrary, no double reference is made int & & a - I'm confused. Constant reference int & const a - No. To the broad, the expression triggers the reference by computing the address with the reference address "shaping" address. The technical reference is stored in memory and occupies the same location as the index, which sometimes gives the possibility of reducing the memory flow when calling the function if, instead of an obvious variable, the reference. Although there may be a case where the compiler facilitates the code by disclosing the place under the reference. Typically, the reference contains a valid area(s), but it is possible to use a non-valid link as well. When resorting to a non-capital cult, there will be an exception or a fatal error or an uncertain UB conduct. Therefore, if the indicator is converted into a reference, it is desirable to check the address validity. In some languages (defe) reference is called var. The references are very similar to 99.9 per cent with common names variables, so they are sometimes used.The reference to a clear variable may be recorded. int & b = a;♪Reference to non-remarkable variable or indirect reference to the apparent variable may be obtained (a) (c) of the indicator to the variable(s) through the operator * int & b = *p; But there's an exception. If the operator is redesigned operator *() the reference to be returned by the operator will be received. It's okay. malloc - first received the index, then lead to the right type of indicator, then, through * the type of reference that is required. For example, int & z1 = *(int*)malloc*(sizeof(int)); (b) Extracting another reference already made.The address in the reference can't be changed. (a) Multipliers with addresses or registers. But they don't do that, it's UB.B., if memory is not used in a careful way, the reference can also be compromised if it happened, you have a wrong program, somewhere outside the area, breaking the net, destroying the memory, etc., you need to carefully write a program that doesn't happen.Index Index - name variable type index. The index contains the address. The index allows: (a) access to the encryption address taken. (b) checking the address by 0 (null) or not zero to (b) obtaining the address of the encryption in an absolute (dual to 10th submission, i.e. as the normal number in the case of linear memory) g) allows the use of the address as a null, and to move forward (or rearward (d) The indicator may be both single and double (like two-size) and more. There is an empty index (with zero address), an index to the apparent/non-residential variable, an index to the mass element, a non-initialized indicator may burn the use of the " launcher " may cause errors or UB - a value shall be assigned to the indicator before the use of the indicator. Usually the index is given with an expression int *p; The star, but there are more complex forms of recording (for class methods and methods, and there are cases). The indicator may be confused with the operator *()♪ The indicator may be both constant (additional to the const) and one that can be changed in the process.There's an index, and there's an operator. тип operator *()♪ The indicator is assigned to a type-application section, in all other cases is the operator of the denomination of the indicator (i.e., conversion to value or reference). Usually, this operator is not redesigned, but some software players can redesign it to get the code.The index does not give access to the subject he points directly. One of the 3 operators needs to be used to gain access to the cult. * -> [] If the expression on the left is a reference, * [] give meaning or reference. If the expression on the left is not a reference, then the whole thing is being copied to the field. These three operators work for a cult, there are no other enclaves, but they can work for individual enclaves if the operators are asked for them.Operator * operator *() (with no orange, multiplication with operandi, receipt of falcon - no) is the operator of receipt or reference from the indicator. Example of use *p♪ (*p).field (for classes). It's accepted not to use the masses or classes. But there is no prohibition on the use of such cases.Shot operator operator ->() - access to fields - Example of use p->fied♪ The operator is available only for structures and classes.Recruiting unit of the mass operator [](тип index) - allows the index to be disclosed as a reference to the mass element. Primber p[0]♪ p[0].field♪ Usually, this operator is used with references to the mass and volumes, but the zero element will be similar to * (unless the operators are redesigned). For the mass, you can get a long mass, for the indicator, no. The operator ' s negligent sight may cause malfunctions, but in the absence of an exit check outside the massivium, quick action is increased.Typically, the first two operators are not allowed to change, but all three operators can be altered to encroach the code or to create a caste-indicator. Operator [] They usually rede redesign when they want to do "better" or "virtual."Since the index has to be often converted into a meaning (more in the reference), sometimes the indicators and references are confused.Size of reference, size of indicator. The index and the reference shall be of the same size. Therefore, substitution within the function of the argument by reference or indicator may result in a reduction in operational memory. But built-in. sizeof() The size of the reference will always be the size of the encryption to which the reference is made, and the number of the address for the indicator will be different. For a normal linear x86 with a 32-bit targeting regime, the size will be 4 bayta for x64-8 bay. But the address may be different from one byte (for some micro-controllers), two bytes (16-battered mode), there are segment-of-the-board double addresses. So if you write under the cross-platform or under the non-standard platform, you have to consider the size of the address may be different. In some cases, it is possible to establish two indexes with different address sizes (when a driver or loader is written, for example). Again, if the compiler reduces the reference or the index, the physical index/link may be without the address (but the address will be stored or in the CP register or the two "replaceable" will be stored at one address).Example of an idea code with an index and a referenceПо сути, с точки зрения ассемблера
- ссылка и указаель - это почти одно и то же.
Отличие только в том, что с точки зрения с++
это разные обьекты с которыми совсем по разному
нужно работать, хоть и по функциональности они похожи.
Если не использовать все возможности указателя
- то ассемблерный код будет идеинтичным. Следующие примеры сформируют одинаковый ассемблерный код
(в 99% случаев).<code>
void SetupA_ptr(char * a){// код с указателем этого метода будет
*a = 'x'; // идеинтичный коду следующего метода
} // Но тут можно проверить ссылку на null
void SetupA_ref(char & a){// код с ссылкой
a = 'x'; // А тут нельзя сделать проверку на null
} // (т.к. при преобразованиях может возникнуть UB)
//----------
char z;
SetupA_ptr(&z); // И даже вызов тут код вызова будет одинаковым
SetupA_ref(z); // И вызов тут
</code>Example of address
Если выражение слева готово принять ссылку - происходит передача ссылки. Если выражение слева не готово принять ссылку, то происходит копирование данных. lvalue - означает left-value - преобразование по значению слева. Например (скомпилировано в старом BCC 5.0):
int a0 = 1; /* mov [ebp-180h],1; /
// Делаем ссылку на a0
int & a1 = a0; / lea edx, [ebp-180h]; mov [ebp-184h],edx; /
// Берём адрес с a1, точнее получаем указатель на a0, на обьект на который ссылается ссылка
int * a2 = &a1 / mov ecx, [ebp-184h]; mov [ebp-188h],ecx; */
// Ниже делаем ссылку по полученому адресу, в итоге на обьект a0
int & a3 = a2 / mov eax, [ebp-188h]; mov [ebp-18Ch],eax; /
// Берём адрес обьекта из ссылки a3, т.е. фактически адрес a0
int * a4 = &a3;/ mov edx, [ebp-18Ch]; mov [ebp-190h],edx; */
printf("%X ",a1); /Вывод: 1/
printf("%X ",a2); /Вывод: 18FDD0 адрес a0/
printf("%X ",a3); /Вывод: 1/
printf("%X ",a4); /Вывод: 18FDD0 адрес a0/
Но если мы ссылку или звездочка-указатель присваиваем в int - то он поменяет свой адрес.
int b0 = 1;
int * b1 = &b0; // Тут адрес b0
int b2 = *b1; // Тут мы теряем ссылку, b2 не умеет хранить адрес.
int * b3 = &b2; // А тут будет адрес b2
int & b4 = b0; // Тут адрес b0
int b5 = b4; // Тут мы теряем ссылку, b5 не умеет хранить адрес.
int * b6 = &b5; // Тут адрес b5
Но если мы пишем
int a = 1;
int b = 2;
int * pa = &a;
int * pb = &b;
*pa = *pb; // тут в а скопируется значение b, присваивание ссылки не будет
int & c = *pb; // тут будет скопирован адрес b, т.к. инициализация
// Менять ссылку ещё раз - запрещено, int& - слева запрещён.
с = a; // Скопирует значение а, 1 в переменную b.
Аналогичо, если мы передаём аргумент в функцию
f1(int arg1) - то arg1 получает копию переменной и
для arg1 резервируется отдельное место для хранения,
изменения в arg1 не повлияют на значение переменной в вызвавшей функции,
а если мы передаём аргумент в функцию
f2(int & arg2) - то arg2 сохранит адрес переменной,
а если передали ссылку - то адрес ссылки,
если передали *p (от int * p) - то сохранит адрес записаный в p.
И изменения в arg2 коснуться той переменной,
на которую создана ссылка изначально.Simplified example of a smart mass
class MyArray {
int * source;
int max_index;
int noValue; // Если адрес не верный.
public:
void Init(int * src, int maxidx) {
source = src;
max_index = maxidx;
}
int& operator[](int index) {
if ((index < 0)||(index >= max_index)) return noValue;
// Вернём что-нибудь,
//но можно a) вызвать исключение
//можно б) вызвать printf и вывести ошибку на экран
return source[index];
// Будет передана ссылка на элемент,
// Поэтому при изменении результата, который вернул оператор []
// будет меняться оригинальный массив.
// если убрать & - то получится "readonly" массив.
// Ссылка позволяет аккуратно сделать "проброс"
}
}
MyArray arr;
int array[10];
arr.Init(array,10);
arr[1] = 10;// сохранится
arr[20] = 20; // не сохранится, сбоя не будет
P.S. В STL есть хорошая реализация массива std::array The complete map file can answer what addresses the variable references and indicators have been given by the compiler. Unless the level of detail allows it to be seen. The same disassembled code will show what the compiler did to your variables and references. The use of variables and references makes it possible to optimize the code and to manage memory more flexibly.