Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.93/56: Рейтинг темы: голосов - 56, средняя оценка - 4.93
0 / 0 / 0
Регистрация: 31.07.2014
Сообщений: 24

Имя массива в С++ это указатель или ссылка?

12.06.2020, 14:18. Показов 13851. Ответов 133
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Пытаюсь понять что такое имя массива в С++! Указатель или ссылка? Сразу скажу что пока рассматриваю только статические массивы.
Теория говорит что это указатель, собственно поэтому для имени массива применима арифметика указателей.
Но! раз это указатель, то значит это переменная под которую компилятор выделил ячейку памяти в которой должен храниться адрес первого элемента массива arr[0]. Раз такая ячейка памяти есть то по идее можно узнать ее адрес так - &arr!
К сожалению такой трюк не работает и получается что &arr==arr! Для меня это никак не укладывается под описание указателя.

Попробовал выяснить по аналогии с простой переменной что такое указатель, а что такое ссылка!
Вот простенький код для простой переменной и результат его выполнения:
Кликните здесь для просмотра всего текста
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
        int a = 10;
    int* b = &a;
    int** c = &b;
    cout << "Указатели" << endl;
    cout << "ТИП" << "\t\t" << "int" << "\t" << "int*" << "\t\t" << "int*" << "\t\t" << "int" << "\t" << "int**" << "\t\t" << "int**" << "\t\t" << "int*" << "\t\t" << "int" << endl;
    cout << "ОПЕРАЦИЯ" << "\t" << "a" << "\t" << "&a" << "\t\t" << "b = &a" << "\t\t" << "*b" << "\t" << "&b" << "\t\t" << "c = &b" << "\t\t" << "*c" << "\t\t" << "**c" << endl;
    cout << "Значение" << "\t" << a << "\t" << &a << "\t" << b << "\t" << *b << "\t" << &b << "\t" << c << "\t" << *c << "\t" << **c << endl << endl;
 
    cout << "Ссылки" << endl;
    int& d = a;
    int* e = &d;
    cout << "ТИП" << "\t\t" << "int&" << "\t" << "\t" << "\t" << "int*" << "\t\t" << "int" << "\t" << "int*" << endl;
    cout << "ОПЕРАЦИЯ" << "\t" << "d" << "\t" << "&d" << "\t\t" << "e = &d" << "\t\t" << "*e" << "\t" << "&e" << endl;
    cout << "Значение" << "\t" << d << "\t" << &d << "\t" << e << "\t" << *e << "\t" << &e << endl;


Результат говорит о том что если переменная "b" - указатель на переменную "a", то переменная b находится в памяти по адресу &b и содержит значение адреса переменной a равное &a. Все вполне согласуется с теорией.
Если же переменная "d" - ссылка на переменную "a", то для переменной b вроде как не выделяется памяти, по крайней мере собственного адреса в памяти для переменной d нет и операция &d дает лишь адрес переменной a.

Если поступить аналогично с массивом?
Кликните здесь для просмотра всего текста
Code
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
        const int size = 10;
    int arr[size] = {0,1,2,3,4,5,6,7,8,9};
    int* pArr = arr;
 
    void* a = &arr;         // студия ругается на cout << *a
    void** c = &a;          // студия ругается на cout << **с
    void* d = &a;           // студия ругается на cout << *d
 
    void* b = &pArr;
    void** e = &b;
    void* f = &b;
 
    cout << "arr + i" << "\t\t" << "arr[i]" << "\t" << "*(arr + i)" << "\t" << "&arr" << "\t\t" << "a = &arr" << "\t" << "&a" << "\t\t" << "c = &a" << "\t\t" << "d = &a" << "\t\t" << "*c" << endl;
    
    for (int i = 0; i < 10; i++)
    {
    cout << arr + i << "\t" << arr[i] << "\t" << *(arr + i) << "\t\t" << &arr << "\t" << a << "\t" << &a << "\t" << c << "\t" << d << "\t" << *c << endl;
    }
    
    cout << "pArr + i" << "\t" << "pArr[i]" << "\t" << "*(pArr + i)" << "\t" << "&pArr" << "\t\t" << "b = &pArr" << "\t" << "&b" << "\t\t" << "e = &b" << "\t\t" << "f = &b" << "\t\t" << "*e" << endl;
 
    for (int i = 0; i < 10; i++)
    {
    cout << pArr + i << "\t" << pArr[i] << "\t" << *(pArr + i) << "\t\t" << &pArr << "\t" << b << "\t" << &b << "\t" << e << "\t" << f << "\t" << *e << endl;
    }


Если объявить указатель pArr на массив arr, то видно что для pArr аналогично указателю простой переменной выделяется место в памяти с адресом &pArr в которой содержится адрес первого элемента массива arr[0]. Все как бы укладывается в мои представления.
А что же с именем массива? Ведь утверждается что это указатель на 1й элемент этого массива arr[0].
Операция &arr дает адресс такой же как и у первого элемента массива, как будто нет никакого указателя а есть ссылка по аналогии с обычной переменной!
Но почему же тогда для имени массива доступна арифметика указателя? для обычной ссылки такого ведь нет.
В последнем примере все указатели имеют тип void* (не знаю насколько это корректно), поэтому думаю что корректней следующий код, но результат тот же самый! Имя массива как будто является ссылкой а не указателем.
Кликните здесь для просмотра всего текста
Code
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
const int size = 10;
    int arr[size] = {0,1,2,3,4,5,6,7,8,9};
 
    int* pArr = arr;
 
    int(*a)[size] = &arr;
    int(**c)[size] = &a;
    
    int** b = &pArr;
    int*** e = &b;
    
    cout << "arr + i" << "\t\t" << "arr[i]" << "\t" << "*(arr + i)" << "\t" << "a = &arr" << "\t" << "*a" << "\t\t" << "c = &a" << "\t\t" << "*c" << "\t\t" << "**c" << endl;
    
    for (int i = 0; i < 10; i++)
    {
    cout << arr + i << "\t" << arr[i] << "\t" << *(arr + i) << "\t\t" << a << "\t" << *a << "\t" << c << "\t" << *c << "\t" << **c << endl;
    }
    
    cout << endl;
    cout << "pArr + i" << "\t" << "pArr[i]" << "\t" << "*(pArr + i)" << "\t" << "b = &pArr" << "\t" << "*b" << "\t\t" << "**b" << "\t\t" << "e = &b" << "\t\t" << "*e" << endl;
 
    for (int i = 0; i < 10; i++)
    {
        cout << pArr + i << "\t" << pArr[i] << "\t" << *(pArr + i) << "\t\t" << b << "\t" << *b << "\t" << **b << "\t\t" << e << "\t" << *e << "\t" << endl;
    }



У меня такое представление об указателях, что это переменная которая в памяти имеет собственное место т.е. имеет свой адрес и содержит адрес переменной на которую указывает. примерно как на следующем рисунке:


Все же объясните что такое имя массива? указатель или ссылка? или у меня неправильное представление об этих вещах?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
12.06.2020, 14:18
Ответы с готовыми решениями:

Указатель или ссылка на указатель. В чем разница?
Есть вопрос про указатели и ссылки на указатели :scratch: Хочу в функциях f1() и в f2() динамически выделить память и возвратить этот...

Указатель на константную строку и имя массива как указатель
Изучаю C. У меня есть указатель на константную строку, и я хочу его изменить путем передачи в функцию. Это работает без проблем: ...

Ссылка на объект в памяти и указатель это одно и тоже?
Разобрался со смыслом различий значимых типов и ссылочных типов, а так же с особенностями их передачи через ref и out. Но не понятно...

133
Неэпический
 Аватар для Croessmah
18150 / 10732 / 2067
Регистрация: 27.09.2012
Сообщений: 27,047
Записей в блоге: 1
12.06.2020, 20:35
Студворк — интернет-сервис помощи студентам
cahmep, могу посоветовать взглянуть книжечку "Структуры данных в C++" за авторством Уильяма Топпа и Уильяма Форда. Где-то вначале (емнип), как раз объясняется, что массив - это не указатель. Объясняется весьма просто и понятно. И других полезностей там много. Для начинающего самое то.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
12.06.2020, 20:40
Цитата Сообщение от Croessmah Посмотреть сообщение
Все темы с вопросом "массивы и указатели" превращаются в свалку.
Они к сожалению располагают. По природе своей. Попробуйте обьъяснить новичку почему разыменование указателя на массив вообще допустимо. Тип же составной. И почему разыменование даёт указатель опять же. Должно же быть значение массива (а мы понимаем что это не реально).
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
using namespace std;
 
int main()
{
    int a[]={1,2,3};
 
    typedef  int(*pTArray)[3] ;
    pTArray pa = &a ;
    cout<<(*pa)[0]<<' '<<(*pa)[1]<<' '<<(*pa)[2]<<endl;//ok  
    cout<<pa[0]<<' '<<pa<<' '<<(*pa)<<endl;//dereferece of array pointer is a strange thing
return 0;
}
То есть у преподавателей С++ всегда будет работа.
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
12.06.2020, 20:50
Цитата Сообщение от IGPIGP Посмотреть сообщение
И почему разыменование даёт указатель опять же.
Разыменование дает массив. Который потом преобразуется к указателю.

Добавлено через 3 минуты
Цитата Сообщение от IGPIGP Посмотреть сообщение
Должно же быть значение массива
Должно, и есть.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
using namespace std;
 
int main()
{
    int a[]={1,2,3};
 
    typedef  int(*pTArray)[3] ;
    pTArray pa = &a ;
    cout<<(*pa)[0]<<' '<<(*pa)[1]<<' '<<(*pa)[2]<<endl;//ok  
    cout<<sizeof(pa[0])<<' '<<sizeof(pa)<<' '<<sizeof(*pa)<<endl;
    return 0;
}
Если бы это был указатель, то sizeof бы вам вернул размер указателя, но он возвращает размер массива в байтах. Это происходит потому, что sizeof не вводит контекст, при котором массив начнет неявно преобразовываться к указателю.
1
248 / 70 / 9
Регистрация: 22.07.2018
Сообщений: 321
12.06.2020, 20:52
Цитата Сообщение от IGPIGP Посмотреть сообщение
юди пишущие стандарт не считают слова достойными вниманию объектами тут комментарии излишни. А это позволяет вам и кому-либо еще, делать тыц
Интересно, у тебя самого есть представление о том, что ты хочешь сказать?
Цитата Сообщение от IGPIGP Посмотреть сообщение
Вы же не различаете указатель как объкект и его значение
Што? В каком месте?
Цитата Сообщение от IGPIGP Посмотреть сообщение
Я не писал о том что такое тип указателя
А я где-то говорил обратное?

Цитата Сообщение от IGPIGP Посмотреть сообщение
адрес это алгебраическое (арифметическое) значение указателя
Цитата Сообщение от IGPIGP Посмотреть сообщение
адрес это Часть значения.
Т.е. у значения указателя несколько частей, одна часть "арифметическая" и называется "адрес"? Откуда ты это берёшь? И какие другие части, как они называются?

Цитата Сообщение от Undisputed Посмотреть сообщение
тогда что вы скажете насчет этого?
Нужно фиксить вординг, вот и всё.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
12.06.2020, 20:53
Цитата Сообщение от DrOffset Посмотреть сообщение
Разыменование дает массив. Который потом преобразуется к указателю.
Вот-вот. Попробуйте это объяснить без свалки. В том-то и дело, что сначала людям говорят о том, что разыменование указателя возвращает ссылку. У массивов это сразу вызывает преобразование в указатель.
0
248 / 70 / 9
Регистрация: 22.07.2018
Сообщений: 321
12.06.2020, 20:54
Цитата Сообщение от IGPIGP Посмотреть сообщение
Попробуйте обьъяснить новичку почему разыменование указателя на массив вообще допустимо. Тип же составной.
Для начала придётся объяснить, как составность типа должна мешать разыменованию.
Цитата Сообщение от IGPIGP Посмотреть сообщение
разыменование даёт указатель опять же
0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
12.06.2020, 20:55
argcargv,
А в каком направлении фиксить и почему?
Нужно изменить описание addressof, или может добавить в список значения указателей ещё и адрес?
0
248 / 70 / 9
Регистрация: 22.07.2018
Сообщений: 321
12.06.2020, 20:56
Цитата Сообщение от Undisputed Посмотреть сообщение
А в каком направлении фиксить и почему?
Нужно изменить описание addressof
Да.
0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
12.06.2020, 20:56
И все таки, при текущем положении, есть ли в том коде UB?
0
Неэпический
 Аватар для Croessmah
18150 / 10732 / 2067
Регистрация: 27.09.2012
Сообщений: 27,047
Записей в блоге: 1
12.06.2020, 20:56
cahmep, слушай DrOffset - польза будет.

Я вот слушаю его, и даже че-та умею. Когда не слушаю - не умею.
1
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
12.06.2020, 20:57
argcargv,
А почему например не добавить новое значение в список допустимых? Мне просто интересно как вы определили правильный вариант
0
248 / 70 / 9
Регистрация: 22.07.2018
Сообщений: 321
12.06.2020, 20:58
Цитата Сообщение от Undisputed Посмотреть сообщение
И все таки, при текущем положении, есть ли в том коде UB?
Думаю, устаревший вординг это не повод считать поведение неопределённым.
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
12.06.2020, 20:58
Цитата Сообщение от DrOffset Посмотреть сообщение
Если бы это был указатель, то sizeof бы вам вернул размер указателя
DrOffset, вам кажется что тот факт, что sizeof получает объект, а сдвиг в поток - указатель кажется логичным. Каждый кто давно это знает не видит проблем. А человек который пытается применить логику (системно анализировать) имеет ощущения. Я об этом.
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
12.06.2020, 20:58
Цитата Сообщение от IGPIGP Посмотреть сообщение
В том-то и дело, что сначала людям говорят о том, что разыменование указателя возвращает ссылку. У массивов это сразу вызывает преобразование в указатель.
Нет не сразу, а только в контексте определенных выражений.
0
248 / 70 / 9
Регистрация: 22.07.2018
Сообщений: 321
12.06.2020, 21:00
Цитата Сообщение от IGPIGP Посмотреть сообщение
В том-то и дело, что сначала людям говорят о том, что разыменование указателя возвращает ссылку
"Разыменование" это применение унарного оператора *? Во-первых, оно ничего не "возвращает", ну да ладно, это придирка, а во вторых — не ссылку. Так что те, кто говорит про ссылку, просто безграмотны.
0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
12.06.2020, 21:01
argcargv,
Может попустили мой вопрос, продублирую
Имя массива в С++ это указатель или ссылка?
0
248 / 70 / 9
Регистрация: 22.07.2018
Сообщений: 321
12.06.2020, 21:01
Цитата Сообщение от Undisputed Посмотреть сообщение
А почему например не добавить новое значение в список допустимых? Мне просто интересно как вы определили правильный вариант
Ну попробуй добавить и посмотри, что на это скажут.
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
12.06.2020, 21:02
Цитата Сообщение от IGPIGP Посмотреть сообщение
сдвиг в поток - указатель кажется логичным.
"Сдвиг в поток" получает указатель, потому что он только указатель и запрашивает. Т.е. не существует перегрузки "сдвига в поток", которая принимала бы не указатель.
Если вы напишете такую перегрузку, то никакого преобразования в указатель не будет.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13233 / 6865 / 1827
Регистрация: 18.10.2014
Сообщений: 17,398
12.06.2020, 21:02
Цитата Сообщение от IGPIGP Посмотреть сообщение
ни к сожалению располагают. По природе своей. Попробуйте обьъяснить новичку почему разыменование указателя на массив вообще допустимо. Тип же составной.
???

У кого это, интересно, может возникнуть такой вопрос? Указатели на структуры вроде новички успешно разыменовывают и ничего удивительного в этом не видят, хоть "тип же составной". Указатель на массив здесь ничем не отличается.

Цитата Сообщение от IGPIGP Посмотреть сообщение
И почему разыменование даёт указатель опять же.
Нет, конечно.

Разыменование указателя на массив дает lvalue типа "массив", а никакой не "указатель опять же". А далее это lvalue типа "массив" обрабатывается по общим правилам для любых массивов. Получится ли после этого "указатель опять же" - целиком зависит от контекста.

Цитата Сообщение от IGPIGP Посмотреть сообщение
А человек который пытается применить логику (системно анализировать) имеет ощущения.
0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
12.06.2020, 21:04
argcargv,
Так это был просто вопрос... У тебя есть на него ответ?
Ведь утверждение исходит от тебя... Было бы круто, если бы именно ты на него ответил, так же как отвечал на остальные вопросы...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
12.06.2020, 21:04

как такое правильно писать? это ссылка на указатель?
#include &lt;iostream&gt; using namespace std; char *chch2 = &quot;hello&quot;; char*&amp; f() { char *&amp;chch3 = chch2; return...

Что лучше ссылка или указатель?
Что лучше - ссылка или указатель?

Не удалось найти имя типа или пространства имен пропущена директива using или ссылка на сборку
Доброе время суток.Есть код: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace...

Как ускорить работу. Ссылка или указатель
У меня следующая ситуация. Обработка изображений с EMGUCV. Объект Image весит очень много. Этот объект надо передавать в мой класс. ...

Имя массива как указатель
Используя имя массива как указатель, и применяя адресную арифметику выполнить задание (каждое задание оформить отдельной функцией). Дан...


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

Или воспользуйтесь поиском по форуму:
100
Ответ Создать тему
Новые блоги и статьи
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru