Другие языки программирования и технологии
Указатели или что это у вас * & C++
Объясните срочно кратко, что значат эти символы перед или после переменных, и зачем они нужны вообще, заранее спасибо
void foo(char* str) {
}
void foo(std::string& str) {
}
В первом случае - указатель, во втором - ссылка. В C++ стараются почти не использовать указателей. Есть еще умные указатели, но и их тоже. То есть до 99% кода - ссылки
}
void foo(std::string& str) {
}
В первом случае - указатель, во втором - ссылка. В C++ стараются почти не использовать указателей. Есть еще умные указатели, но и их тоже. То есть до 99% кода - ссылки
Каждая переменная хранится в памяти.
Например:
int a = 0;
Переменная a хранится в памяти, начиная с адреса, допустим, 1000 и занимает 4 байта - байты по адресу 1000, 1001, 1002, 1003.
Указатель на a:
int * p = &a;
Звездочка ( * p ) значит, что p - это указатель, то есть, число (как правило, из 8 байт, либо из 4х байт).
Тип int перед звездочкой ( int * p ) значит, что p указывает на место в пямяти, начиная с которого хранятся данные переменной типа int (то есть, 4 байта - int обычно занимает 4 байта).
Амперсанд ( & ) в этом случае значит "взять адрес памяти, начиная с которого хранится переменная a", то есть, &a будет в нашем случае равен 1000.
Если написать:
*p = 1;
То это будет значить "содержимому, которое находится по адресу, хранящемуся в указателе p и занимает количество байт памяти, соответствующее размеру типа, на который указывает p (int, 4 байта), присвоить 1".
По адресу 1000 запишутся 4 байта - 1, 0, 0, 0 - и значение a станет равным 1.
Значение (*p) тоже будет равно 1.
Если написать:
a = 11;
То значение содержимого указателя p, то есть, *p станет тоже равно 11.
Еще бывает ссылка.
Ссылка - это почти то же самое, что указатель, просто пишется по-другому.
Например:
int & r = a;
Это значит "завести ссылку r, которая указывает на значение типа int, которое лежит по адресу памяти, начиная с которого лежит переменная a", то есть, на 4 байта, начиная с адреса 1000 в нашем случае.
Если написать:
r = 2;
то в память по адресам 1000-1003 запишутся байты 2, 0, 0, 0. Значение r станет равно 2 и значение a станет равно 2.
Если написать:
a = 22;
То значение ссылки r тоже станет равно 22.
Ссылка отличается от указателя тем, что на ходу нельзя изменить адрес, на который она указывает. То есть. Допустим, есть еще переменная b, которая лежит начиная с адреса 2000.
int b = 3;
На ходу для указателя p мы можем написать:
p = &b;
Тогда p станет равным 2000. Он будет указывать на 4 байта, которые лежат по адресам 2000-2003.
И если мы напишем:
*p = 4;
То в память по адресам 2000-2003 запишутся байты 4, 0, 0, 0 и значение переменной b станет равным 4.
Однако, для ссылки мы так написать не можем -- если напишем
&r = b;
То будет ошибка компиляции.
Адрес ссылке можно только при создании этой ссылки присваивать.
Например:
int a = 0;
Переменная a хранится в памяти, начиная с адреса, допустим, 1000 и занимает 4 байта - байты по адресу 1000, 1001, 1002, 1003.
Указатель на a:
int * p = &a;
Звездочка ( * p ) значит, что p - это указатель, то есть, число (как правило, из 8 байт, либо из 4х байт).
Тип int перед звездочкой ( int * p ) значит, что p указывает на место в пямяти, начиная с которого хранятся данные переменной типа int (то есть, 4 байта - int обычно занимает 4 байта).
Амперсанд ( & ) в этом случае значит "взять адрес памяти, начиная с которого хранится переменная a", то есть, &a будет в нашем случае равен 1000.
Если написать:
*p = 1;
То это будет значить "содержимому, которое находится по адресу, хранящемуся в указателе p и занимает количество байт памяти, соответствующее размеру типа, на который указывает p (int, 4 байта), присвоить 1".
По адресу 1000 запишутся 4 байта - 1, 0, 0, 0 - и значение a станет равным 1.
Значение (*p) тоже будет равно 1.
Если написать:
a = 11;
То значение содержимого указателя p, то есть, *p станет тоже равно 11.
Еще бывает ссылка.
Ссылка - это почти то же самое, что указатель, просто пишется по-другому.
Например:
int & r = a;
Это значит "завести ссылку r, которая указывает на значение типа int, которое лежит по адресу памяти, начиная с которого лежит переменная a", то есть, на 4 байта, начиная с адреса 1000 в нашем случае.
Если написать:
r = 2;
то в память по адресам 1000-1003 запишутся байты 2, 0, 0, 0. Значение r станет равно 2 и значение a станет равно 2.
Если написать:
a = 22;
То значение ссылки r тоже станет равно 22.
Ссылка отличается от указателя тем, что на ходу нельзя изменить адрес, на который она указывает. То есть. Допустим, есть еще переменная b, которая лежит начиная с адреса 2000.
int b = 3;
На ходу для указателя p мы можем написать:
p = &b;
Тогда p станет равным 2000. Он будет указывать на 4 байта, которые лежат по адресам 2000-2003.
И если мы напишем:
*p = 4;
То в память по адресам 2000-2003 запишутся байты 4, 0, 0, 0 и значение переменной b станет равным 4.
Однако, для ссылки мы так написать не можем -- если напишем
&r = b;
То будет ошибка компиляции.
Адрес ссылке можно только при создании этой ссылки присваивать.
Символы * и & в с++ имеют очень много смыслов в различных контекстах, и понимание этих смыслов требует понимания синтаксиса этих контекстов.
При объявлении нового экземпляра * будет означать указатель на экземпляр. & соответственно - ссылка.
int * a;
int & b;
Те же знаки перед переменной - другой смысл: * - разыменование указателя, & - взятие адреса переменной.
В контексте выражения & может быть бинарным оператором "и".
Двойной && это вообще песня - в выражении может быть логическим оператором "и".
В объявлении экземпляра это уже ссылка на так называемое rvalue (правая ссылка). Это как бы значение без имени, которому мы теперь решили таки дать имя, но не делать для него переменную.
Теперь ещё веселее && у аргумента темплейтной функции. Это уже будет не ссылка а перенаправляющая ссылка (forwarding reference). Ее вообще непросто объяснить, так что я не буду терять на нее время.
Может ещё что забыл...
При объявлении нового экземпляра * будет означать указатель на экземпляр. & соответственно - ссылка.
int * a;
int & b;
Те же знаки перед переменной - другой смысл: * - разыменование указателя, & - взятие адреса переменной.
В контексте выражения & может быть бинарным оператором "и".
Двойной && это вообще песня - в выражении может быть логическим оператором "и".
В объявлении экземпляра это уже ссылка на так называемое rvalue (правая ссылка). Это как бы значение без имени, которому мы теперь решили таки дать имя, но не делать для него переменную.
Теперь ещё веселее && у аргумента темплейтной функции. Это уже будет не ссылка а перенаправляющая ссылка (forwarding reference). Ее вообще непросто объяснить, так что я не буду терять на нее время.
Может ещё что забыл...
Похожие вопросы
- Как разыменовать указатель в C++
- Зачем в С/C++ создан отдельный тип "указатель"
- Когда стоит использовать указатели c++
- Зачем нужны указатели в c++? начал изучать язык C++ и не очень понимаю зачем нужны указатели?
- Зачем вообще указатели в C++?
- Массив указателей в C++
- C++. Указатели. Связный список. Как добавить элемент в конец списка? Вопрос для разбирающихся
- C++ Указатели и функции.
- C++: в чем принципиальная разница между использованием членов класса и указателей на них?
- C++ указатель на ссылку, ссылка на указатель что можно создать и пример кода если нетрудно.