Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.94/34: Рейтинг темы: голосов - 34, средняя оценка - 4.94
25 / 25 / 19
Регистрация: 13.07.2015
Сообщений: 433

Почему при присваивании адреса массива не ставится знак '&' получения адреса

22.11.2015, 21:01. Показов 7574. Ответов 88
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
C++
1
2
3
4
5
6
7
8
9
10
int main()
{
    int a[2] = { 2, 3 };
    int* b;
    b = a; //Почему при присваивании адреса массива не ставится знак '&' получения адреса.
//А когда присваиваешь адрес отдельной переменной, то необходимо ставить этот знак.
//int a=2;
    int* b;
    b = &a;//
}
И ещё адрес массива из пяти элементов передаст указателю все пять элементов? От адреса первого [0] до адреса последнего [4]. То есть, после такого присвоения указатель будет иметь все 5 адресов?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
22.11.2015, 21:01
Ответы с готовыми решениями:

Операция получения адреса & и vector
Здравствуйте. Работает ли Операция получения адреса (&) в векторе? Просто есть пример в книги, но про вектор ничего не сказано....

1. Ввести символьный массив. Найти адреса всех парных его элементов. 2. Вывести адреса элементов массива 4 на 4, находящ
Помогите пж... 1. Ввести символьный массив. Найти адреса всех парных его элементов. 2. Вывести адреса элементов массива 4 на 4,...

Почему разные адреса одного и того же элемента динамического массива?
Я создаю динамический массив и отправляю его в функцию, если потом сравнивать адреса элементов массива в главной и вызываемой функции они...

88
14 / 14 / 1
Регистрация: 14.03.2015
Сообщений: 113
22.11.2015, 21:07
В C++ использование имени массива без индекса образует указатель на первый элемент массива.
Вот
0
Диссидент
Эксперт C
 Аватар для Байт
27714 / 17332 / 3810
Регистрация: 24.12.2010
Сообщений: 38,978
22.11.2015, 21:57
Цитата Сообщение от Aqua77 Посмотреть сообщение
Почему при присваивании адреса массива не ставится знак '&' получения адреса
Массив - он уже сам адрес.
Упрощенно так. int mass[2] создает кусок памяти для хренения 2-х целых и переменную - адрес этой памяти. (эксперты, возможно. скажут, что это не совсем так, но тебе лучше сейчас представлять дело именно таким образом). Так что mass - это уже указатель(адрес). Присваивание int *b = mass имеет дело с сущностями одной природы.
Цитата Сообщение от Aqua77 Посмотреть сообщение
//А когда присваиваешь адрес отдельной переменной, то необходимо ставить этот знак.
Надеюсь, из вышеизложенного все уже понятно.
Цитата Сообщение от Aqua77 Посмотреть сообщение
И ещё адрес массива из пяти элементов передаст указателю все пять элементов?
Конечно нет! Он дает указатель только на первый элемент (адрес, где начинается массив). А про его длину он ничего не знает и знать не хочет. И в этом все прелести и все опасности языка Си.
Цитата Сообщение от Aqua77 Посмотреть сообщение
То есть, после такого присвоения указатель будет иметь все 5 адресов?
Надеюсь, что ответ на этот вопро уже понятен. Но доступ ко всем пяти элементам построен.
*b, *(b+4), *(b+100) - а вот тут ты уже обращаешься неизвестно куда. И программа твоя крашится.
Кстати, надо понять, что &a[5] абсолютно тоже самое, что и *(a+5)
1
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
22.11.2015, 22:02
Цитата Сообщение от Байт Посмотреть сообщение
ак что mass - это уже указатель(адрес).
Он неявно приводится к указателю на первый элемент.
Если бы "b" была указателем на массив, то пришлось бы использовать "&" для взятия адреса массива:
C++
1
2
    int a[2] = { 2, 3 };
    int(*b)[2] = &a;
1
22.11.2015, 22:08

Не по теме:

Цитата Сообщение от Croessmah Посмотреть сообщение
Если бы "b" была указателем на массив,
Слушай, не путай парня, а? Ты еще расскажи ему чем указатель на указатель на указатель отличается от просто указателя на указатель. И так - рекурсивно, пока голова не закружится. А ведь похоже, человек и правда пытается разобраться. Вот разберется - он тебе покажет, кошаку вредному:)

0
22.11.2015, 22:16

Не по теме:

Цитата Сообщение от Байт Посмотреть сообщение
Слушай, не путай парня, а?
Ок. Тогда еще покажем ссылку на массив:
C++
1
2
    int a[2] = { 2, 3 };
    int(&b)[2] = a;
Я ж вредный :)
Вот разберется - он тебе покажет, кошаку вредному
да ладно, я ж как лучше :)

0
6 / 6 / 2
Регистрация: 06.01.2015
Сообщений: 180
22.11.2015, 22:36
В случае с массивом, его имя является указателем. На самом деле такой формат mas[i] упрощение такого *(mas+i). Если просто написать *mas, то будем ссылаться на первый элемент так как *(mas+0). В памяти элементы массива распределяются друг за другом, компилятор определяет какого типа данные в массиве и когда мы пишем *(mas+i), он как бы доумножает это i на кол-во байт, выделяемых под каждый элемент. Если массив целых чисел, адреса будут отличать на 4 байта. Так суммируя адреса он доходит до нужного и просто разыменовывает его. То есть, если писать mas+i мы будем получать адреса элементов, что эквивалентно &mas[i].
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
22.11.2015, 22:39
Цитата Сообщение от Apparat_UA Посмотреть сообщение
В случае с массивом, его имя является указателем.
пост 4!
1
6 / 6 / 2
Регистрация: 06.01.2015
Сообщений: 180
22.11.2015, 23:03
Цитата Сообщение от Croessmah Посмотреть сообщение
Он неявно приводится к указателю на первый элемент.
Если бы "b" была указателем на массив, то пришлось бы использовать "&" для взятия адреса массива
Спасибо. Где можно поподробнее почитать об этом ?
0
Диссидент
Эксперт C
 Аватар для Байт
27714 / 17332 / 3810
Регистрация: 24.12.2010
Сообщений: 38,978
22.11.2015, 23:20
Цитата Сообщение от Apparat_UA Посмотреть сообщение
Где можно поподробнее почитать об этом ?
Цитата Сообщение от Croessmah Посмотреть сообщение
Он неявно приводится к указателю на первый элемент.
Вечер поздний, спать неохота, а делать нечего. Давай попробуем этот момент разжевать. Пока кашей не станет.
На все объявленные в функции переменные (и параметры тож) в памяти выделяется некоторая область (стек называется, но - не суть). И в странслированной функции этот адрес есть (ей известен). И поэтому известны ей адреса всех переменных. Вот "int *b" выделяет кусочек памяти. А "int mass[2]" выделяет память только на массив. А указатель на этот массив ей не нужен. Он известен. Он - константа. И просто присутствует как таковая в сгенерированных командах. Вот и все. И самое сложное - это понять, что на самом деле все чрезвычайно просто
3
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
22.11.2015, 23:25
Apparat_UA, можно почитать тему, начиная с сообщения Ссылка на массив
1
22.11.2015, 23:39

Не по теме:

Croessmah, у меня зреет тема о том, как надо учить студиоузов. На первой лекции рассказать о чрезвычайной простоте и убогости вычислительной машины. О том, что она умеет делать только очень примитивные операции. И только то, что этих операций миллионы и выполняются они со скоростью миллиардов в секунду делает наш мир столь "прекрасным"

0
25 / 25 / 19
Регистрация: 13.07.2015
Сообщений: 433
23.11.2015, 10:07  [ТС]
Цитата Сообщение от Байт Посмотреть сообщение
&a[5] абсолютно тоже самое, что и *(a+5)
&a[5] - это адрес 6-го элемента а *(a+5) Значение элемента?

Добавлено через 15 минут
Цитата Сообщение от Apparat_UA Посмотреть сообщение
компилятор определяет какого типа данные в массиве и когда мы пишем *(mas+i), он как бы доумножает это i на кол-во байт, выделяемых под каждый элемент.
То есть если массив типа int, и я хочу обратится к 5-тому элементу компилятор зная что один элемент типа int содержит 4 байта умножает 4 на 5.
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
23.11.2015, 10:41
Цитата Сообщение от Aqua77 Посмотреть сообщение
&a[5] - это адрес 6-го элемента а *(a+5) Значение элемента?
Да. Только для исключения путаницы, предпочтительнее писать не "6-го элемента", а "элемента с индексом 5", имхо.
Цитата Сообщение от Aqua77 Посмотреть сообщение
компилятор зная что один элемент типа int содержит 4 байта умножает 4 на 5.
Снова да Именно поэтому опасно в указателе на базовый класс хранить адрес начала массива класса производного.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
 
struct B {
    int i;
};
 
struct D : B {
    int j;
};
 
int main()
{
    D d[3];
    
    d[0].i = 1;
    d[0].j = 2;
    
    d[1].i = 3;
    d[1].j = 4;    
    
    d[2].i = 5;
    d[2].j = 6; 
    
    B* b = d; 
 
    std::cout << b[0].i << std::endl; // 1, ok
 
    std::cout << b[1].i << std::endl; // 2, но хотели бы 3
    
    std::cout << b[2].i << std::endl; // 3, но хотели бы 5   
}
http://coliru.stacked-crooked.... 1d7731aee2
0
23.11.2015, 11:58

Не по теме:

Цитата Сообщение от Байт Посмотреть сообщение
На первой лекции рассказать о чрезвычайной простоте и убогости вычислительной машины. О том, что она умеет делать только очень примитивные операции. И только то, что этих операций миллионы и выполняются они со скоростью миллиардов в секунду делает наш мир столь "прекрасным"
Поздно. В какой-то книге я уже видел этот подход :)

0
Модератор
Эксперт CЭксперт С++
 Аватар для sourcerer
5288 / 2376 / 342
Регистрация: 20.02.2013
Сообщений: 5,773
Записей в блоге: 20
23.11.2015, 12:37
Aqua77, у Дейтелов в книжке "Как программировать на C++" (2008), в 8 главе (стр. 534):
Цитата Сообщение от Харви М. Дейтела и Пола Дж. Дейтела
Предположим, сделаны следующие объявления:
C++
1
2
int b[5]; // создать 5-элементный целый массив b
int *bPtr; // создать указатель на целое bPtr
Так как имя массива (без индекса) является указателем (константным) на его
первый элемент, мы можем присвоить указателю bPtr адрес первого элемента
массива b при помощи оператора присваивания
C++
1
bPtr = b;
Этот оператор эквивалентен следующему, в котором используется операция
взятия адреса первого элемента массива:
C++
1
bPtr = &b[0];
Альтернативный способ ссылки на элемент массива b[3], использующий
выражение с указателем, представлен в следующем операторе:
C++
1
*(bPtr + 3)
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
23.11.2015, 12:40
Цитата Сообщение от gru74ik Посмотреть сообщение
Так как имя массива (без индекса) является указателем (константным) на его
первый элемент
еще раз:
4.2 Array-to-pointer conversion
1. An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to a prvalue of type “pointer to T”. The result is a pointer to the first element of the array.
0
Модератор
Эксперт CЭксперт С++
 Аватар для sourcerer
5288 / 2376 / 342
Регистрация: 20.02.2013
Сообщений: 5,773
Записей в блоге: 20
23.11.2015, 13:19
Croessmah, то есть, у Дейтелов ошибка?
0
23.11.2015, 13:30

Не по теме:

У переводчиков ошибка скорее всего. Надо в оригинале смотреть для подстраховки. Там много очепяток и неточностей.

0
Модератор
Эксперт CЭксперт С++
 Аватар для sourcerer
5288 / 2376 / 342
Регистрация: 20.02.2013
Сообщений: 5,773
Записей в блоге: 20
23.11.2015, 13:41
Или, скажем так, упрощение?

Добавлено через 10 минут
У Праты вот:
Цитата Сообщение от Стивен Прата
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// addpntrs.cpp -- pointer addition
#include <iostream>
int main()
{
    using namespace std;
    double wages[3] = {10000.0, 20000.0, 30000.0};
    short stacks[3] = {3, 2, 1};
 
// Here are two ways to get the address of an array
    double * pw = wages;     // name of an array = address
    short * ps = &stacks[0]; // or use address operator
// with array element
    cout << "pw = " << pw << ", *pw = " << *pw << endl;
    pw = pw + 1;
    cout << "add 1 to the pw pointer:\n";
    cout << "pw = " << pw << ", *pw = " << *pw << "\n\n";
 
    cout << "ps = " << ps << ", *ps = " << *ps << endl;
    ps = ps + 1;
    cout << "add 1 to the ps pointer:\n";
    cout << "ps = " << ps << ", *ps = " << *ps << "\n\n";
 
    cout << "access two elements with array notation\n";
    cout << "stacks[0] = " << stacks[0] 
         << ", stacks[1] = " << stacks[1] << endl;
    cout << "access two elements with pointer notation\n";
    cout << "*stacks = " << *stacks
         << ", *(stacks + 1) =  " << *(stacks + 1) << endl;
 
    cout << sizeof(wages) << " = size of wages array\n";
    cout << sizeof(pw) << " = size of pw pointer\n";
    // cin.get();
    return 0; 
}
В большинстве контекстов C++ интерпретирует имя массива как адрес его
первого элемента. Таким образом, следующий оператор создает pw как указатель на тип
double, затем инициализирует его wages, который также является адресом первого
элемента массива wages:
C++
1
double * pw = wages;
Для wages, как и любого другого массива, справедливо следующее утверждение:
C++
1
wages = &wages[0] = адрес первого элемента массива
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
23.11.2015, 13:41
Помогаю со студенческими работами здесь

Почему адреса элементов массива находятся в памяти не по порядку
Приветствую! Подскажите пожалуйста почему адреса элементов массива находятся в памяти не по порядку? почему и где происходит изменение...

Ошибка получения ip-адреса
Всем доброго времени суток) Возникла проблема, вот, собственно она: имеется стационарник с прямым подключением к интернету, к нему через...

Определить тип получения IP-адреса
Доброго дня. Подскажите пожалуйста: Необходимо определить, получен ли ip адрес по DHCP или прописан вручную. Надо парсить вывод команды...

Почему при редактировании ip-адреса NetworkManager создаёт второе соединение?
На Ubuntu Sevrer 16.04 LTS поставил NetworkManager. Включил его. Перезагрузил. Отредактировал ip-адрес. Перезагрузил. Смотрю, две...

Получения адреса объекта вызвавшего события
Всем доброго дня уважаемые форумчане. Ситуация в следующим, во время выполнения программы динамически создаются кнопке на форме...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru