А. Богатырев - Руководство полного идиота по программированию (на языке Си), страница 9
Описание файла
PDF-файл из архива "А. Богатырев - Руководство полного идиота по программированию (на языке Си)", который расположен в категории "". Всё это находится в предмете "информатика" из 1 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .
Просмотр PDF-файла онлайн
Текст 9 страницы из PDF
*/file:///Volumes/WININSTALL/assets/materials_informatiks.html57/6803.06.2015Андрей Богатырев. Руководство полного идиота<br> по программированию (на языке Си)/* ФУНКЦИЯ ПОДСЧЕТА ДЛИНЫ СТРОКИ.Как уже объяснялось, строка текста - это массив char,в конце которого помещен символ '\0'.Сам символ \0 не считается.*/int strlen(char s[]){/* функция от массива буквint counter = 0;/* счетчик и одновременно индексwhile(s[counter] != '\0')counter++;return counter;*/*//* пока не встретился признак конца текста *//* посчитать символ*//* сколько символов, отличных от '\0' */}/* ФУНКЦИЯ ПЕЧАТИ СТРОКИ.Печатаем каждый элемент массива как символ при помощи putchar(c).Как только встречаем элемент массива, равный '\0' - останавливаемся.Заметьте, что при наличии завершающего символа нам НЕ НАДОпередавать в функцию размер массива, он нам неинтересен.В конце эта функция переводит строку.*/int putstr(char s[]){int i = 0;/* индекс */while(s[i] != '\0'){putchar(s[i]);i++;}putchar('\n');return i;}/* ТЕПЕРЬ МЫ ЗАНИМАЕМСЯ ФУНКЦИЕЙ ИНВЕРТИРОВАНИЯ.Для этого нам нужна вспомогательная функция:сдвиг элементов массива на 1 влево.Исходный массив: A B C D E F<---------Результат:BCDEFFПоследний элемент удваивается.n - размер массива.Функция работает так:Исходный массив: A B C D E F n=6После i=1BBCDEFПосле i=2BCCDEFПосле i=3BCDDEFПосле i=4BCDEEFПосле i=5BCDEFFi=6 ==> остановка.*/void shiftLeft(char s[], int n){int i;for(i=1; i < n; i++)s[i-1] = s[i];}/* Функция инвертирования.file:///Volumes/WININSTALL/assets/materials_informatiks.html58/6803.06.2015Андрей Богатырев.
Руководство полного идиота<br> по программированию (на языке Си)Идея такова:- если длина массива меньше или равна 1, то инвертировать нечего,ибо массив состоит из 1 или 0 элементов.- если длина массива > 1, тоa) Спасти нулевой элемент массива.ABCDEF||Vtmpb) Сдвинуть массив влевоBCDEFFc) В последний элемент массива поместить спасенный нулевой элемент.tmp|VBCDEFAd) Инвертировать начало массива длиной n-1.{B C D E F}AПолучится:FEDCBAЧто и требовалось.s[] - массив,n - его длина.*/void reverse(char s[], int n){char tmp;if(n <= 1)return;/* нечего инвертировать */tmp = s[0];shiftLeft(s, n);s[n-1] = tmp;/* спасти *//* сдвинуть *//* переместить */reverse(s, n-1);/* инвертировать начало */}/* ВТОРАЯ ВЕРСИЯ нерекурсивна.
Рекурсия заменена циклом.Длина начала массива, которую надо инвертировать,вынесена на переменную length.*/void reverse1(char s[], int n){char tmp;int length;for(length=n; length > 1; --length){tmp = s[0];shiftLeft(s, length);s[length-1] = tmp;}}char testString[] = "abcdefghijklmnopqrstuvwxyz";/* Если не задать размер массива, он будет вычислен компилятором автоматически.Он будет равен числу букв внутри "..." ПЛЮС одна ячейка для невидимогоfile:///Volumes/WININSTALL/assets/materials_informatiks.html59/6803.06.2015Андрей Богатырев.
Руководство полного идиота<br> по программированию (на языке Си)символа '\0' на конце.В данном случае это 27.*/void main(){int len;len = strlen(testString);/* вычислить длину строки: 26 ('\0' на конце не считается) */printf("Строка для теста: \"%s\", ее длина %d\n",testString,len);/* Обратите внимание на два момента:- строку (массив char) следует печатать по формату %s- чтобы внутри "..." напечатать символ "надо изобразить его как \"А чтобы в putchar напечатать символ ' надо писать putchar('\'');*//* Первая инверсия */reverse(testString, len);putstr("Инвертированная строка:");putstr(testString);/* Вторая инверсия - возвращает в исходное состояние */reverse1(testString, len);putstr("Инвертированная в исходное состояние строка:");putstr(testString);}19_1.c/* Еще более простой вариант решения:просто обменивать элементы местами.ABCDEFGHIJJBCDEFGHIA||JBCDEFGHIAJICDEFGHBA||JICDEFGHBAJIHDEFGCBA||----><-----этипотом этипотом этиJIHDEFGCBAJIHGEFDCBA||JIHGEFDCBA||JIHGFEDCBAстоп.*/#include <stdio.h>/* Обмен значений двух переменных типа char */void swap(char *s1, char *s2){char c;file:///Volumes/WININSTALL/assets/materials_informatiks.html60/6803.06.2015Андрей Богатырев.
Руководство полного идиота<br> по программированию (на языке Си)c = *s1; *s1 = *s2; *s2 = c;}void reverse(char s[], int n){int first, last;first = 0;last = n-1;/* индекс первого элемента массива *//* индекс последнего элемента массива */while(first < last){/* пока first левее last */swap(&s[first], &s[last]);first++;/* сдвинуть вправо */last--;/* сдвинуть влево */}}char testString[] = "abcdefghijklmnopqrstuvwxyz.";void main(){int len;len = strlen(testString);/* Есть такая стандартная функция */reverse(testString, len);printf("Инвертированная строка: %s\n", testString);}19_2.c/* Еще один вариант решения:сформировать ответ в дополнительном массиве,а потом скопировать его на прежнее место.*/#include <stdio.h>char testString[] = "abcdefghijklmnopqrstuvwxyz.";/* Конструкция sizeof(массив)/sizeof(массив[0])выдает размер массива, даже если он не был явно объявлен.Эта конструкция применяется (чаще всего) для задания массивас размером, равным размеру уже объявленного массива.*/char tempString[ sizeof(testString) / sizeof(testString[0]) ];void reverse(char s[], int n){int i;/* вывернуть, результат в tempString[] */for(i=0; i < n; i++)tempString[n-1-i] = s[i];tempString[n] = '\0';/* признак конца строки *//* скопировать на старое место */for(i=0; i < n; i++)s[i] = tempString[i];s[n] = '\0';/* признак конца строки */}void main(){int len;file:///Volumes/WININSTALL/assets/materials_informatiks.html61/6803.06.2015Андрей Богатырев.
Руководство полного идиота<br> по программированию (на языке Си)len = strlen(testString);/* Есть такая стандартная функция */reverse(testString, len);printf("Инвертированная строка: %s\n", testString);}19_3.c/* Задача инвертирования массива целых чисел */#include <stdio.h>int arr[] = {1, 5, 10, 15, 20, 25, 30};int arrLen = sizeof(arr) / sizeof(arr[0]);/* размер массива *//* Распечатка массива в строку */void printit(int row[], int n){int i;for(i=0; i < n; i++){printf("%d", row[i]);if(i == n-1) putchar('\n');elseputchar(' ');}}/* Печать отступа. Отладочная функция */void printShift(int n){n = arrLen - n;while(n > 0){printf(" ");n--;}}/* Сдвиг массива */void shiftleft(int row[], int n){int i;for(i=1; i < n; i++)row[i-1] = row[i];}/* Инвертирование */void reverse(int row[], int n){int pocket;printShift(n);/* трассировка */printf("CALLED reverse(row, %d)\n", n); /* трассировка */if(n <= 1){printShift(n);/* трассировка */printf("return from reverse(row, %d);\n", n); /* трассировка */return;}pocket = row[0];shiftleft(row, n);row[n-1] = pocket;printShift(n);printit(arr, arrLen);/* трассировка *//* трассировка */reverse(row, n-1);file:///Volumes/WININSTALL/assets/materials_informatiks.html62/6803.06.2015Андрей Богатырев.
Руководство полного идиота<br> по программированию (на языке Си)printShift(n);/* трассировка */printf("all done; return from reverse(row, %d);\n", n); /* трассировка */}void main(){reverse(arr, arrLen);printit(arr, arrLen);}20.c/* Задача: написать функцию для распечатки массива целых чиселв виде таблицы в columns столбцов.При этом порядок элементов должен быть таков:012345678910*//* Пусть в массиве n элементов.Если n < columns, то мы получаем такую ситуацию (n=2, columns=4)01пустопустоПоэтомуif(n < columns) columns = n;Далее, прямоугольная таблица с columns столбцами и lines строкамиможет содержать максимум columns*lines элементов.
Поэтому:columns*lines >= nВычислим число строк.Нам нужно минимальное целое число строк, такое чтоlines >= n/columnsТакое число вычисляется по формулеlines = (n + (columns - 1)) / columns;где деление целочисленное.Далее надо только вывести формулу для индекса элемента в массивев зависимости от номера строки (y) и столбца (x).index(x, y) = (x * lines + y);причем если index >= n, то ничего не выводить*/#include <stdio.h>int array[100];void printArray(int a[], int n, int columns){int lines;/* число строк */int x, y;int index;/* номер колонки, номер строки - с нуля *//* индекс элемента в массиве */file:///Volumes/WININSTALL/assets/materials_informatiks.html63/6803.06.2015Андрей Богатырев.
Руководство полного идиота<br> по программированию (на языке Си)if(n < columns) columns = n;lines = (n + (columns-1)) / columns;/* Используем вложенные циклы: по строкам, а внутри - по столбцам */for(y=0; y < lines; y++){for(x=0; x < columns; x++){index = x * lines + y;if(index >= n) /* элемент за концом массива */break; /* прервать строку *//* break выводит толькоиз внутреннего цикла (по столбцам) *//* сделать отступ в следующую колонку */if(x != 0) putchar('\t');printf("%02d|%d", index, a[index]);/* Формат %02d заставляет печатать целое числос использованием ДВУХ цифр, причем есличисло состоит из одной цифры, то спередиприписывается нуль.*/}putchar('\n'); /* перейти к следующей строке */}}void main(){int i, cols;/* Инициализация значений элементов массива */for(i=0; i < 100; i++)array[i] = i + 1;for(cols=4; cols <= 13; cols++){printf("\t\t* * * ТАБЛИЦА В %d СТОЛБЦОВ * * *\n", cols);printArray(array, 77, cols);putchar('\n');}}20_1.c#include <stdio.h>main(){int x, y;int COLUMNS = 11;int LINES = 10;int value;/* цикл по строкам */for(y=0; y < LINES; y++){/* цикл по столбцам */for(x=0; x < COLUMNS; x++){/* что напечатать */value = LINES * x + y;/* если это не нулевой столбец, то перейтив следующую колонкуfile:///Volumes/WININSTALL/assets/materials_informatiks.html64/6803.06.2015Андрей Богатырев.