Язык си массив символов
Строки в языке C
Строки в C, как и в большинстве языков программирования высокого уровня рассматриваются как отдельный тип, входящий в систему базовых типов языка. Так как язык C по своему происхождению является языком системного программирования, то строковый тип данных в C как таковой отсутствует, а в качестве строк в С используются обычные массивы символов.
Исторически сложилось два представления формата строк:
Формат ANSI устанавливает, что значением первой позиции в строке является ее длина, а затем следуют сами символы строки. Например, представление строки «Моя строка!» будет следующим:
11 ‘М’ ‘о’ ‘я’ ‘ ‘ ‘с’ ‘т’ ‘р’ ‘о’ ‘к’ ‘а’ ‘!’
В строках с завершающим нулем, значащие символы строки указываются с первой позиции, а признаком завершения строки является значение ноль. Представление рассмотренной ранее строки в этом формате имеет вид:
‘М’ ‘о’ ‘я’ ‘ ‘ ‘с’ ‘т’ ‘р’ ‘о’ ‘к’ ‘а’ ‘!’ 0
Объявление строк в C
Строки реализуются посредством массивов символов. Поэтому объявление ASCII строки имеет следующий синтаксис:
char имя[длина];
Объявление строки в С имеет тот же синтаксис, что и объявление одномерного символьного массива. Длина строки должна представлять собой целочисленное значение (в стандарте C89 – константа, в стандарте C99 может быть выражением). Длина строки указывается с учетом одного символа на хранение завершающего нуля, поэтому максимальное количество значащих символов в строке на единицу меньше ее длины. Например, строка может содержать максимально двадцать символов, если объявлена следующим образом:
char str[21]; Инициализация строки в С осуществляется при ее объявлении, используя следующий синтаксис:
char str[длина] = строковый литерал;
Строковый литерал – строка ASCII символов заключенных в двойные кавычки. Примеры объявления строк с инициализацией:
char str1[20] = «Введите значение: «, str2[20] = «»;
const char message[] = «Сообщение об ошибке!»;
Работа со строками в С
Так как строки на языке С являются массивами символов, то к любому символу строки можно обратиться по его индексу. Для этого используется синтаксис обращения к элементу массива, поэтому первый символ в строке имеет индекс ноль. Например, в следующем фрагменте программы в строке str осуществляется замена всех символов ‘a’ на символы ‘A’ и наоборот.
Массивы строк в С
Объявление массивов строк в языке С также возможно. Для этого используются двумерные массивы символов, что имеет следующий синтаксис:
char имя[количество][длина];
Первым размером матрицы указывается количество строк в массиве, а вторым – максимальная (с учетом завершающего нуля) длина каждой строки. Например, объявление массива из пяти строк максимальной длиной 30 значащих символов будет иметь вид:
Число строковых литералов должно быть меньше или равно количеству строк в массиве. Если число строковых литералов меньше размера массива, то все остальные элементы инициализируются пустыми строками. Длина каждого строкового литерала должна быть строго меньше значения длины строки (для записи завершающего нуля).
При объявлении массивов строк с инициализацией допускается не указывать количество строк в квадратных скобках. В таком случае, количество строк в массиве будет определено автоматически по числу инициализирующих строковых литералов.
Например, массив из семи строк:
Функции для работы со строками в С
Все библиотечные функции, предназначенные для работы со строками, можно разделить на три группы:
Ввод и вывод строк в С
Для ввода и вывода строковой информации можно использовать функции форматированного ввода и вывода (printf и scanf). Для этого в строке формата при вводе или выводе строковой переменной необходимо указать спецификатор типа %s. Например, ввод и последующий вывод строковой переменной будет иметь вид:
char str[31] = «»;
printf(«Введите строку: «);
scanf(«%30s”,str);
printf(«Вы ввели: %s”,str);
Недостатком функции scanf при вводе строковых данных является то, что символами разделителями данной функции являются:
Поэтому, используя данную функцию невозможно ввести строку, содержащую несколько слов, разделенных пробелами или табуляциями. Например, если в предыдущей программе пользователь введет строку: «Сообщение из нескольких слов», то на экране будет выведено только «Сообщение».
Для ввода и вывода строк в библиотеке stdio.h содержатся специализированные функции gets и puts.
Функция gets предназначена для ввода строк и имеет следующий заголовок:
char * gets(char *buffer);
Между тем использовать функцию gets категорически не рекомендуется, ввиду того, что она не контролирует выход за границу строки, что может произвести к ошибкам. Вместо нее используется функция fgets с тремя параметрами:
char * fgets(char * buffer, int size, FILE * stream);
Функция puts предназначена для вывода строк и имеет следующий заголовок:
int puts(const char *string);
Простейшая программа: ввод и вывод строки с использованием функций fgets и puts будет иметь вид:
Помимо функций ввода и вывода в потоки в библиотеке stdio.h присутствуют функции форматированного ввода и вывода в строки. Функция форматированного ввода из строки имеет следующий заголовок:
Функции форматированного вывода в строку имеют следующие заголовки:
Преобразование строк
В С для преобразования строк, содержащих числа, в численные значения в библиотеке stdlib.h
предусмотрен следующий набор функций:
double atof(const char *string); // преобразование строки в число типа double
int atoi(const char *string); // преобразование строки в число типа int
long int atol(const char *string); // преобразование строки в число типа long int
long long int atoll(const char *string); // преобразование строки в число типа long long int
Корректное представление вещественного числа в текстовой строке должно удовлетворять формату:
После символов E, e указывается порядок числа. Корректное представление целого числа в текстовой строке должно удовлетворять формату:
Помимо приведенных выше функций в библиотеке stdlib.h доступны также следующие функции преобразования строк в вещественные числа:
Аналогичные функции присутствуют и для преобразования строк в целочисленные значения:
Функции обратного преобразования (численные значения в строки) в библиотеке stdlib.h присутствуют, но они не регламентированы стандартом, и рассматриваться не будут. Для преобразования численных значений в строковые наиболее удобно использовать функции sprintf и snprintf.
Обработка строк
В библиотеке string.h содержаться функции для различных действий над строками.
Функция вычисления длины строки:
size_t strlen(const char *string);
Функции копирования строк:
Функции сравнения строк:
Функции осуществляют сравнение строк по алфавиту и возвращают:
положительное значение – если string1 больше string2;
отрицательное значение – если string1 меньше string2;
нулевое значение – если string1 совпадает с string2;
Функции объединения (конкатенации) строк:
Функции поиска символа в строке:
Функция поиска строки в строке:
char * strstr(const char *str, const char *substr);
Функция поиска первого символа в строке из заданного набора символов:
size_t strcspn(const char *str, const char *charset);
Функции поиска первого символа в строке не принадлежащему заданному набору символов:
size_t strspn(const char *str, const char *charset);
Функции поиска первого символа в строке из заданного набора символов:
char * strpbrk(const char *str, const char *charset);
Функция поиска следующего литерала в строке:
char * strtok(char * restrict string, const char * restrict charset);
Особенности работы со строками
Неформатированные ввод из стандартного потока и вывод в стандартный поток
С помощью функции printf() можно легко вывести на экран строку, содержащую пробелы:
С другой стороны, ввести строку произвольной длины, содержащую пробелы в неизвестных местах, исключительно с помощью функции scanf() невозможно. Для scanf() любой символ пустого пространства является сигналом завершения ввода очередных данных, если только не производится считывание символа.
В заголовке цикла getchar() возвращает символ, далее записываемый в очередную ячейку массива. После этого элемент массива сравнивается с символом ‘\n’. Если они равны, то цикл завершается. После цикла символ ‘\n’ в массиве «затирается» символом ‘\0’. В условии цикла должна быть также предусмотрена проверка на выход за пределы массива; чтобы не усложнять пример, опущена.
Однако в языке программирования C работать со строками можно проще. С помощью функций стандартной библиотеки gets() и puts() получают строку из стандартного потока и выводят в стандартный поток. Буква s в конце слов gets и puts является сокращением от слова string (строка).
В качестве параметров обе функции принимают указатель на массив символов (либо имя массива, либо указатель).
Функция gets() помещает полученные с ввода символы в указанный в качестве аргумента массив. При этом символ перехода на новую строку, который завершает ее работу, игнорируется.
Функция puts() выводит строку на экран и при этом сама добавляет символ перехода на новую строку. Простейший пример использования этих функций выглядит так:
Массив символов и указатель на строку
Как мы знаем, строка представляет собой массив символов, последний элемент которого является нулевым символом по таблице ASCII, обозначаемым ‘\0’. При работе со строками также как с численными массивами можно использовать указатели. Мы можем объявить в программе массив символов, записать туда строку, потом присвоить указателю адрес на первый или любой другой элемент этого массива и работать со строкой через указатель:
В заголовке цикла указателю сначала присваивается адрес первого элемента массива, его значение увеличивается до тех пор, пока не встретится пробел. В итоге указатель указывает на пробел и мы можем получить с его помощью вторую часть строки.
Иногда в программах можно видеть такое объявление и определение переменной-указателя:
Строку, которая была присвоена не массиву, а указателю, также можно получить, обратившись по указателю:
Но давайте посмотрим, что же все-таки происходит, и чем такая строка, присвоенная указателю, отличается от строки, присвоенной массиву.
Когда в программе определяются данные и объявляются переменные, то под них отводится память. При этом данные, которые не были присвоены переменным, поменять в процессе выполнения программы уже нельзя.
Что происходит в примере? В программе вводится строковый объект, который по сути является строковой константой (литералом). Ссылка на первый элемент этой строки присваивается указателю. Мы можем менять значение указателя сколько угодно, переходить к любому из элементов константного массива символов или даже начать ссылаться на совершенно другую строку. Но вот поменять значение элементов строки не можем. Это можно доказать таким кодом:
В последней строке кода возникнет ошибка, т.к. совершается попытка изменить строку-константу.
Тем более нельзя делать так:
В данном случае память не была выделена под массив символов, который мы пытаемся считать функцией scanf() ; память была выделена только под указатель. Поэтому записать строку просто некуда. Другое дело, если память была выделена с помощью объявления массива, после чего указателю был присвоен адрес на этот массив:
Поэтому если вам требуется в программе неизменяемый массив символов, то можете определить его через указатель.
Передача строки в функцию
Передача строки в функцию ничем не отличается от передачи туда массива чисел:
В этом примере функция change() принимает в качестве параметра указатель на символ. В теле функции значение указателя инкрементируется, указывая на следующий символ массива. В теле цикла инкрементируется значение, которое находится по адресу, который содержит указатель.
Массив строк и массив указателей
Рассмотрим более сложный пример. Допустим, у нас есть набор строк. Требуется выполнить сортировку строк по возрастанию по признаку длины: сначала вывести самые короткие строки, затем более длинные.
Набор строк можно представить как двумерный массив, т.е. массив, состоящий из одномерных массивов, где каждый одномерный массив — это строка символов:
Представьте себе, что значит выполнить сортировку строк. Это значит, надо поменять местами содержимое множества ячеек памяти. Это достаточно трудоемкая для компьютера работа, особенно если строк очень много. Однако можно поступить по-иному. Достаточно создать массив указателей, каждый элемент которого будет указывать на соответствующую ему строку первого массива. Далее выполнить сортировку указателей, что несомненно быстрее. Конечно, сам массив строк отсортирован не будет, однако благодаря указателям у нас будет хранится отсортированный «срез» массива:
Примечания к программе:
Напишите программу, которая сортирует строки по алфавиту. Для упрощения задачи пусть сортировка выполняется только по первым буквам строк (если первые буквы слов одинаковы, то вторые и последующие символы проверять не надо).
Функции обработки строк в Cи
В программе строки могут определяться следующим образом:
Кроме того, должно быть предусмотрено выделение памяти для хранения строки.
Под хранение строки выделяются последовательно идущие ячейки оперативной памяти. Таким образом, строка представляет собой массив символов. Для хранения кода каждого символа строки отводится 1 байт.
При определении массива символов необходимо сообщить компилятору требуемый размер памяти.
Компилятор также может самостоятельно определить размер массива символов, если инициализация массива задана при объявлении строковой константой:
В этом случае имена m2 и m3 являются указателями на первые элементы массивов:
При объявлении массива символов и инициализации его строковой константой можно явно указать размер массива, но указанный размер массива должен быть больше, чем размер инициализирующей строковой константы:
В этом случае объявление массива переменной m4 может быть присвоен адрес массива:
Для указателя можно использовать операцию увеличения (перемещения на следующий символ):
Массивы символьных строк
В этом случае poet является массивом, состоящим из четырех указателей на символьные строки. Каждая строка символов представляет собой символьный массив, поэтому имеется четыре указателя на массивы. Указатель poet[0] ссылается на первую строку:
*poet[0] эквивалентно ‘П’,
*poet[l] эквивалентно ‘-‘.
Инициализация выполняется по правилам, определенным для массивов.
Тексты в кавычках эквивалентны инициализации каждой строки в массиве. Запятая разделяет соседние
последовательности.
Кроме того, можно явно задавать размер строк символов, используя описание, подобное такому:
Разница заключается в том, что такая форма задает «прямоугольный» массив, в котором все строки имеют одинаковую длину.
Свободный массив
Операции со строками
Большинство операций языка Си, имеющих дело со строками, работает с указателями. Для размещения в оперативной памяти строки символов необходимо:
Для выделения памяти под хранение строки могут использоваться функции динамического выделения памяти. При этом необходимо учитывать требуемый размер строки:
Функции ввода строк
Для ввода строки, включая пробелы, используется функция
В качестве аргумента функции передается указатель на строку, в которую осуществляется ввод. Функция просит пользователя ввести строку, которую она помещает в массив, пока пользователь не нажмет Enter.
Функции вывода строк
Для вывода строк можно воспользоваться рассмотренной ранее функцией
или в сокращенном формате
Для вывода строк также может использоваться функция
которая печатает строку s и переводит курсор на новую строку (в отличие от printf() ). Функция puts() также может использоваться для вывода строковых констант, заключенных в кавычки.
Функция ввода символов
Для ввода символов может использоваться функция
которая возвращает значение символа, введенного с клавиатуры. Указанная функция использовалась в рассмотренных ранее примерах для задержки окна консоли после выполнения программы до нажатия клавиши.
Функция вывода символов
Для вывода символов может использоваться функция
которая возвращает значение выводимого символа и выводит на экран символ, переданный в качестве аргумента.
Пример Посчитать количество введенных символов во введенной строке.
Результат выполнения
Основные функции стандартной библиотеки string.h
Основные функции стандартной библиотеки string.h приведены в таблице.
Пример использования функций
Результат выполнения
Комментариев к записи: 111
#include
#include «string.h»
#include «stdio.h»
using namespace std;
int main()
<
char from, to;
char text[100],*wbeg, * wend, delim[] = » ;. » ;
cout «Input text and put ‘.’ at the end: » ; cin.getline(text, 100, ‘.’);
do < cout "Line is empty! Retry: " ; cin.getline(text, 100, '.');>while (strlen(text) == 0);
int n_delim = strspn(text, delim); // возвращает к-сть разделителей
wbeg = text + n_delim; // указатель на начало слова
wend = text + strlen(text); // указатель на конец слова
n_delim = strcspn(wbeg, delim); //длина первого слова
int count = 1; cout «Input number of thе word: » ; int number; cin >> number;
while ((wbeg + n_delim if (count == number)
<
do
<
cout «Input symbol, that should be changed: » ; char ch1; cin >> ch1; //запрос буквы
char *pos_s = strchr(wbeg, ch1);
if (pos_s == 0) cout «No symbol!» ;
else if (wbeg + n_delim «Input symbol to change one: » ; char ch2; cin >> ch2;
ch2 = &pos_s;
> while (count else cout «No words with given number!» ; return 0;
>
return 0;
>
Как стать программистом
Обучение основам программирования на C для чайников.
Страницы
Последние новости
YoungCoder теперь и на Stepikе. Записывайтесь: https://vk.cc/75rISy
Чтобы записаться на курс, необходимо зарегистрироваться на Степике: https://vk.cc/75rIC4
Это моя личная ссылка-приглашение на Stepik для вас. Регистрируясь по этой ссылке, записываясь на курсы и решая задачи, Вы помогаете автору данного сайта принять участие в конкурсе платформы Stepik! Подробности конкурса здесь: https://vk.cc/75rKuS
воскресенье, 4 августа 2013 г.
Занятие 14. Строки и символьные массивы в языке Си.
Прочитайте улучшенную версию этого урока «Ввод и вывод символьных строк».
Объявление и инициализация строк.
Рис. 4. Вывод на экран символьного массива без нулевого элемента в конце |
Ввод и вывод строк.
Рис.9. Использование стандартных функций вывода строки puts(), fputs(). Особенности вывода. |
Если Вам понравился этот урок, расскажите о нем вашим друзьям. В этом Вам могут помочь кнопки основных социальных сетей, расположенные ниже. Вам остается всего лишь кликнуть по любой из них.
123 комментария :
Самый непонятный урок для меня 🙁
Особенно с длинной строки.
«Количество символов, которые может считать функция с учетом символа конца строки. В нашем случае это 10, т.е. рабочих из них девять, и один зарезервирован для конца строки.»
Почему 9 да еще и минус один под конец строки и того 8? А на выводе все равно получается, что считали и вывели 9 символов. (Листинг 14.8)
Последний символ 100% записывается в конец строки и считается n-ным (последним) элементом массива? Как этот символ считать? т.е. как написать for (i = 0; i == конец строки; i++); (ага пока читал извилина шевельнулась. Не знаю только в правильную ли сторону 🙂 Получается так сделать нельзя т.к. мы сначала i приравниваем к целому числу, а потом хотим проверить не равено ли он символу. Тогда все равно не понятно как сделать такой цикл, что бы он выполнялся до конца строки).
Я наверное коряво написал. Смотрите 10 можете считать. Из них рабочих 9. А десятый, который не рабочий как раз и зарезервирован под конец строки.
Длина массива и длинна строки это разные вещи ведь. Длинна массива может быть и 100 элементов, а вот длина строки, которая хранится в этом массиве может быть и меньше. Например, Литстинг 14.3
Длинна массива str 17 элементов, а длина строки, которую мы туда поместили всего двенадцать. Из них, как мы уже разобрались 11 рабочие и последний, двенадцатый символ конца строки. )
Теперь, с учетом этих пояснений попробуйте ответить на свои последние вопросы или переформулировать их. Если не получится, напишите я или отвечу или дам еще подсказку. )
Ruby on Rails c нуля!
Программирование на языке Си: Использование массивов данных в Си. Указатели.
октября 31, 2011 | Published in Си и C++ | 9 Comments
Объявление массива в Си
Массив (Array) относится к вторичным типам данных. Массив в Си представляет собой коллекция явно определенного размера элементов определенного типа. то есть в отличие от массивов в Ruby массивы в Си являются однотипными (хранят данные только одного типа) и имеют заранее определенную длину (размер).
В Си массивы можно грубо разделить на 2 типа: массив чисел и массив символов. Разумеется, такое деление абсолютно условное ведь символы — это также целые числа. Массивы символов также имеют несколько иной синтаксис. Ниже приведены примеры объявления массивов:
В первом случае мы объявляем массив целых чисел (4 байта на число) размером в 100 элементов. Точнее мы резервируем память для хранения 100 элементов типа int.
Во втором случае мы определяем массив из 10 целочисленных элементов и сразу же присваиваем элементам массива значения.
В третьем случае мы определяем массив символов. В Си нету строк, но есть массивы символов, которые заменяют строки.
В последнем случае мы также объявляем массив символов с помощью специального — более лаконичного синтаксиса. Массивы ch и ch2 практически идентичны, но есть одно отличие. Когда для создания массива мы используем синтаксис со строковой константой, то в конец массива символов автоматически добавляется символ \0, при использовании стандартного синтаксиса обявления массива мы должны самостоятельно добавлять \0 в качестве последнего элемента массива символов. Символ \0 (null) используется для идентификации конца строки. О страках мы поговорим более подробно в отдельной статье.
Обращение к элементам массива в Си
В Си обращение к элементам массива достаточно тривиально и похоже на то как это делается в большинстве других языков программирования. После имени переменной ссылающейся на массив мы в квадратных скобках указываем индекс (еще его называют ключом) элемента. В примере ниже показано как мы обращаемся к первому элементу массива:
В общем случае объявление массива имеет следующий синтаксис:
Количество элементов массива и список элементов являются обязательными атрибутами объявления массива, точнее обязательным является любое одно из них, но не оба сразу.
Для того, чтобы вникнуть в устройство массивов необходимо познакомиться с такой концепцией как указатели в Си.
Указатели в Си
Типы данных необходимы для того, чтобы мочь выделить кусок памяти определенного размера для хранения данных и определения того, что это за данные ибо без явного определения непонятно является ли набор нулей и единиц числом, символом или чем-нибудь еще. В этом случае переменная является ссылкой на фрагмент памяти определенного размера и типа, например, int переменная ссылается на определенную область памяти объемом 4 байта, в которой хранится целое число, а char переменная ссылается на область памяти объемом 1 байт в которой хранится символ (код символа).
Чтобы получить адрес на который ссылается переменная мы используем специальный оператор & — оператор адреса (address operator), пример:
Строка printf(«%p\n», &arr); напечатает 0xbfbbe068. 0xbfbbe068 — шестнадцатеричное представление адреса памяти где хранится число 100500.
Указатели — это переменные специального типа, которые хранят не обыкновенные значения, но их адреса в памяти.
В примере выше мы присваиваем переменным a и b одинаковое значение — число 10, но переменные a и b ссылаются на две разные области памяти, то есть мы сохраняем в памяти число 10 два раза. Если мы изменим значение переменной b, то оно это не отразится на переменной a и наоборот. Это отличается от того, как мы работаем с переменными в Ruby, где переменные — это ссылки на объекты хранимые в памяти, и при присваивании в стиле a = b = 10 мы получаем один объект — число 10 и две ссылки на него.
Если нам необходима будет еще одна ссылка на ту же область памяти, на которую ссылается переменная a, то мы можем воспользоваться указателем. Пример:
Указатели и массивы
На самом деле в Си нет массивов в привычном для многих людей понимании. Любой массив в Си — это просто ссылка на нулевой элемент массива. Пример:
Как видите я вас не обманул, переменная ссылающаяся на массив на самом деле ссылается только на его нулевой элемент, то есть является указателем на адрес хранения первого элемента.
Когда мы запускаем программу, то операционная система предоставляет программе два особых объема памяти — стек (stack) и кучу (heap). В нашей программе используется только стек. Стек хранит значения упорядочено. Когда мы создаем массив, мы на самом деле создаем указатель ну нулевой элемент коллекции элементов и резервируем память для N-количества элементов. В примере выше мы создали коллекцию из 3 элементов типа int, т.е. каждый элемент занимает 4 байта памяти. Когда мы воспользовались функцией sizeof(), которая возвращает размер в байтах переданного ей аргумента, то получили значение 12 т.е. массив занимает 12 байт памяти: 3элемента * 4 байта. Поскольку для хранения элементов коллекции используется стек — элементы сохраняются по порядку, то есть занимают соседние области стека, а это означает, что мы можем перемещаться по коллекции зная позицию элемента и размер коллекции. Пример:
Программа напечатала нам информацию о массиве из 5 элементов: номер элемента, значение и адрес в памяти. Обратите внимание на адреса элементов — это то, о чем я вам говорил. Адреса идут подряд и каждый следующий больше предыдущего на 4. В 5 элементе коллекции, которого мы на самом деле не объявляли хранится общее количество элементов коллекции. Самое интересное — это то, что мы можем аналогичным образом использовать и указатели для прохода по массиву. Пример:
Примечания
1. Обратите внимание на то, что указателю b мы присваиваем не адрес массива a, а само значение переменной a, ведь a это, по сути и есть указатель.
2. Использование квадратных скобой с указанием индексов элементов массива — это такой синтаксический сахар в Си для более удобного и понятного обращения к элементам коллекции.
3. Как я уже говорил, в Си нету традиционных массивов потому, я называю их коллекциями для того, чтобы подчеркнуть эту особенность Си.
4. Адрес 1 элемента массива больше адреса 0 элемента массива на объем памяти выделяемой под хранение элемента данного типа. Мы работаем с элементами типа int, для хранения каждого из которых используется 4 байта. Адрес элемента массива в памяти и вообще любых данных — это адрес первого байта выделяемой под его хранение памяти.
5. Для упрощения понимания представьте, что память компьютера — это огромный кинотеатр, где места пронумерованы от 0 до, скачем 1_073_741_824. У данных типа char задница нормального размера и они помещаются в одном кресле (занимают один байт), а у толстых посетителей типа long double задницы огромные и каждый из них вмещается только на 10 сидениях. Когда у толстых посетителей кинотеатра спрашивают номер их места, они говорят только номер первого кресла, а количество и номера всех остальных кресел можно легко вычислить исходя из комплекции посетителя (типа данных). Массивы можно представить в виде групп однотипных посетителей кинотеатра, например группа худеньких балерин типа char из 10 человек займет 10 мест потому, что char вмещается в одном кресле, а группа любителей пива состоящая из 5 человек типа long int займет 40 байт.
6. У операторов & и * имеется несколько популярных названий, но вы можете называть их хоть Васей и Петей. Главное, что стоит запомнить — это:
& — показывает номер первого занятого посетителем кинотеатра сидения. То есть адрес первого занимаемого байта.
* — позволяет обратиться к посетителю сищящему на определенном месте. То есть позволяет получить значение, что хранится по определенному адресу в памяти.
На этом статья окончена, но не окончена тема массивов и указателей, а тем более изучения всего языка Си.
Лучшая благодарность автору — ваши комментарии!