Форум » C/C++ для начинающих (C/C++ for beginners) » -Вывод массива массивов на консоль с использованием только указателей. » Ответить

-Вывод массива массивов на консоль с использованием только указателей.

Сыроежка: Эта тема возникла на основе исходного вопроса на Stackoverflow по ссылке Printing an array sideways (transpose) only using pointers В заголовке темы трудно передать полностью смысл задания, поэтому опишу его более подробно. Имеется массив массивов All, как это задано в исходном вопросе [pre2] 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 }; [/pre2] Последней элемент массива All является нуль-указателем, то есть граничным значением массива. Требуется вывести этот массива на консоль без использования синтаксиса индексации элементов массива, а используя только указатели, операцию разыменования указателей и арифметику указателей. Как сказано в исходном вопросе на Stackoverflow [quote]only using pointers, even int i as an index is unaccepted. [/quote] даже объявления целочисленных переменных, как, например, [pre2] int i;[/pre2] запрещены. Первый элемент каждого под-массива содержит число элементов в под-массиве и не должен выводиться на консоль.. То есть вывод должен выглядеть следующим образом: [pre2] -5 6 1 2 15 4 14 11 -3 7 -2 5 4 1 2 8 2 [/pre2] Сделайте в этом месте паузу и попробуйте написать такую функцию вывода самостоятельно. ---------------------------------------------------------------------------------------------------------------------- Если у вас не получилось, то для начала будет проще написать функцию вывода с использованием индексации массивов, чтобы на основе этой функции написать функцию, которая использует только индексы. Ниже приведена демонстрационная программа. [pre2] #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 ); } [/pre2] Ее вывод на консоль, как и требуется, выглядит следующим образом [pre2] -5 6 1 2 15 4 14 11 -3 7 -2 5 4 1 2 8 2 [/pre2] Сначала в этом предложении [pre2] while ( a[n] ) ++n; [/pre2] определяется сколько актуальных элементов (под-массивов) содержит исходный массив, то есть не является ли он пустой. Это значение также задает число колонок выводимых под-массивов. Если массив содержит под-массивы, то вычисляется максимальное значение для возможного числа строк. [pre2] 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; //...[/pre2] Так как первый (нулевой) элемент каждого под-массива не выводится на консоль, так как он содержит число элементов в под-массиве, то максимальное число строк, заданное в переменной m, уменьшается на единицу. Итак, мы имеем общее число строк и колонок в выводимой таблице. Все, что теперь требуется при выводе конкретного элемента под-массива, - это проверить не выходит ли индекс общего числа строк значение для числа элементов в под-массиве, содержащим этот элемент. Как теперь написать тоже самое, но с использованием только указателей и арифметики указателей? Очевидно, что необходимо найти тот под-массив (указатель на него), который содержит больше всего элементов. Зная этот под-массив, не трудно с помощью указателей записать предложения циклов и выражения обращения к каждому выводимому элементу. Ниже показано, как в этом случае функция вывода на консоль может выглядеть. [pre2] #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 ); } [/pre2] Итак, если исходный массив содержит актуальные элементы [pre2]if ( *a ) { int **m = a; for ( int **j = a + 1; *j; ++j ) { if ( **m < **j ) m = j; } //... [/pre2] мы находим тот под-массив, который содержит максимальное число элементов. А далее, используя арифметику указателей, выводим конкретные элементы под-массивов.-

Ответов - 0



полная версия страницы