Rating@Mail.ru

Форум по операционной системе GNU/Linux и свободному программному обеспечению


Текущее время: 19 июн 2018, 23:23

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 94 ]  На страницу 1, 2, 3, 4, 5 ... 10  След.
Автор Сообщение
Непрочитанное сообщениеДобавлено: 09 окт 2013, 21:33 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 10806
Откуда: Харьков
Мне выпала необходимость выполнить небольшой учебный курс для пары-тройки учеников, по использованию C в Linux... детали не важны ;-) .
И по ходу я придумываю не совсем тривиальные примеры, заставляющие детальнее подумать над синтаксическими правилами C ... хотя, казалось бы, чего там думать?
Но примеры получаются временами ... смешные. И я решил показывать их здесь. В расчёте на то, что кто-то, у кого есть любопытные примерчики, тоже покажет их здесь... ;-)

Кроме того, предлагаю всем, у кого возникнут вопросы и сомнения по C, писать о них тоже сюда - вместе разберёмся.


Вернуться к началу
 Профиль Отправить личное сообщение  
 
Непрочитанное сообщениеДобавлено: 09 окт 2013, 21:37 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 10806
Откуда: Харьков
Olej писал(а):
Но примеры получаются временами ... смешные.


Типы данных (файл 1.c):
Код:
#include <stdio.h>

// скалярные типы данных:
int main () {
   int i = 123;
   short is = 12;
   char ic1 = 3, ic2 = '2';
   long il = 12345;
   long long ill = 123456;

   printf( " %d \n %d \n %d \n %d \n %lx \n %llx \n",
              i,    is,   ic1,  ic2,  il,    ill );
   printf( "%c => %i\n", ic2, ic2 );

   double rd = 3.14159265358979323846264338327950288419716939937510;
   float rf = rd;
#define FMT "%30.27f"
   printf( FMT" - "FMT" = "FMT"\n", rd, rf, rd - rf );

   return 0;
}


Выполнение:
Код:
bash-4.2$ ./exe1
 123
 12
 3
 50
 3039
 1e240
2 => 50
 3.141592653589793115997963469 -  3.141592741012573242187500000 = -0.000000087422780126189536531


Последний результат хорош:
A = A;
A - A ... - это вовсе не равно 0 ;-)


Вернуться к началу
 Профиль Отправить личное сообщение  
 
Непрочитанное сообщениеДобавлено: 09 окт 2013, 21:41 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 10806
Откуда: Харьков
Olej писал(а):
Но примеры получаются временами ... смешные.


Следующая группа операций: агрегирование данных из простых скалярных (файл 2.c):
Код:
bash-4.2$ cat 2.c
#include <stdio.h>
#include <string.h>
#include <wchar.h>

// агрегаты данных:
int main () {

   int ai[] = { 1, 2, 3, 4, 5 }, ni, j;
   printf( "%d => ", ni = sizeof( ai ) / sizeof( ai[ 0 ] ) );
   for( j = 0; j < ni; j++ ) printf( "%d, ", ai[ j ] );
   printf( "\n" );

   // разница в представлении
   char ac[] = { '1', '2', '3', '4', '5', 0, '6', '\0' };
   printf( "%d (строка %d) => ", ni = sizeof( ac ) / sizeof( ac[ 0 ] ), strlen( ac ) );
   for( j = 0; j < ni; j++ ) printf( "%d, ", ac[ j ] );
   printf( "\n" );

   // присвоение структурных данных
   struct ss {
      int a1, a2, a3;
   } vss1 = { 1, 2, 3 }, vss2 = { 3, 2, 1 };
   vss1 = vss2;
   printf( " %d %d %d \n", vss1.a1, vss1.a2, vss1.a3 );

   // наложение разнородныз данных
   struct su {
      union {
         char c[ 12 ];     
         short s[ 6 ];
         float f[ 3 ];
      };
   } su1 = {{{ '1', '2', '3', '4', '5', '6', 0, 0, 0, 0, 0, 0 }}};
   printf( "размер структуры %d байт\n", sizeof( su1 ) );
   for( j = 0; j < sizeof( su1.c ) / sizeof( su1.c[ 0 ] ); j++ )
      printf( "%d, ", su1.c[ j ] );
   printf( "\n" );
   for( j = 0; j < sizeof( su1.s ) / sizeof( su1.s[ 0 ] ); j++ )
      printf( "%d, ", su1.s[ j ] );
   printf( "\n" );
   for( j = 0; j < sizeof( su1.f ) / sizeof( su1.f[ 0 ] ); j++ )
      printf( "%f, ", su1.f[ j ] );
   printf( "\n" );
   char *p = (char*)&su1;
   printf( "адрес=%p : %s, длина %d символов\n", p, p, strlen( p ) );
   
   // разница длины UTF-8 строки (русскоязычной) в байтах и символах
   const char buf[] = "русскоязычная строка";
   printf( "строка: '%s', длина %d ,байт\n", buf, strlen( buf ) );

   return 0;
}


Результатом это имеет:
Код:
bash-4.2$ ./exe2
5 => 1, 2, 3, 4, 5,
8 (строка 5) => 49, 50, 51, 52, 53, 0, 54, 0,
 3 2 1
размер структуры 12 байт
49, 50, 51, 52, 53, 54, 0, 0, 0, 0, 0, 0,
12849, 13363, 13877, 0, 0, 0,
0.000000, 0.000000, 0.000000,
адрес=0xbf8c7e34 : 123456, длина 6 символов
строка: 'русскоязычная строка', длина 39 ,байт

Любопытный последний результат: глаза явно видят 20 букв, а программа говорит 39 байт ;-)


Вернуться к началу
 Профиль Отправить личное сообщение  
 
Непрочитанное сообщениеДобавлено: 09 окт 2013, 21:44 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 10806
Откуда: Харьков
Структуры управления (файл 3.c):
Код:
bash-4.2$ cat 3.c
#include <stdio.h>

// структуры управления:
int main () {
   short s1[] = { 1, 2, 3, 4, 5, 6 },
         ns = sizeof( s1 ) / sizeof( s1[ 0 ] ),
         i;
   for( i = 0; i < ns; i++ )
      printf( "%d, ", s1[ i ] );
   printf( "\n" );

   i = -1;
   while( ++i < ns ) {
      printf( "%d, ", s1[ i ] );
   }
   printf( "\n" );

   i = 0;
   do {
      printf( "%d, ", s1[ i ] );
   } while( i++ < ns - 1 );      // !!!
   printf( "\n" );

   for( i = 0; i < ns; i++ ) {
      printf( "%d : ", s1[ i ] );
      switch( s1[ i ] ) {
         case 1:
         case 2:
            printf( "%s ", "мало" );
            break;
         case 3:
            printf( "%s ", "нормально" );
            break;
         case 4:
            printf( "%s ", "много" );
            break;
         default:
            printf( "%s ", "чрезмерно" );
         case 5:
            printf( "%s", "много " );
      }
      printf( "\n" );
   
   }

   return 0;
}


Здесь меньше веселья ... но всё же:
Код:
bash-4.2$ ./exe3
1, 2, 3, 4, 5, 6,
1, 2, 3, 4, 5, 6,
1, 2, 3, 4, 5, 6,
1 : мало
2 : мало
3 : нормально
4 : много
5 : много
6 : чрезмерно много


Вернуться к началу
 Профиль Отправить личное сообщение  
 
Непрочитанное сообщениеДобавлено: 09 окт 2013, 21:46 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 10806
Откуда: Харьков
Последняя на сегодня группа развлечений ;-) - вызовы функций:
Код:
bash-4.2$ cat 4.c
#include <stdio.h>

typedef int (*summ_t) ( int );
int summ2( int x ) { return x + 2; }
int summ3( int x ) { return x + 3; }
int summ4( int x ) { return x + 4; }

summ_t funcs[] = { summ2, summ3, summ4 };

int call( summ_t func, void *data ) {
   return func( *(int*)data );
}

void set1( int x ) { x++; }
void set2( int* x ) { (*x)++; }

//------------------------------------------

#define N 10
typedef struct {
   int x[ N ];
} astruct_t;

astruct_t revers( astruct_t s ) {
   int n, i, j;
   n = sizeof( s ) / sizeof( int );
   for( i = 0, j = n - 1; i < j; i++, j-- ) {
      int var = s.x[ i ];
      s.x[ i ] = s.x[ j ];
      s.x[ j ] = var;
   }
   return s;
}

void show_ba( astruct_t* b, astruct_t* a ) {
   int i;
   printf( "before: " );
   for( i = 0; i < N; i++ )
      printf( "%d%s", b->x[ i ], i != N - 1 ? ", " : ""  );
   printf( " | after: " );
   for( i = 0; i < N; i++ )
      printf( "%d%s", a->x[ i ], i != N - 1 ? ", " : ""  );
   printf( "\n" );
}

//------------------------------------------

void mod( astruct_t* s ) {
   int n = sizeof( *s ) / sizeof( int );
   void pow2( void ) {
      int i;
      for( i = 0; i < n; i++ )
         s->x[ i ] *= s->x[ i ];
   }
   pow2();
   return;
}

//------------------------------------------


// функции и вызовы:
int main () {
   int i;
//------------------------------------------
   for( i = 0; i < sizeof( funcs ) / sizeof( funcs[ 0 ] ); i++ )
      printf( "%d ", funcs[ i ]( i ) );
   printf( "\n" );
//------------------------------------------
   summ_t summ2_2 = summ2;
   printf( "%d ", summ2_2( 7 ) );
   for( i = 0; i < sizeof( funcs ) / sizeof( funcs[ 0 ] ); i++ ) {
      summ2_2 = funcs[ i ];
      printf( "%d ", summ2_2( 7 ) );
   }
   printf( "\n" );
//------------------------------------------
   i = 3;
   int *pi = &i;
   printf( "косвенный вызов: %d\n", call( summ3, &i ) );
   set1( i );
   printf( "передача параметра: по значению -> %d,", i );
   set2( pi );
   printf( " по ссылке -> %d\n", i );
//------------------------------------------
   astruct_t before = {{ 1, 2, 3, 4, 5, 6, 7 }},
             after = {{ 10*(0) }};
   show_ba( &before, &after );
   printf( "revers ... ... ...\n" );
   after = revers( before );
   show_ba( &before, &after );
//------------------------------------------
   after = before;
   mod( &after );
   printf( "вложенные описания функций (GCC):\n" );
   show_ba( &before, &after );
//------------------------------------------
   return 0;
}


И что из этого получается:
Код:
bash-4.2$ ./exe4
2 4 6
9 9 10 11
косвенный вызов: 6
передача параметра: по значению -> 3, по ссылке -> 4
before: 1, 2, 3, 4, 5, 6, 7, 0, 0, 0 | after: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
revers ... ... ...
before: 1, 2, 3, 4, 5, 6, 7, 0, 0, 0 | after: 0, 0, 0, 7, 6, 5, 4, 3, 2, 1
10
вложенные описания функций (GCC):
before: 1, 2, 3, 4, 5, 6, 7, 0, 0, 0 | after: 1, 4, 9, 16, 25, 36, 49, 0, 0, 0


Вернуться к началу
 Профиль Отправить личное сообщение  
 
Непрочитанное сообщениеДобавлено: 09 окт 2013, 21:52 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 10806
Откуда: Харьков
Кроме того, на GCC в Linux "свет клином не сошёлся" (особенно последний 1-2 года ;-) ), поэтому всё это можно (попробовать!) собрать новым компилятором Clang:
Код:
bash-4.2$ make clang
clang -xc -Wall 1.c -o exe1l
clang -xc -Wall 2.c -o exe2l
clang -xc -Wall 3.c -o exe3l
clang -xc -Wall 4.c -o exe4l
4.c:50:21: error: expected ';' at end of declaration
   void pow2( void ) {
                    ^
                    ;
1 error generated.
make: *** [exe4l] Ошибка 1

... и убедиться, что не все расширения GCC Clang готов проглотить, в частности, вложенные определения функций ему не понравились... Или, по крайней мере, это не так просто, и должно оговариваться как-то опциями.
Иначе не очень понятно, как они тогда с помощью Clang скомпилировали ядро Linux, о чём сообщалось несколько месяцев назад?

Но здесь же можно убедиться, что программы, собранные Clang, выполняются точно так же как GCC, а заодно можно их сравнить по параметрам...
Хотя бы, для начала, в том, что размером то они отличаются ;-) :
Код:
bash-4.2$ ls -l exe*
-rwxrwxr-x 1 olej olej 5206 окт.   9 21:52 exe1
-rwxrwxr-x 1 olej olej 5074 окт.   9 21:48 exe1l
-rwxrwxr-x 1 olej olej 6187 окт.   9 21:52 exe2
-rwxrwxr-x 1 olej olej 6155 окт.   9 21:48 exe2l
-rwxrwxr-x 1 olej olej 5545 окт.   9 21:52 exe3
-rwxrwxr-x 1 olej olej 5430 окт.   9 21:48 exe3l
-rwxrwxr-x 1 olej olej 7233 окт.   9 21:52 exe4


P.S. Для любителей поразвлекаться архив всего рассказанного выше - прилагается:


Вложения:
examples.tgz [2.95 КБ]
Скачиваний: 578
Вернуться к началу
 Профиль Отправить личное сообщение  
 
Непрочитанное сообщениеДобавлено: 15 окт 2013, 14:47 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 10806
Откуда: Харьков
Подсказали (в тему):
- есть такая книжка (даже в переводе):
Цитата:
Керниган Б., Ритчи Д., Фьэр А.
Язык программирования Си. Задачи по языку Си
Пер.с англ. Д.Б.Подшивалова и В.А.Иващенко. -
М.:Финансы и статистика, 1985. - с.193-278.

Она вдвое толще, чем оригинал K&R - это те задачи и упражнения, что Фьэр добавил.
(как утверждает человек, которому я не могу не доверять ;-) - это лучший сборник задач)

Вот электронный вариант именно самого задачника: А.Фьюэр, Задачи по языку С.
Пользуйтесь!

P.S. Мне сообщили, что в некоторых браузерах (Safari на MacOS) этот URL не открывается (что-то в записях DNS серверов намудрено).
Этот URL - это ХПИ (Харьковский Политехнический Институт) ... сейчас он как-то по-другому называется ... университе-е-е... ;-) (но DNS нормально зарегистрировать не в состоянии).
Тогда можете открывать этот текст по IP адресу:
Код:
$ nslookup khpi-iip.mipk.kharkiv.edu
Server:      192.168.1.1
Address:   192.168.1.1#53

Non-authoritative answer:
Name:   khpi-iip.mipk.kharkiv.edu
Address: 194.44.157.122


Вернуться к началу
 Профиль Отправить личное сообщение  
 
Непрочитанное сообщениеДобавлено: 15 окт 2013, 14:53 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 10806
Откуда: Харьков
Olej писал(а):
(как утверждает человек, которому я не могу не доверять ;-) - это лучший сборник задач)


Цитата:
Процесс изучения языка программирования можно представить как последовательное прохождение трех этапов (каждый этап, несомненно, может повторяться неоднократно). Первый этап состоит в освоении синтаксиса языка, по крайней мере настолько, что транслятор перестает "ругаться", обнаружив в вашей программе бессмысленные конструкции. Второй этап состоит в осмыслении правильно построенных транслятором конструкций языка. На третьем этапе вырабатывается определенный стиль программирования, соответствующий духу языка, т.е. умение писать ясные, краткие и правильные программы.

Головоломки в этой книге предназначены для того, чтобы помочь читателю на втором этапе обучения языку. Они бросают вызов искусству владения читателем основными правилами языка, заводят его в "редко посещаемые закоулки" языка, подводят к граничным условиям и знакомят с немногими откровенными ловушками. (Конечно, С, как всякий язык программирования, имеет свою долю неясностей, которая познается на опыте.)

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


Это из предисловия к этому сборнику задач, которое само по себе интересно прочитать.


Вернуться к началу
 Профиль Отправить личное сообщение  
 
Непрочитанное сообщениеДобавлено: 15 окт 2013, 15:13 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 10806
Откуда: Харьков
Olej писал(а):
Этот URL - это ХПИ (Харьковский Политехнический Институт) ... сейчас он как-то по-другому называется ...

Там вообще шикарная (по подборке) библиотека: Каталог библиотеки кафедры "Информатика и интеллектуальная собственность"
Изображение
- по операционным системам
- ... особенно по UNIX
- особенно все знаменитые статьи Эдсгара Дэйкстры в переводе на русский - это обязаны все читать!
Изображение
Изображение
- и особенно Э.Дейкстра Взаимодействие последовательных процессов, что есть вообще просто классика!


Вернуться к началу
 Профиль Отправить личное сообщение  
 
Непрочитанное сообщениеДобавлено: 15 окт 2013, 20:13 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 10806
Откуда: Харьков
Olej писал(а):
P.S. Мне сообщили, что в некоторых браузерах (Safari на MacOS) этот URL не открывается (что-то в записях DNS серверов намудрено).
Этот URL - это ХПИ (Харьковский Политехнический Институт) ... сейчас он как-то по-другому называется ... университе-е-е... ;-) (но DNS нормально зарегистрировать не в состоянии).
Тогда можете открывать этот текст по IP адресу:


Наблюдаемое с этим URL не поддаётся объяснению, это нельзя понять:
- обращение из Opera (v.12.16) по имени http://khpi-iip.mipk.kharkiv.edu/librar ... index.html заканчивается ошибкой 404
- обращение из Firefox (v.24.0) , в тот же момент времени, по http://khpi-iip.mipk.kharkiv.edu/librar ... index.html - ОК и мгновенно, влёт...
- обращение из Opera по имени (IP) http://194.44.157.122/library/extent/pr ... index.html - всё OK

Я такого цирка ещё не видел :-o


Вернуться к началу
 Профиль Отправить личное сообщение  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 94 ]  На страницу 1, 2, 3, 4, 5 ... 10  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB
[ Time : 0.142s | 22 Queries | GZIP : On ]