Форум программистов, компьютерный форум, киберфорум
Наши страницы
C для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Papayaved
75 / 75 / 8
Регистрация: 24.09.2015
Сообщений: 335
1

На что указывает указатель на массив?

28.06.2018, 12:20. Просмотров 313. Ответов 21
Метки нет (Все метки)

На что указывает указатель на массив? С указателем на первый элемент все понятно - он указывает на первый элемент массива, но более точно было бы сказать, что это указатель на массив

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
unsigned char buf[1518];
 
typedef struct {
    ...
    unsigned char (* p_data)[1518];
} Packet;
 
Packet packet;
 
void Parse(unsigned char buf[1518]) {
    ... // Parse packet
   packet.p_data = &buf;
}
 
void func(unsigned char value) {
    (*packet.p_data)[42] = value;
}
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.06.2018, 12:20
Ответы с готовыми решениями:

Что такое указатель на массив и как им пользоваться?
Всем привет! Нужна информация по сабжу, как объявлять, и что вообще...

Указатель на массив строк - В функции Test печатается непонятно что из памяти
Здравствуйте, Есть часть кода(см. ниже). Объясните, почему в функции Test...

Почему нельзя двумерный массив преобразовывать в указатель на указатель?
Имеем массив: int daytab; при передаче его в функции количество столбцов...

Функция сохраняет кое что в бинарник, но проблема в том что указатель на файл все время оказывается пустой
у меня функция сохраняет кое что в бинарник, но проблема в том что указатель на...

Не могу через указатель на двумерный массив вернуть все значения в другой массив
Не могу через указатель на двумерный массив вернуть все значения в другой...

21
Croessmah
++Ͻ
14944 / 8536 / 1628
Регистрация: 27.09.2012
Сообщений: 21,017
Записей в блоге: 2
Завершенные тесты: 1
28.06.2018, 20:08 2
Цитата Сообщение от Papayaved Посмотреть сообщение
На что указывает указатель на массив?
Не поверишь, на массив.

Цитата Сообщение от Papayaved Посмотреть сообщение
packet.p_data = &buf;
И здесь вовсе не то, что Вы ожидаете.
И, емнип, даже не скомпилируется.
0
Papayaved
75 / 75 / 8
Регистрация: 24.09.2015
Сообщений: 335
28.06.2018, 22:28  [ТС] 3
Croessmah, какой адрес содержит указатель? Чем должен инициализироваться указатель на массив?

У меня компилируется именно такой код, по другому такой указатель без приведения типов не инициализировать - пока правда не тестировал в деле, пишу ответную часть на C#.

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

Добавлено через 9 минут
У меня есть мысль, что пока на константный указатель (имя массива) ни кто не ссылается (не берет его адрес), то компилятор его не создает в памяти, а если берется его адрес, то для статического массива будет создан указатель на массив, как у динамических массивов в С++
0
ValeryS
Модератор
7446 / 5638 / 716
Регистрация: 14.02.2011
Сообщений: 19,207
Завершенные тесты: 1
28.06.2018, 22:51 4
имя массива это и есть указатель на массив, точнее на его первый элемент
а вот указатель на массив в таком вот аспекте
Цитата Сообщение от Papayaved Посмотреть сообщение
packet.p_data = &buf;
это указатель на указатель
Цитата Сообщение от Papayaved Посмотреть сообщение
У меня есть мысль, что пока на константный указатель (имя массива) ни кто не ссылается (не берет его адрес), то компилятор его не создает в памяти,
неправильная мысль, иначе бы не работали всякие табличные методы

Добавлено через 4 минуты
чтобы показать что имя и указатель это одно и тоже
попробуй вот так
C
1
2
3
4
int arr[]={1,2,3};
 
int a=arr[0];// здесь в a 1 работаем через элемент массива
int b=*arr; // здесь в b тоже 1, работаем через указатель
0
Papayaved
75 / 75 / 8
Регистрация: 24.09.2015
Сообщений: 335
28.06.2018, 22:59  [ТС] 5
ValeryS, для статических массивов место под указатель в памяти не отводится обычно, а так же

C
1
sizeof(array);
возвращает не размер указателя. Статический массив - это отдельный тип с некоторой совместимостью с указателями

Добавлено через 1 минуту
ValeryS, но
C
1
array++;
не будет работать

Добавлено через 3 минуты
Вопрос о типе указателя на статический массив на какой адрес он указывает, думаю не на первый элемент массива
0
ValeryS
Модератор
7446 / 5638 / 716
Регистрация: 14.02.2011
Сообщений: 19,207
Завершенные тесты: 1
28.06.2018, 23:13 6
Цитата Сообщение от Papayaved Посмотреть сообщение
для статических массивов место под указатель в памяти не отводится обычно,
а куда же оно девается?
причем у тебя в примере не статический а глобальный массив
Цитата Сообщение от Papayaved Посмотреть сообщение
а так же

C
1
sizeof(array);
возвращает не размер указателя.
разумеется, возвращает размер массива в байтах
Цитата Сообщение от Papayaved Посмотреть сообщение
но
C
1
array++;
не будет работать
а как бы ты хотел чтобы он работал?

Цитата Сообщение от Papayaved Посмотреть сообщение
на какой адрес он указывает, думаю не на первый элемент массива
попробуй
C
1
2
3
4
int arr[]={1,2,3};
int *parr=&arr[0];
int *parr1=arr;
printf("%p %p %p",arr, parr,parr1);
какие адреса выведутся на экран
0
Papayaved
75 / 75 / 8
Регистрация: 24.09.2015
Сообщений: 335
29.06.2018, 07:56  [ТС] 7
ValeryS, в понятиях языка есть только статическая, динамическая и автоматическая память. Понятие глобальности - это область видимости, а не тип размещения в памяти.

Переменные место для которых выделяется на этапе компиляции находятся в статической памяти, не в зависимости от области видимости.

Имя массива ведет себя как константный указатель (хотя это специальный тип данных). Вопрос о том какой адрес выдает операция взятия адреса массива. Я сейчас фактически уверен это будет адрес константного указателя, который компилятор бы не создал, если бы он ни кому не потребовался
0
ValeryS
Модератор
7446 / 5638 / 716
Регистрация: 14.02.2011
Сообщений: 19,207
Завершенные тесты: 1
29.06.2018, 09:08 8
Цитата Сообщение от Papayaved Посмотреть сообщение
в понятиях языка есть только статическая, динамическая и автоматическая память.
мы про память или про массив?
посмотри что означает ключевое слово static
у тебя объявлен глобальный а не статический массив.
Цитата Сообщение от Papayaved Посмотреть сообщение
Я сейчас фактически уверен
ну так надо привести факты
Цитата Сообщение от Papayaved Посмотреть сообщение
который компилятор бы не создал, если бы он ни кому не потребовался
компилятор с оптимизатором не путаешь?

Добавлено через 39 минут
проверить выделяется память под массив можно вот так
C
1
2
3
4
5
6
int a;
int arr[100];
int b;
..........
 
int c= (int)(&b-&a);
если равна размеру int то память не выделилась а если 100 int(или больше) то выделилась
0
Papayaved
75 / 75 / 8
Регистрация: 24.09.2015
Сообщений: 335
29.06.2018, 10:11  [ТС] 9
В каком же типе памяти размещаются глобальные переменные?

Есть куча (динамическая память, что относиться к С++), стек (автоматическая), статическая и внешняя память, (еще регистровая). Статическая и внешняя - для компилятора обычно одна и та же область физической памяти (нет границы в физической памяти между глобальными и статическими переменными, это только области видимости).

Подчеркивая, что массив статический я имеел в виду, что массив не динамический, что адреса элементов массива определяются на этапе компиляции (слова static также может используется для обозначения "приватности").

ValeryS,
Проверять надо так
C
1
2
3
int a[100];
int b[100];
int c = (int)(&a - &b);
Создание типа данных массив не увеличивает объем занимаемой памяти, также как и объединение в структуру. Добавляя массив в программу память данных уменьшится ровно на количество элементов массива.
0
Миниатюры
На что указывает указатель на массив?  
Papayaved
75 / 75 / 8
Регистрация: 24.09.2015
Сообщений: 335
29.06.2018, 10:20  [ТС] 10
Внешняя память - эта та же статическая только зарезервированная в другом файле. Все глобальные переменные оказываются в статической памяти

Когда линкер собирает файлы в программу, то статические и глобальные переменные будет перемешаны в одной и той же статической памяти
0
ValeryS
Модератор
7446 / 5638 / 716
Регистрация: 14.02.2011
Сообщений: 19,207
Завершенные тесты: 1
29.06.2018, 10:27 11
Цитата Сообщение от Papayaved Посмотреть сообщение
В каком же типе памяти размещаются глобальные переменные?
в статической, но область видимости у них разная
вот например
C
1
2
3
4
5
6
int arr1[100];
static int arr2[100];
 
void fnc()
{
static int arr3[100];
все три массива будут лежать в одной памяти, но область видимости у них разная
Цитата Сообщение от Papayaved Посмотреть сообщение
Есть куча (динамическая память, что относиться к С++)
а что malloc отменили уже?
Цитата Сообщение от Papayaved Посмотреть сообщение
Проверять надо так
чтобы узнать размер( выделение памяти) одного массива нужно определить два
Цитата Сообщение от Papayaved Посмотреть сообщение
Добавляя массив в программу память данных уменьшится ровно на количество элементов массива.
что то я вконец запутался как так добавляя уменьшаем память
0
Papayaved
75 / 75 / 8
Регистрация: 24.09.2015
Сообщений: 335
29.06.2018, 10:35  [ТС] 12
ValeryS, в стандарте С нет такого понятия как динамическая память

Если в программу добавить массив

C++
1
char a[1024];
размер занимаемый переменными в памяти увеличиться ровно на 1024 байта (а не 1028 байта), ни какого указателя компилятор не создаст. Свободная память уменьшится
0
ValeryS
Модератор
7446 / 5638 / 716
Регистрация: 14.02.2011
Сообщений: 19,207
Завершенные тесты: 1
29.06.2018, 10:45 13
Цитата Сообщение от Papayaved Посмотреть сообщение
память данных уменьшится
Цитата Сообщение от Papayaved Посмотреть сообщение
Свободная память уменьшится
разночтения не видишь?
Цитата Сообщение от Papayaved Посмотреть сообщение
размер занимаемый переменными в памяти увеличиться ровно на 1024 байта (а не 1028 байта), ни какого указателя компилятор не создаст.
ну а кто то утверждал обратное?
я сразу говорил
Цитата Сообщение от ValeryS Посмотреть сообщение
имя массива это и есть указатель на массив,
Цитата Сообщение от Papayaved Посмотреть сообщение
нет такого понятия как динамическая память
где разместится вот такой массив, точнее выделится память
C
1
int* arr=(int*) malloc(100*sizeof(int));
0
Ygg
1553 / 353 / 137
Регистрация: 10.02.2018
Сообщений: 769
29.06.2018, 12:23 14
Цитата Сообщение от Papayaved Посмотреть сообщение
На что указывает указатель на массив?
На массив, элементами которого являются массивы фиксированного размера и типа.

Аргумент <buf> внутри функции Parse не является массивом, только указателем на unsigned char.
При взятии его адреса получается указатель на временный указатель в стеке, а не указатель на исходный массив.
Для корректного присвоения нужно использовать значение <buf> без <&> при этом произойдет преобразование типов.
Или можно заменить в аргументе массив на указатель на массив, тогда варнингов не будет, а преобразование типов ложится на вызывающую сторону.
0
Papayaved
75 / 75 / 8
Регистрация: 24.09.2015
Сообщений: 335
29.06.2018, 13:06  [ТС] 15
ValeryS,
суда можно вставлять картинки и можно сделать копию страницы стандарта с названием dinamic memory или dynamic array.

Рядом с фразой я привел книгу Кернигана и Ритчи, поэтому оговорился про С++ чтобы им не противоречить
0
ValeryS
Модератор
7446 / 5638 / 716
Регистрация: 14.02.2011
Сообщений: 19,207
Завершенные тесты: 1
29.06.2018, 13:10 16
Цитата Сообщение от Papayaved Посмотреть сообщение
привел книгу Кернигана и Ритчи
ну так
а в курсе что register auto устаревшие?
а в С++ последних стандартов auto это вообще другое значение
0
Croessmah
++Ͻ
14944 / 8536 / 1628
Регистрация: 27.09.2012
Сообщений: 21,017
Записей в блоге: 2
Завершенные тесты: 1
29.06.2018, 13:31 17
Цитата Сообщение от Papayaved Посмотреть сообщение
С указателем на первый элемент все понятно - он указывает на первый элемент массива, но более точно было бы сказать, что это указатель на массив
Это было бы как раз не точно. Имя массива преобразуется в указатель на первый элемент, но имя массива как таковое указателем не является.
Except when it is the operand of the sizeof operator, the_Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.
Papayaved, начнем с того, что указатель содержит адрес чего-то. Ему глубоко фиолетово что там лежит на самом деле. Другой вопрос, как интерпретировать эти данные. Если это указатель на int, то значит считаем, что там лежит int, если это указатель на double, то считаем, что там лежит double, если это указатель на массив, то считаем, что там лежит массив заданного размера с элементами заданного типа. Соответственно, в зависимости от типа указателя, данные будут интерпретированы по-разному. В самом простом случае, sizeof от массива даст sizeof(тип_элементов) * количество_элементов.

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include  <stdio.h>
 
 
int main(void)
{
    int buf[10];
    int * p_int = buf;
    int (* p_arr)[10] = &buf;        
    printf("p_int = %p\np_arr = %p\nsizeof(p_int) = %d\nsizeof(p_arr) == %d\nsizeof(*p_int) = %d\nsizeof(*p_arr) == %d\n", 
           p_int, 
           p_arr, 
           (int)sizeof(p_int), 
           (int)sizeof(p_arr),
           (int)sizeof(*p_int), 
           (int)sizeof(*p_arr)
    );
    return 0;
}
Цитата Сообщение от вывод
p_int = 0x7ffe1cebdbd0
p_arr = 0x7ffe1cebdbd0
sizeof(p_int) = 8
sizeof(p_arr) == 8
sizeof(*p_int) = 4
sizeof(*p_arr) == 40
http://rextester.com/IBDKTB14126
1
Papayaved
75 / 75 / 8
Регистрация: 24.09.2015
Сообщений: 335
29.06.2018, 13:36  [ТС] 18
Croessmah,
C
1
2
3
4
5
6
7
8
9
10
11
12
13
int main(void)
{
    int buf[5] = {11, 12, 13, 14, 15};
    int * p_int = buf;
    int (* p_arr)[5] = &buf;        
    printf("p_int = %p\np_arr = %p\np_arr[3] = %d\n (*p_arr)[3] = %d\n", 
           p_int, 
           p_arr,
           p_arr[3],
           (*p_arr)[3]
    );
    return 0;
}
p_int = 0x7ffd687bc8e0
p_arr = 0x7ffd687bc8e0
p_arr[3] = 1752942876
(*p_arr)[3] = 14
0
Croessmah
++Ͻ
14944 / 8536 / 1628
Регистрация: 27.09.2012
Сообщений: 21,017
Записей в блоге: 2
Завершенные тесты: 1
29.06.2018, 13:42 19
Papayaved, и? Что здесь не так или смущает?

Добавлено через 3 минуты
Цитата Сообщение от Papayaved Посмотреть сообщение
указатель указывает в одно и тоже место, но синтаксис нужен разный
Ну да, так и есть. Типы же разные. Разыменовав указатель на int, получаем int, разыменовав указатель на int[10], получаем int[10].

Кстати, выше уже писали, напишу еще раз. В параметрах функции типа "массива" не будет, типом будет указатель:

C
1
2
3
4
void foo(int p[10]);//p имеет тип int *
void foo(int p[1234]);//p имеет тип int *
void foo(int * p);//p имеет тип int *
//то есть эти объявления эквивалентны
0
Papayaved
75 / 75 / 8
Регистрация: 24.09.2015
Сообщений: 335
29.06.2018, 13:49  [ТС] 20
Croessmah, синтаксис в начальной задаче значит правильный

Решился вопрос, что такое взятие адреса от массива - это оказался тот же самый адрес
0
29.06.2018, 13:49
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.06.2018, 13:49

Указатель на структуру - что напечатает программа
Возьмём пример на языке Си: #include &lt;stdio.h&gt; typedef struct { int...

Указатель на массив структур
Собственно вопрос, как реализовать? Что бы можно было потом обращаться через...

Указатель на двухмерный массив
Всем привет, вот случайно наткнулся на тему указателей и возникла проблема с...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru