On-line: гостей 0. Всего: 0 [подробнее..]
Программисты всех стран, объединяйтесь!

АвторСообщение



ссылка на сообщение  Отправлено: 22.06.18 17:15. Заголовок: -Вывод массива массивов на консоль с использованием только указателей.


Эта тема возникла на основе исходного вопроса на Stackoverflow по ссылке Printing an array sideways (transpose) only using pointers

В заголовке темы трудно передать полностью смысл задания, поэтому опишу его более подробно. Имеется массив массивов All, как это задано в исходном вопросе

 
int A[] = { 5,-5,14,5,2 };
int B[] = { 3,6,11 };
int C[] = { 4,1,-3,4 };
int D[] = { 6,2,7,1,8,2 };
int E[] = { 2,15 };
int F[] = { 3,4,-2 };
int *All[] = { A,B,C,D,E,F,NULL };


Последней элемент массива All является нуль-указателем, то есть граничным значением массива.

Требуется вывести этот массива на консоль без использования синтаксиса индексации элементов массива, а используя только указатели, операцию разыменования указателей и арифметику указателей. Как сказано в исходном вопросе на Stackoverflow


 цитата:
only using pointers, even int i as an index is unaccepted.



даже объявления целочисленных переменных, как, например,

 
int i;


запрещены.

Первый элемент каждого под-массива содержит число элементов в под-массиве и не должен выводиться на консоль..

То есть вывод должен выглядеть следующим образом:

 
-5 6 1 2 15 4
14 11 -3 7 -2
5 4 1
2 8
2


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

----------------------------------------------------------------------------------------------------------------------

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

Ниже приведена демонстрационная программа.

 
#include <stdio.h>

void print_transpose( int *a[] )
{
int n = 0;
while ( a[n] ) ++n;

if ( n )
{
int m = a[0][0];
for ( int j = 1; j < n; j++ )
{
if ( m < a[j][0] ) m = a[j][0];
}

if ( m ) --m;

for ( int i = 0; i < m; i++ )
{
for ( int j = 0; j < n; j++ )
{
if ( i + 1 < a[j][0] )
{
printf( "%2d ", a[j][i + 1] );
}
else
{
printf( "%3c", ' ' );
}
}

putchar( '\n' );
}
}
}

int main( void )
{
int A[] = { 5, -5, 14, 5, 2 };
int B[] = { 3, 6, 11 };
int C[] = { 4, 1, -3, 4 };
int D[] = { 6, 2, 7, 1, 8, 2 };
int E[] = { 2, 15 };
int F[] = { 3, 4, -2 };

int *All[] = { A, B, C, D, E, F, NULL };

print_transpose( All );
}


Ее вывод на консоль, как и требуется, выглядит следующим образом

 
-5 6 1 2 15 4
14 11 -3 7 -2
5 4 1
2 8
2


Сначала в этом предложении

 
while ( a[n] ) ++n;


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

Если массив содержит под-массивы, то вычисляется максимальное значение для возможного числа строк.

 
if ( n )
{
int m = a[0][0];
for ( int j = 1; j < n; j++ )
{
if ( m < a[j][0] ) m = a[j][0];
}

if ( m ) --m;
//...


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

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

Как теперь написать тоже самое, но с использованием только указателей и арифметики указателей?

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

Ниже показано, как в этом случае функция вывода на консоль может выглядеть.

 
#include <stdio.h>

void print_transpose( int *a[] )
{
if ( *a )
{
int **m = a;
for ( int **j = a + 1; *j; ++j )
{
if ( **m < **j ) m = j;
}

for ( int *i = *m + 1 ; i < *m + **m; ++i )
{
for ( int **j = a; *j; j++ )
{
if ( i - *m < **j )
{
printf( "%2d ", *( *j + ( i - *m ) ) );
}
else
{
printf( "%3c", ' ' );
}
}
putchar( '\n' );
}
}
}

int main( void )
{
int A[] = { 5, -5, 14, 5, 2 };
int B[] = { 3, 6, 11 };
int C[] = { 4, 1, -3, 4 };
int D[] = { 6, 2, 7, 1, 8, 2 };
int E[] = { 2, 15 };
int F[] = { 3, 4, -2 };

int *All[] = { A, B, C, D, E, F, NULL };

print_transpose( All );
}


Итак, если исходный массив содержит актуальные элементы

if ( *a ) 
{
int **m = a;
for ( int **j = a + 1; *j; ++j )
{
if ( **m < **j ) m = j;
}
//...


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

Спасибо: 0 
ПрофильЦитата Ответить
Новых ответов нет


Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 3
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет