Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
1 / 1 / 0
Регистрация: 02.10.2023
Сообщений: 39

Почему можно сделать ссылку int*& = p на указатель *p = arr, но нельзя напрямую int*& = arr?

28.02.2024, 12:16. Показов 756. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здесь ошибок нет

C++
1
2
3
    int arr[4];
    int *p = arr;
    int*& x = p;
А здесь пишет annot bind non-const lvalue reference of type 'int*&' to an rvalue of type 'int*' кто-нибудь может объяснять почему. В первом случае мы присваим укзаателю р значение arr, т е адрес первого элемента массива. А во втором мы делаем тоже самое, то через дополнительную переменнуб
C++
1
2
    int arr[4];
    int*& x = arr;
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
28.02.2024, 12:16
Ответы с готовыми решениями:

Написать функцию swap(int& a,int& b,int& c), которая изменяет значения параметров по правилу a->b->c->a
Написал 3 функции с разной адресацией, возникает проблема с swap1 и swap. Не могу понять где ошибка. Нужно чтоб вывод работал: По...

Синонимы операций взятия адреса массива (arr и &arr)
возможно коряво написал заголовок, да и сам вопрос банальный. после создании лок. массива его адрес можно получить при помощи его имени или...

Напишите функцию f(int& m1, int& m0, int N), которая воз- вращает первую и последнюю цифры двузначного натурального числа N
Напишите функцию f(int& m1, int& m0, int N), которая воз- вращает первую и последнюю цифры двузначного натурального числа N. Решение. ...

12
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
28.02.2024, 12:36
Сам arr нельзя изменять, а p можно.
0
459 / 246 / 15
Регистрация: 29.10.2014
Сообщений: 1,084
28.02.2024, 12:48
Цитата Сообщение от efewfedd Посмотреть сообщение
А во втором мы делаем тоже самое
?
int& x = arr; - это попытка передачи по ссылке всего статического массива, а не его первого элемента. Ошибка отражается компилятором, а '*' - это "ошибка из ошибки".
0
Заблокирован
28.02.2024, 13:36
Цитата Сообщение от nmcf Посмотреть сообщение
Сам arr нельзя изменять, а p можно.
Всё не совсем так.
Результат приведения массива в указатель - является prvalue.
А на prvalue нельзя взять ссылку.

Добавлено через 32 секунды
В большинстве случаев.... )
1
фрилансер
 Аватар для Алексей1153
6444 / 5637 / 1128
Регистрация: 11.10.2019
Сообщений: 14,997
28.02.2024, 13:50
Цитата Сообщение от efewfedd Посмотреть сообщение
Почему
потому что тип неверно указан

C++
1
2
3
4
5
6
7
8
9
10
11
    int arr[4];
    
    int(&x)[4] = arr;//ссылка на массив
    int(*p)[4] = &arr;//указатель на массив
    
    //или так
    auto& x1=arr;
    auto* p1=&arr;
 
    static_assert(std::is_same_v<decltype(x),decltype(x1)>);
    static_assert(std::is_same_v<decltype(p),decltype(p1)>);
Добавлено через 1 минуту
а тут
Цитата Сообщение от efewfedd Посмотреть сообщение
int *p = arr;
автоматическое встроенное преобразование имени массива в указатель на его первый элемент. То есть, так:
C++
1
int *p = &arr[0];
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
28.02.2024, 14:04
Цитата Сообщение от SmallEvil Посмотреть сообщение
Всё не совсем так.
Результат приведения массива в указатель - является prvalue.
А на prvalue нельзя взять ссылку.
Ну я об этом и сказал простыми словами.
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
28.02.2024, 14:34
Цитата Сообщение от efewfedd Посмотреть сообщение
В первом случае мы присваим укзаателю р значение arr, т е адрес первого элемента массива. А во втором мы делаем тоже самое...
Автор темы очередная жертва ширпотребных книг или статей для начинающих, где заявляют, что массив - это указатель.
0
Заблокирован
28.02.2024, 16:15
Цитата Сообщение от DrOffset Посмотреть сообщение
Автор темы очередная жертва ширпотребных книг или статей для начинающих, где заявляют, что массив - это указатель.
Что довольно странно, даже в С это не так.
Взять хотя бы новую тему про функции с переменным числом аргументов.
Проблема с арифметикой указателей
В С так же нужно использовать макросы.
Откуда всё это берется ? Думаю мусор в тырнете накапливается и не убирается ...
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
28.02.2024, 16:54
Цитата Сообщение от SmallEvil Посмотреть сообщение
Откуда всё это берется ?
Знаю как минимум десяток книг, где про это написано именно так.
0
фрилансер
 Аватар для Алексей1153
6444 / 5637 / 1128
Регистрация: 11.10.2019
Сообщений: 14,997
28.02.2024, 17:39
Цитата Сообщение от SmallEvil Посмотреть сообщение
Откуда всё это берется
оттуда же, откуда и
Цитата Сообщение от commun Посмотреть сообщение
статического массива
0
Заблокирован
28.02.2024, 17:49
Цитата Сообщение от Алексей1153 Посмотреть сообщение
статического массива
Это немного другое ))
Это трактовка. Неправильное название сущностей.
А в данном случае, это совсем другое, это грубая ошибка, из-за незнания, или переноса знаний из одной области в другую, в которой (в переносимой области) человек не разбирается.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12927 / 6795 / 1819
Регистрация: 18.10.2014
Сообщений: 17,193
28.02.2024, 18:11
Лучший ответ Сообщение было отмечено efewfedd как решение

Решение

Цитата Сообщение от efewfedd Посмотреть сообщение
кто-нибудь может объяснять почему.
Ну так - несоответствие типов. Неконстантные ссылки всегда привязываются напрямую. Однако невозможно привязать ссылку одного типа напрямую к объекту другого типа.

Взглянем на совершенно аналогичный по своей сути и структуре пример. Так можно:

C++
1
2
3
int x = 42;
double d = x;
double &r = d;
А вот так - нельзя:

C++
1
2
int x = 42;
double &r = x;
Почему?

Потому что во втором примере ссылку типа double & нельзя привязать к объекту типа int. Это совершенно разные и никак не связанные друг с другом типы. А в первом примере мы сначала неявно преобразовываем значение типа int, кладем результат в объект типа double, а потом привязываем ссылку уже к объекту типа double. Здесь все нормально.

В точности то же самое происходит и в ваших примерах. Вы пытаетесь привязать ссылку типа int *& к объекту типа int [4]. Так нельзя. Это совершенно разные типы, не имеющие ничего общего. Откуда у вас вообще могла возникнуть идея выполнить такую привязку? Зачем?

---

Если бы ссылка была константная (т.е. "на константу"), то тогда и второй пример мог бы работать по схеме первого. Просто создание промежуточного (временного) объекта требуемого типа - для привязки ссылки к нему - делалось бы неявно.

Так можно

C++
1
2
int x = 42;
const double &r = x;
и в вашем случае можно

C++
1
2
int arr[4];
int *const &x = arr;
Но когда ссылка не константная, то такой номер не пройдет из-за несоответствия типов.

Разумеется, еще раз, константная ссылка при этом привязывается не напрямую к правой части (это невозможно), а к промежуточному временному объекту правильного типа.
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
28.02.2024, 20:39
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Ну так - несоответствие типов. Неконстантные ссылки всегда привязываются напрямую. Однако невозможно привязать ссылку одного типа напрямую к объекту другого типа.
3.7. Ссылки
Ссылки были введены в основном для поддержки перегрузки операторов. Дуг
Макилрой вспоминает, что однажды я объяснял ему некоторые проблемы, ка-
савшиеся схемы перегрузки операторов. Он употребил слово «ссылка», после чего
я, пробормотав «спасибо», выбежал из его кабинета, чтобы на следующий день
появиться с практически готовым решением, которое и вошло в язык. Просто Дуг
тогда напомнил мне об Algol68.
В языке C аргументы всегда передаются функции по значению, а в случаях,
когда передача объекта по значению не годится или слишком неэффективна, про-
граммист может передать указатель на объект. При этом нотация должна быть
удобной, поскольку нельзя ожидать, что пользователь всегда будет вставлять опе-
ратор взятия адреса для больших объектов. Так,


a= b - c;

это общепринятая нотация, в то время как

a = &b - &c;

нет. Как бы то ни было, &b - &c уже имело в C определенную семантику, и менять
ее я не хотел.
После инициализации ссылка уже не может ссылаться ни на что другое.
Иными словами, коль скоро она инициализирована, нельзя заставить ее ссы-
латься на другой объект, то есть нельзя изменять привязку. В прошлом меня
неприятно удивил тот факт, что в Algol68 предложение r1=r2 может означать
либо присваивание объекту, на который ссылается r1, либо изменение значе-
ния самой ссылки r1 (повторная привязка) в зависимости от типа r2. Я хотел
уйти от таких проблем в C++.
Если необходимы более сложные манипуляции, всегда можно воспользовать-
ся указателями. Поскольку в C++ есть и ссылки, и указатели, ему не нужны сред-
ства для различения операций над самой ссылкой и операций над объектом, на
который она ссылается (как в Simula). Не нужен и дедуктивный механизм, при-
меняемый в Algol68.
Однако я сделал одну серьезную ошибку, разрешив инициализировать некон-
стантную (без спецификатора const) ссылку значением, не являющимся lvalue.
Например:


C++
1
2
3
4
5
6
7
void incr(int& rr) { rr++; }
void g()
{
  double ss = 1;
  incr(ss); // примечание: передано double, ожидалось int
               // исправлено в версии 2.0
}
Из-за различия типов int& не может ссылаться на переданное значение типа
double, поэтому генерировалась временная переменная для хранения значения
типа int, инициализированная значением ss. В связи с этим функция incr мо-
дифицировала данную временную переменную, а вызывающая функция получа-
ла неизмененное значение.
Я разрешил инициализировать ссылки нееlvalue, чтобы сделать различие
между вызовом по значению и по ссылке деталью реализации вызываемой функ-
ции, которая вызывающей вообще неинтересна. Для константных ссылок это воз-
можно, для неконстантных – нет. В версии 2.0 определение C++ было соответ-
ствующим образом изменено.
Следует отметить, что константную ссылку можно инициализировать не lvalue,
а также lvalue, для типа которой требуется преобразование. В частности, это по-
зволяет вызывать написанную на Fortran функцию с аргументом-константой:

C++
1
2
3
4
5
extern "Fortran" float sqrt(const float&);
void f()
{
  sqrt(2); // вызов с передачей аргумента по ссылке
}
Помимо очевидных применений ссылок (для передачи аргументов), мы счи-
тали важной возможность использовать ссылки как возвращаемые значения. Это
позволило легко написать оператор взятия индекса для класса String:

C++
1
2
3
4
5
class String {
  // ...
  char& operator[](int index); // оператор взятия индекса
  // возвращает ссылку
};
C++
1
2
3
4
5
6
void f(String& s, int i)
{
  char c1 = s[i]; // присвоить результат operator[]
  s[i] = c1;       // присвоить результату operator[]
  // ...
}
Возврат ссылки на внутреннее представление String предполагает, что пользо-
ватели ведут себя ответственно.


Бьерн Страуструп
Дизайн и эволюция С++
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
28.02.2024, 20:39
Помогаю со студенческими работами здесь

int *arr или int arr[10]
Подскажите, корректно ли использовать для объявления массива или строки int *arr; char *srt; Так же и некоторые переменные...

Объявление массива int *arr почему так
Объявление массива int *arr почему так, а не int arr, что означает *

Нюансы синтаксиса: что значит запись const vector<int>&a и vector<int>&a при передаче в функцию vector<int>sort?
Увидел запись const vector&lt;int&gt;&amp;a при передаче в функцию и хотелось бы понять её значение и как она влияет на (изначальный) массив, который...

Как считать данные в vector<pair<int, pair<int, int>>> arr(m) ?
Здравствуйте! Помогите, как считать данные данные в массив такого типа? vector&lt;pair&lt;int, pair&lt;int, int&gt;&gt;&gt; arr(m) Пытался...

Как можно увеличить размер вектора, который является элементом вектора vector<vector<int>>arr(n, vector <int>)
Написал программу, которая создает вектор 'а' векторов 'b', вектора 'b' содержат 2 числа. Стало интересно, как нужно изменить программу...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка. Рецензия / Мнение/ Перевод https:/ / **********/ gallery/ thinkpad-x220-tablet-porn-gzoEAjs . . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru