Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Димка сборник ответов по информатике=).docx
Скачиваний:
3
Добавлен:
25.09.2019
Размер:
130.19 Кб
Скачать

Билет 29

Многомерные массивы так же часто используются, как и одномерные. Вот примеры: в школьных журналах написаны Фамилия и класс; любые базы данных; Вообще, многомерные массивы - это массивы массивов. Т.е. каждый индексный номер содержит массив. Вот пример уже из языка Си:

int i[2][4] = {{1,2,3,4}, {5,6,7,8}};

Т.е. тут мы создаем двумерный массив размером 2х4. Т.е. 2 строчки по 4 элемента каждая.

В принципе, остальное тут так же. Давайте теперь рассмотрим, как в многомерном массиве вводить и выводить элементы:

#include <conio.h>

#include <stdio.h>

int main()

int arr[2][4];

for (int i = 0; i < 2; i++){

for (int j = 0; j < 4;j++ ){

scanf ("%d", &arr[i][j]);

for (int i = 0; i < 2; i++){

for (int j = 0; j < 4;j++ ){

printf ("%d ", arr[i][j]);

printf ("\n");

getch();

return 0;

Все очень похоже на одномерный массив. Только в многомерном массиве мы создаем двойной цикл, первый - это проход по столбцу, а второй - это проход по элементам массива (идем по строке).

Во всех моих примерах при изменении размера многомерного массива, например вместо arr[2][4], хочу сделать arr[7][6]. Так вот, что бы сделать такое изменения придется изменять абсолютно все циклы, так как они ориентируются по старым данным. Но есть способ исправить эту проблему.

Для этого в языке С/C++ есть директива предпроцессора define. Давайте рассмотрим его на примере:

#include <conio.h>

#include <stdio.h>

#define SIZE_A 2

#define SIZE_B 2

int main()

int arr[SIZE_A][SIZE_B];

for (int i = 0; i < SIZE_A; i++){

for (int j = 0; j < SIZE_B;j++ ){

scanf ("%d", &arr[i][j]);

for (int i = 0; i < SIZE_A; i++){

for (int j = 0; j < SIZE_B;j++ ){

printf ("%d ", arr[i][j]);

printf ("\n");

getch();

return 0;

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

Осталось научиться передавать многомерные массивы в функцию. Вот как это делается:

void printArr (int arr[][2]){ //тело; }

Тут обязательным условием является написание во втором индексе количества элементов, иначе компилятор выдаст ошибку. Ах да, вызывается функция из программы, так же как и одномерный массив:

printArr(arr);

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

Задания:

попробуйте попробовать заполнить и вывести массив, но не при помощи индексов, а при помощи указателей. Это довольно сложно, но если долго мучиться, то точно получится

у нас есть массив 4х4. вычислите сумму элементов главной диагонали (1х1, ... , 4х4)

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

Упакованные строки

Упакованные строки - это также массив из 4-ех байтовых ячеек, но схема размещения памяти другая, где вся память ячейки испольуется. В результате для размещения каждого символа необходим 1 байт (8 бит) вместо 4 байтов (32 битов) у распакованных строк. Когда вы используете упакованную строку, то в ячейки будет уже 4 символа, вместо одного у распакованных.

Примечание: Упакованная строка может хранить символы только одно-байтовой кодировки, такие как ASCII, или один из расширенных наборов ASCII.

Например:

Данный пример показывает представление 4-ех байтовой ячейки у упакованной строки. Каждый цветной байт хранит один символ строки. Вся память используется. Упакованный вариант слова "pack":

0111 0000 0110 0001 0110 0011 0110 1011

Когда нужно использовать упакованные строки, а когда распакованные?

Упакованные:

Хранение численных значений в диапозоне 0-255

Хранение ASCII текста

Распакованные:

Хранение численных значений больше 255

Хранение юникод текста или стандарта не ASCII

Как использовать упакованные строки в AMXX скриптинге?

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

Здесь приведены две простые функции для упаковки и распаковки строк:

public strpack(const s_Unpacked[], s_Packed[])

new i

while((s_Packed{i} = s_Unpacked[i++])) {}

public strunpack(const s_Packed[] , s_Unpacked[])

new i

while((s_Unpacked[i] = s_Packed{i++})) {}

При объявления переменной нужно указывать желательный размер и добавлять 'char' идентификатор после него. Вы также должны указывать символ '!' перед присвоением строки переменной.

Пример:

Код: Выделить всё

new s_String[11 char] = !"The string"

Доступ к ячейке строки похож на доступ к элементу распакованной строки, только вместо [] нужно использовать {}.

Пример:

Код: Выделить всё

Распакованная строка = s_String[5]

Упакованная строка = s_String{5}

Сколько памяти я съэкономлю при использовании упакованных строк?

Количество сохраненной памяти меняется в зависимости от числа и размера строк, используемых в плагине. Для определения используемой памяти был написан плагин. По умолчанию, он использует упакованные строки. Для того чтобы получить результат использования распакованных строк нужно закомментировать строчку:

Код: Выделить всё

#defined PACKED_STRINGS

Код: Выделить всё

#include <amxmodx>

#define PLUGIN "Packed vs Unpacked"

#define VERSION "1.0"

#define AUTHOR "bugsy"

#define PACK_STRINGS

#define NUM_STRINGS 20

#define MAX_STRING_SIZE 512

#if defined PACK_STRINGS

new g_szUnpackBuffer[MAX_STRING_SIZE];

new g_szStrings[NUM_STRINGS][MAX_STRING_SIZE char]

#else

new g_szStrings[NUM_STRINGS][MAX_STRING_SIZE]

#endif

public plugin_init()

register_plugin(PLUGIN, VERSION, AUTHOR)

public plugin_cfg()

for ( new iTest = 0 ; iTest < NUM_STRINGS ; iTest++ )

#if defined PACK_STRINGS

g_szStrings[iTest] = !"Packed strings"

strunpack( g_szStrings[iTest] , g_szUnpackBuffer );

server_print( "%d = %s" , iTest , g_szUnpackBuffer );

#else

g_szStrings[iTest] = "Unpacked strings";

server_print( "%d = %s" , iTest , g_szStrings[iTest] );

#endif

#if defined PACK_STRINGS

public strunpack( szPacked[] , szUnpacked[] )

new i;

while((szUnpacked[i] = szPacked{i++})){}

#endif