Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/4: Рейтинг темы: голосов - 4, средняя оценка - 4.50
10 / 10 / 5
Регистрация: 30.01.2013
Сообщений: 99
1

Детально о массивах

24.02.2014, 09:06. Показов 673. Ответов 4
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем доброго времени суток. Уже создавал похожий пост, думал, все понял, но вот прошел ровно год и появились новые вопросы. Дело пойдет о массивах, а точнее о том, что происходит в компиляторе, когда мы их объявляем.

На данный момент, у меня такое представление о них:

Случай первый:
C
1
char mass[10];
Выделяется 10 байт памяти, создается константный указатель mass (const char*) и в него заносится адрес первой ячейки выделенной памяти. Т.е. эквивалентным будет следующая инструкция:
C
1
const char* mass = malloc(10);
Случай второй:
C
1
char mass[] = "Onotole";
Анализируется количество букв в слове, выделяется такое же количество байт + место под символ конца строки (\0), создается константный указатель mass (const char*) и в него заносится адрес первой ячейки выделенной памяти. Эквивалентный код:
C
1
char* mass = "Onotole";
Случай третий:
C
1
char* mass[] = {"Ivan", "Vovan", "Stepan", "Baran"};
Создается массив из указателей (char*) с количеством индексов равным количеству слов в фигурных скобках. Для каждого слова, что в фигурных скобках, выделяется память (с учетом символа конца строки для каждого слова). Причем память может выделяться так, что слова могут находиться в совершенно разных участках памяти. Затем адреса первых ячеек памяти каждого слова заносятся в массив указателей.

Случай четвертый:
C
1
char mass[2][7] = {"Andrey", "Sergey"};
В памяти выделяется последовательность из 14 байт (2*7). Затем в эту последовательность байт заносится строка "Andrey\0Sergey\0".

Прошу поправить меня (или дополнить), где я неверно представляю принципы работы массивов.

Вопрос: Если в четвертом случае я все верно описал, почему же тогда можно использовать следующую конструкцию: printf("%c", **mass); - тут смущает двойное разыменование. Но ведь речь идет не о массиве указателей! Как такое возможно?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
24.02.2014, 09:06
Ответы с готовыми решениями:

многопоточность детально!
Уважаемые!!!! на базовом уровне ознакомился с многопоточностью в Java (потоки, ключевые слова,...

В массивах G(8), K(19) определить кол-во и произведение элементов меньших 26 в двух заданных массивах (6;34)
Задать два одномерных массива значений, чтобы величины элементов массивов попадали в заданный...

Детально изучена механика полета мух
Ученые из Корнеллского университета США выяснили, как дрозофилам удается выполнять быстрые и резкие...

Опишите, пожалуйста, детально разгон проца и оперативы
процессор amd athlon 64 x2 4000+ 2.1 ГГц, оператива ddr2 2Gb 400Mhz + 1Gb 333Mhz, мать ASRock...

4
127 / 126 / 59
Регистрация: 22.01.2014
Сообщений: 462
24.02.2014, 23:51 2
двойное разыменование дает доступ к символу, а не к строке.
Эквивалентно
printf("%c", mass[0][0]);//Должно вывести A.
Первое разъименовывание дает доступ к "Andrey", второе к букве A.
Как я понимаю, дело в том что "имя" массива, фактически является указателем на первый элемент массива.
имя дает указатель(адрес), раизменовывание(или [0]) дает доступ к первому элементу, второе разъименовывание к его первому элементу базового типа из прошлой операции.
1
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
25.02.2014, 03:33 3
Цитата Сообщение от murtukov Посмотреть сообщение
Выделяется 10 байт памяти, создается константный указатель
1. const-указатель и указатель на const-данные - это вовсе не одно и то же.
const-указатель нельзя двигать, но зато можно изменять данные, на которые
он указывает. Указатель на const-данные, наоборот, двигать можно, но зато
через него можно обращаться к данным только на чтение. Есть еще const-
указатели на const-данные (для параноиков).

2. В C/C++ строковые литералы константны (по стандарту языка), попытка их
изменения ведет к неопределенному поведению. Например:
C++
1
2
char *pName = "John";
pName[0] = "D"; // Bang!
3. Массивы, в отличие от строковых литералов, неконстантны.
C++
1
2
char pName[] = {"John"};
pName[0] = "D"; // OK.
1
10 / 10 / 5
Регистрация: 30.01.2013
Сообщений: 99
26.02.2014, 00:37  [ТС] 4
Николай, я знаю что такое двойное разыменование и знаю результат таких действий, но, понимаете, двойное разыменование можно применять только к указателю на указатель, но в четвертом случае создается не массив указателей, иначе имя массива было бы указателем на указатели.
В действительности же в четвертом случае создается просто массив символов, т.е. получается мы имеем один указатель на символы (по крайней мере так говорили знатоки из другого моего поста: Для разбирающихся в работе массивов и указателей) и применить двойное разыменование тут нельзя, хотя на деле оно работает.
У меня определенно где-то ошибка в представлении работы массивов и указателей.
На данный момент меня интересует, что же все таки происходит "за кулисами" в этой инструкции:
C
1
char mass[2][7] = {"Andrey", "Sergey"};
Добавлено через 5 минут
Убежденный, с первым знаком, просто иногда путаю объявления const char* и char * const ввиду недостатка опыта работы с подобным)
А про второе и третье не знал, спасибо.

P.S. Прочтите мой пост выше. Не знаете ответа на вопрос?

Добавлено через 10 минут
nikolay1982, кстати, все обращения вида: mass[2][3] автоматически заменяются компилятором в *(*(mass+2)+3). Пример:
C
1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
 
int main()
{
    char pName[2][6] = {"Timur", "Marat"};
// две последующие строки эквивалентны и выводят букву r
    printf("%c", pName[1][2]);
    printf("%c", *(*(pName+1)+2));
    return 0;
}
Добавлено через 6 минут
Убежденный, неправильно пытаться совершить присвоение pName[0] = "D"; - тут нужны одинарные кавычки
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12458 / 7482 / 1753
Регистрация: 25.07.2009
Сообщений: 13,762
26.02.2014, 01:42 5
Цитата Сообщение от murtukov Посмотреть сообщение
неправильно пытаться совершить присвоение pName[0] = "D"; - тут нужны одинарные кавычки
Да оно и с одинарными не должно работать. По сути само объявление
C
1
char * str = "bla bla bla";
уже неправильное. Правильно
C
1
const char * str = "bla bla bla";
Строковые литералы располагаются в памяти "только для чтения" (должны бы по крайней мере).

Что же до вопроса по поводу двухмерных массивов, намекну:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <string.h>
 
typedef char shortstring_t[8];
 
int main(void) {
    char words1[2][8] = { "word1", "word2" };
    shortstring_t words2[] = { "word3", "word4" };
    
    printf("%d\n", strlen(words1[0]));
    printf("%d\n", sizeof(words1[0]));
    printf("%d\n", sizeof(words1));
    
    printf("\n");
    
    printf("%d\n", strlen(words2[0]));
    printf("%d\n", sizeof(words2[0]));
    printf("%d\n", sizeof(words2));
    
    return 0;
}
Код
$ ./shortstring 
5
8
16

5
8
16
0
26.02.2014, 01:42
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.02.2014, 01:42
Помогаю со студенческими работами здесь

Объясните, пожалуйста, код (детально метод gameUpdate()
Объясните, пожалуйста, код (детально метод gameUpdate()): public class Main extends Application...

Нужно детально разобрать, почему цикл бесконечный
Вот имеется цикл double n=50; while(n&gt;0) n+=15; printf(&quot;%lf&quot;,n); Мне нужно понять,почему...

Как детально посмотреть то что находиться в строковой переменной
Здравствуйте, Как детально посмотреть то что находиться в строковой переменной? Получаю значит я...

вопрос по MySql+php (введите более детально описание)
Привет всем ! Подскажите с чем связано следующее явление и как его исправить : Есть скрипт котрый...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru