Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
27 / 27 / 18
Регистрация: 13.09.2014
Сообщений: 137

Размер массива

06.12.2014, 21:50. Показов 1219. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Почему это работает? И как это понимать?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "stdafx.h"
#include <iostream>
using namespace std;
 
template <size_t Len>
void print(int(&arr)[Len])
{
    for (size_t i = 0; i < Len; ++i)
        cout << " "[!i] << arr[i];
    cout << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
    setlocale(0, "Rus");
    int arr[] = { 1, 2, 5, 4, 3, 2, 3};
    print(arr);
    cin.get();
    return 0;
}
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
06.12.2014, 21:50
Ответы с готовыми решениями:

Ввести размер массива с клавиатуры и передать этот размер в конструктор
Я создал массив объектов. И я хочу ввести размер этого массива с клавиатуры, и передать этот размер в конструктор, как мне это сделать? ...

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

Функция, которая удаляет из целочисленного одномерного массива все, и возвращает новый размер массива
Разработать и испытать функцию, которая удаляет из целочисленного одномерного массива все, и возвращает новый размер массива. #include...

5
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
06.12.2014, 21:58
Цитата Сообщение от notemac Посмотреть сообщение
Почему это работает? И как это понимать?
Что конкретно? Вывод размера массива в шаблоне или пробел м/у элементами?
0
27 / 27 / 18
Регистрация: 13.09.2014
Сообщений: 137
07.12.2014, 03:38  [ТС]
Tulosba, откуда функция узнает размер массива? (Как высчитывает...)
И вот это, что значит
C++
1
cout << [!i]
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
07.12.2014, 05:02
Лучший ответ Сообщение было отмечено notemac как решение

Решение

Цитата Сообщение от notemac Посмотреть сообщение
откуда функция узнает размер массива? (Как высчитывает...)
Из шаблона:

C++
1
2
template <size_t Len>
void print(int(&arr)[Len])
"Шаблон" означает, что это - не функция. Это шаблон, на основе которого компилятор сам создаст функцию.

В вашем случае, компилятор сначала смотрит, что за аргумент вы подсовываете:

C++
1
print(arr);
После чего он смотрим, чем является arr ?

C++
1
int arr[] = { 1, 2, 5, 4, 3, 2, 3};
И видит, что это массив, и знает сколько в нем элементов.

А потом он смотрит на сам шаблон:

C++
1
2
template <size_t Len>
void print(int(&arr)[Len])
Судя по описанию шаблона он принимает некоторый массив с размерностью Len.
И сопоставляет:
так-так-так, а ведь сюда как раз подсунули массив с размерностью... ммм...
Вот параметр Len и становится равным размерности переданного массива.

Вот так компилятор сгенерирует функцию в которой везде вместо слова Len будет подставлен размер того массива, что вы указали в аргументе.

Добавлено через 27 минут
Цитата Сообщение от notemac Посмотреть сообщение
И вот это, что значит
cout << [!i]

Давайте рассмотрим в деталях запись:
C++
1
2
for (size_t i = 0; i < Len; ++i)
        cout << " "[!i] << arr[i];
Что здесь хотел автор? Он хотел вывести все элементы массива через пробел. И при этом сделать так, что бы перед самым первым элементом массива пробела не было. Что бы пробелы начались после первого символа.

И теперь давайте пронаблюдаем, как он этого добился.

Для начала вам нужно понять запись вида !i
Здесь i - это переменная. А восклицательный знак - булевое отрицание.

Таким образом для i равной нулю, результат будет 1. А для всех остальных i - ноль.

Далее, литерные константы, это записи вида "text" на самом деле являются неизменяемыми массивами типа char. Так например, "text" это массив, который можно описать в виде:
C++
1
const char ar[]={'t', 'e', 'x', 't',  0};
Соответственно, " " это массив из двух элементов:
C++
1
const char ar[]={' ', 0};
Обратите внимания, литерная константа имеет "невидимый" последний элемент ноль.
Этот ноль сигналит различным текстовым алгоритмам, что строка достигла своего окончания.
Это наследие языка си, который не умеет шаблоны. И там единственные способы понять, что массив закончился - это либо явно передавать его размер, либо вот по нолику.


Ну так вот, раз литерная константа - это массив, значит когда мы пишем:

" "[i] это равносильно тому, как если бы мы написали ar[i]

Таким образом выражение " "[!i] будет равно второму элементу (нолику) для i равном нулю, и первому элементу (пробелу) для всех остальных i.

А значит, что запись:
C++
1
cout << " "[!i] << arr[i];
для i равном нулю превратится в :
C++
1
cout << 0 << arr[i];
А поскольку ноль - это признак конца строки (как я уже писал выше),
то алгоритм работы с текстом просто посчитает что закончилась неначавшаяся строка.
И значит что запись эквивалентна:
C++
1
cout << arr[i];
То бишь вывод arr[i] без пробела вначале.

Для всех прочих i запись превратится в:
C++
1
cout << ' ' << arr[i];
То бишь, сначала пробел, а затем значение элемента.

Итого по итогу имеем на экране:
1 2 5 4 3 2 3
2
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13177 / 6813 / 1821
Регистрация: 18.10.2014
Сообщений: 17,238
07.12.2014, 05:34
Цитата Сообщение от notemac Посмотреть сообщение
откуда функция узнает размер массива? (Как высчитывает...)
Размер массива узнает не функция, а компилятор, который будет генерировать конкретную версию вашей функции из шаблона. Компилятор, разумеется, прекрасно знает размер вашего массива. Т.е. комплятор знает, каково будет значение шаблонного параметра 'Len'. И именно для этого значения 'Len' компилятор генерирует отдельную версию вашей функции

Цитата Сообщение от notemac Посмотреть сообщение
И вот это, что значит
C++
1
cout << [!i]
Это вы где такое увидели??? У вас в коде ничего подобного нет. У вас ясно написано

C++
1
cout << " "[!i];
'" "' - это строковый литерал, т.е. объект типа 'const char[2]', т.е. это обыкновенный массив. К этому массиву вы применяете обыкновенный доступ по индексу '!i' через оператор '[]'. Вот и все.

Классический пример аналогичного приема

C++
1
"0123456789"[i]
Это выражение будет давать символ '5' для i==5, '8' для i==8 и т.д. У вас в коде то же самое, только строка другая.
1
27 / 27 / 18
Регистрация: 13.09.2014
Сообщений: 137
07.12.2014, 23:36  [ТС]
hoggy, TheCalligrapher, спасибо большое! Откуда вы все это знаете)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
07.12.2014, 23:36
Помогаю со студенческими работами здесь

Удалить из массива все элементы встречающиеся менее 3-х раз и вывести размер полученного массива и его содержимое.
Помогите пожалуйста решить задачу!!!!!! Дан целочисленный массив размера n. Удалить из массива все элементы встречающиеся менее 3-х...

Размер массива
Здрасте. Такой вопрос.Можно ли каким то образом вывести число элементов массива,то есть его размер? Допустим int arr; Программа...

Размер массива
Доброго времени! Дан массив классов с некоторыми полями, не суть. Я инициализирую массив сейчас так.(специально упростил) const...

Размер массива
Можно ли изменить размер обычного массива?

Размер статического массива
Можно ли задавть размер статического массива во время работы программы? Если нет, то почему?#include &lt;iostream&gt; using namespace...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
Контроль уникальности заводского номера - вариант №2
Maks 24.03.2026
В отличие от предыдущего варианта добавлено прерывание циклов, также добавлены новые переменные для сохранения контекста ошибки перед прерыванием цикла: Процедура ПередЗаписью(Отказ, РежимЗаписи,. . .
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-text-sdl3-c. zip finish-text-sdl3-cpp. zip
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
Контроль уникальности заводского номера - вариант №1
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере документа выдачи шин для спецтехники с табличной частью. Данные берутся из регистра сведений, по которому настроено. . .
Хочу заставить корпорации вкладываться в здоровье сотрудников: делаю мат модель здравосохранения
anaschu 22.03.2026
e7EYtONaj8Y Z4Tv2zpXVVo https:/ / github. com/ shumilovas/ med2. git
Программный отбор элементов справочника по группе
Maks 22.03.2026
Установка программного отбора элементов справочника "Номенклатура" из модуля формы документа. В качестве фильтра для отбора справочника служит группа номенклатуры. Отбор по наименованию группы. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru