Начинаю осваивать C, появляются вопросы...

Модератор: Модераторы разделов

Аватара пользователя
devilr
Сообщения: 3138
ОС: Mandriva => Gentoo (~amd64)

Re: Начинаю осваивать C, появляются вопросы...

Сообщение devilr »

QWERTYASDF писала:
04.09.2018 00:11
А консольные программы сейчас тоже атавизм что-ли?
Почему? Я этого не говорил. :)
Просто программ с графическим интерфейсом сейчас больше и они на виду. И, именно их их пытаются писать новички, вскоре после того, как освоют всякие "сортировки пузырьком" и "хайнойские башни". А в графических приложениях возникающие ошибки анализируют и исправляют внутри программы. Причём, чаще всего в них вы в явном виде никогда и не вернёте какое-то значение, отличного от нулевого кода завершения.
Допустим, на любимом мною Qt простая программа выглядит как-то так

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

 #include <QApplication>
 #include <QLabel>
 int main(int argc, char *argv[])
 {
     QApplication app(argc, argv);
     QLabel *label = new QLabel("Hello Qt!");
     label->show();
     return app.exec();
 }
и вы там в явном виде не вернёте код ошибки. Хотя он будет, конечно.
Мудрость приходит с возрастом.
Иногда возраст приходит один.
Спасибо сказали:

Аватара пользователя
devilr
Сообщения: 3138
ОС: Mandriva => Gentoo (~amd64)

Re: Начинаю осваивать C, появляются вопросы...

Сообщение devilr »

Bizdelnick писал:
04.09.2018 00:24
Посмотрите в словаре значение слова «атавизм» в таком случае.
Иное значение - атавизмом называют нечто, изжившее себя. Пример: "Пользоваться пейджером - атавизм XXI века!"
Атавизм - ведь это не только биологический термин.
Мудрость приходит с возрастом.
Иногда возраст приходит один.
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 18483
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: Начинаю осваивать C, появляются вопросы...

Сообщение Bizdelnick »

devilr писал(а):
04.09.2018 00:27
Просто программ с графическим интерфейсом сейчас больше и они на виду. И, именно их их пытаются писать новички, вскоре после того, как освоют всякие "сортировки пузырьком" и "хайнойские башни".
Новички пишут, как правило, 100500й гуй к ffmpeg или чему-нибудь подобному. И обрабатывают код его возврата. Безо всяких сортировок и башен.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
devilr
Сообщения: 3138
ОС: Mandriva => Gentoo (~amd64)

Re: Начинаю осваивать C, появляются вопросы...

Сообщение devilr »

Bizdelnick писал:
04.09.2018 00:36
Новички пишут, как правило, 100500й гуй к ffmpeg или чему-нибудь подобному. И обрабатывают код его возврата. Безо всяких сортировок и башен.
Обрабатывают код возврата ffmpeg. Однако сам "гуй", скорее всего, вернёт 0 в случае удачи и -1 в случае ошибки. Или, вообще, выкинут какое нибудь окно с текстом ошибки и завершат свою программу с кодом 0.
Впрочем, возможно, в вашем окружении программисты кодом возврата "гуя" активно пользуются. В моём - нет.
Мудрость приходит с возрастом.
Иногда возраст приходит один.
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 18483
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: Начинаю осваивать C, появляются вопросы...

Сообщение Bizdelnick »

devilr писал(а):
04.09.2018 00:28
Атавизм - ведь это не только биологический термин.
Изначально — именно биологический, его переносное значение непосредственно связано с прямым. Если посмотреть словарь Ожегова или Ушакова, то там вообще никаких переносных значений не фигурирует. А безвестный автор вики-статьи — так себе авторитет.
devilr писал(а):
04.09.2018 00:43
Впрочем, возможно, в вашем окружении программисты кодом возврата "гуя" активно пользуются.
Вообще-то да. Потому что GUI-программы могут запускаться не сами по себе, а другими программами (чаще всего врапперами на shell, но не только). Разные программы, не только zenity и подобные. И, как верно отметили выше, ffmpeg и другие CLI-утилиты вовсе не являются атавизмом.
К тому же, можно подумать, весь мир программ ограничивается GUI-приложениями и консольными утилитами. Как насчёт системных сервисов? Должна система инициализации понимать, штатно завершился демон или нештатно?
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
Hephaestus
Сообщения: 3729
Статус: Многоуважаемый джинн...
ОС: Slackware64-14.1/14.2

Re: Начинаю осваивать C, появляются вопросы...

Сообщение Hephaestus »

QWERTYASDF писала:
03.09.2018 23:07
Ну так получается, что можно просто...
В общем случае, да. Можно. Если не напрягают предупреждения при компиляции.
Хотя я, например, стараюсь, чтобы сборка была "чистой" - без предупреждений. Ну, вот, нравится мне так.
К тому же, если игнорировать предупреждения (особенно когда их много), есть риск пропустить что-нибудь важное (что-нибудь на тему приведения типов или указателей, или неинициализированных переменных, что может в дальнейшем привести к трудноуловимым ошибкам).
Пускай скрипят мои конечности.
Я - повелитель бесконечности...
Мой блог
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 18483
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: Начинаю осваивать C, появляются вопросы...

Сообщение Bizdelnick »

Hephaestus писал:
04.09.2018 09:52
QWERTYASDF писала:
03.09.2018 23:07
Ну так получается, что можно просто...
В общем случае, да. Можно. Если не напрягают предупреждения при компиляции.
Можно, но совсем не нужно. В таком случае программа вернёт мусорное значение, скорее всего отличное от 0. Тип main должен быть int, return обязателен.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
Hephaestus
Сообщения: 3729
Статус: Многоуважаемый джинн...
ОС: Slackware64-14.1/14.2

Re: Начинаю осваивать C, появляются вопросы...

Сообщение Hephaestus »

Bizdelnick писал:
04.09.2018 10:09
В таком случае программа вернёт мусорное значение, скорее всего отличное от 0.
Да, наверное. Но в этом случае возвращаемое значение никого и не интересует.
Согласитесь, странно было бы использовать синтаксис без return и без указания типа возвращаемого значения, но при этом всё-таки рассчитывать на возврат какого-то значения.

Кстати, во втором издании K&R используется именно такой синтаксис.

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

main()
{
.....
.....
}
без указания типа main и без return.
И мне припоминается, даже был компилятор соответствующей версии, который нормально это переваривал. Без варнингов.
Пускай скрипят мои конечности.
Я - повелитель бесконечности...
Мой блог
Спасибо сказали:

Аватара пользователя
devilr
Сообщения: 3138
ОС: Mandriva => Gentoo (~amd64)

Re: Начинаю осваивать C, появляются вопросы...

Сообщение devilr »

Ну, еще есть и микроконтроллеры. В которых функция main часто просто

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

int main(void)
{
   ...
   while(1)
  {
     ...
  }
}
Компилятор подставит, конечно, "return 0". Но, сам программист этого делать в явном случае не будет, скорее всего. Да и бессмысленно это - код из вечного цикла ведь не выйдет.
Мудрость приходит с возрастом.
Иногда возраст приходит один.
Спасибо сказали:

QWERTYASDF
Сообщения: 985
Статус: Чайник со свистком
ОС: GNU/Linux

Re: Начинаю осваивать C, появляются вопросы...

Сообщение QWERTYASDF »

А...так вот к чему мне gcc каждый раз говорил что-то насчет возвращаемого типа функции по умолчанию : ) Буду знать, спасибо.
Спасибо сказали:

Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8255
Статус: Маньяк
ОС: Arch, CentOS, Ubuntu

Re: Начинаю осваивать C, появляются вопросы...

Сообщение serzh-z »

devilr
Ппц, вы говорите про ненужность статусного кода завершения приложения или ненужность возвращаемого значения main?

Точек входа в exit или _exit тысячи и на коде завершения, так или иначе, завязана добрая половина POSIX API, связанная с управлением процессами. Странно обсуждать ненужность этого кода в контексте `exit(main())` - одного из многих способов завершения приложения.
Спасибо сказали:

Аватара пользователя
s.xbatob
Сообщения: 1137
ОС: Fedora

Re: Начинаю осваивать C, появляются вопросы...

Сообщение s.xbatob »

devilr писал(а):
04.09.2018 00:27
и вы там в явном виде не вернёте код ошибки. Хотя он будет, конечно.
как это не верну? Через QCoreApplication::exit(int)
devilr писал(а):
04.09.2018 10:39
Компилятор подставит, конечно, "return 0".
Это C++ вернёт 0. А C вернёт мусор!
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 18483
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: Начинаю осваивать C, появляются вопросы...

Сообщение Bizdelnick »

Hephaestus писал:
04.09.2018 10:27
И мне припоминается, даже был компилятор соответствующей версии, который нормально это переваривал. Без варнингов.
GCC и сейчас переваривает. Если с -ansi и без -Wreturn-type. Но по более новым стандартам такой синтаксис недопустим (лень искать, с какой точно версии).
devilr писал(а):
04.09.2018 10:39
Ну, еще есть и микроконтроллеры.
Там совсем другая история, возвращать-то значение фактически некуда. Да и функция может не main() называться, а как-то иначе.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
bormant
Сообщения: 1328

Re: Начинаю осваивать C, появляются вопросы...

Сообщение bormant »

Мимо, речь про Си, не про Си плюс плюс. Надо сюда:
https://en.cppreference.com/w/c/language/main_function
Спасибо сказали:

Аватара пользователя
bormant
Сообщения: 1328

Re: Начинаю осваивать C, появляются вопросы...

Сообщение bormant »

Hephaestus писал:
04.09.2018 10:27
Согласитесь, странно было бы использовать синтаксис без return и без указания типа возвращаемого значения, но при этом всё-таки рассчитывать на возврат какого-то значения.
В Си (да и в плюсах) не существует синтаксиса без указания типа возвращаемого значения функции. Если тип возвращаемого значения не указан явно, подразумевается int.
Спасибо сказали:

QWERTYASDF
Сообщения: 985
Статус: Чайник со свистком
ОС: GNU/Linux

Re: Начинаю осваивать C, появляются вопросы...

Сообщение QWERTYASDF »

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

Аватара пользователя
Hephaestus
Сообщения: 3729
Статус: Многоуважаемый джинн...
ОС: Slackware64-14.1/14.2

Re: Начинаю осваивать C, появляются вопросы...

Сообщение Hephaestus »

bormant писал(а):
04.09.2018 12:04
В Си (да и в плюсах) не существует синтаксиса без указания типа возвращаемого значения функции.
Почему?
Вот он

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

main()
{
.....
.....
}
это же допустимо с точки зрения синтаксиса, не так ли? Ну или, по крайней мере, было допустимо во времена K&R second edition.
bormant писал(а):
04.09.2018 12:04
Если тип возвращаемого значения не указан явно, подразумевается int.
"Не указан явно" - это значит, что тип не указали. Буквально. Так это и есть вариант синтаксиса без указания типа. Что там при этом подразумевается - вопрос отдельный.
Пускай скрипят мои конечности.
Я - повелитель бесконечности...
Мой блог
Спасибо сказали:

Аватара пользователя
Hephaestus
Сообщения: 3729
Статус: Многоуважаемый джинн...
ОС: Slackware64-14.1/14.2

Re: Начинаю осваивать C, появляются вопросы...

Сообщение Hephaestus »

QWERTYASDF писала:
04.09.2018 12:11
Данная сцена, как мне кажется, говорит о необходимости таки вникать порой в теоретические, и казалось бы, абстрактные вопросы...: )
Ну, куда ж от них деваться? Придется вникать. Особенно, когда оно сегодня - int, завтра - void, а послезавтра вполне может быть bool.
Пускай скрипят мои конечности.
Я - повелитель бесконечности...
Мой блог
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 18483
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: Начинаю осваивать C, появляются вопросы...

Сообщение Bizdelnick »

QWERTYASDF писала:
04.09.2018 12:11
Данная сцена, как мне кажется, говорит о необходимости таки вникать порой в теоретические, и казалось бы, абстрактные вопросы...: )
В C нет более практического и конкретного вопроса, чем сигнатура фунгкции. ☺
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8255
Статус: Маньяк
ОС: Arch, CentOS, Ubuntu

Re: Начинаю осваивать C, появляются вопросы...

Сообщение serzh-z »

Bizdelnick писал:
04.09.2018 12:45
В C нет более практического и конкретного вопроса, чем сигнатура фунгкции.
Ну что такое ты говоришь... Есть более важные вопросы - например, является ли конструкция вопросом или глаголом. =)
Спасибо сказали:

QWERTYASDF
Сообщения: 985
Статус: Чайник со свистком
ОС: GNU/Linux

Re: Начинаю осваивать C, появляются вопросы...

Сообщение QWERTYASDF »

Вы, господа, всегда такие умники по инсинуациям в сторону ТС, однако флудите касательно этих "важных" вопросов столько ,что они очевидно и впрямь важные : )
Спасибо сказали:

Аватара пользователя
Hephaestus
Сообщения: 3729
Статус: Многоуважаемый джинн...
ОС: Slackware64-14.1/14.2

Re: Начинаю осваивать C, появляются вопросы...

Сообщение Hephaestus »

QWERTYASDF
Разрешите поинтересоваться, где и у кого Вы обучаетесь языку Си? И по каким книгам, кстати?
Пускай скрипят мои конечности.
Я - повелитель бесконечности...
Мой блог
Спасибо сказали:

Аватара пользователя
s.xbatob
Сообщения: 1137
ОС: Fedora

Re: Начинаю осваивать C, появляются вопросы...

Сообщение s.xbatob »

Hephaestus писал:
04.09.2018 12:18
Ну, куда ж от них деваться? Придется вникать. Особенно, когда оно сегодня - int, завтра - void, а послезавтра вполне может быть bool.
Не будет такого! В C и вообще в *NIX к вопросам обратной совместимости подходят щепетильно.
Спасибо сказали:

QWERTYASDF
Сообщения: 985
Статус: Чайник со свистком
ОС: GNU/Linux

Re: Начинаю осваивать C, появляются вопросы...

Сообщение QWERTYASDF »

Добрый день. Задание из B&D - Написать программу, копирующую входной поток в выходной, и заменяющую табуляции на \t, возвраты на \b, а бэкслэши на \\. Мой вариант:

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

/* Упражнение 1.10 учебника B&D - копирование входного потока в выходной с заменой строк, содержащих табуляции, возвраты и бэкслыши - на /t /b и // */

#include <stdio.h>

main()
{

 int c;

 	while ( (c = getchar()) != EOF ) {

		if(c == '\t') printf("\\t");
		if(c == '\b') printf("\\b");
		if(c == '\\') 
		       	printf("\\\\");
        	else printf("%c", c);
		
	}

}
Но работает криво, не понимаю почему. При табуляции - подставляет \t, однако после этого еще один пробел. При возвратах - подставляет \b только, если после этого не идут никакие символы, если идут - то подставляет один бэкслэш (\). В случае бэкслэшэй в тексте - работает корректно. Можете объяснить, почему так происходит с табуляциями и возвратами? )
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 18483
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: Начинаю осваивать C, появляются вопросы...

Сообщение Bizdelnick »

QWERTYASDF, Вы некорректно используете if. Либо каждый последующий if должен быть в else, или используйте switch. С минимальными изменениями корректное решение будет таким:

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

/* Упражнение 1.10 учебника B&D - копирование входного потока в выходной с
 * заменой строк, содержащих табуляции, возвраты и бэкслыши - на /t /b и // */

#include <stdio.h>

int main() {
  int c;

  while ((c = getchar()) != EOF) {
    if (c == '\t')
      printf("\\t");
    else if (c == '\b')
      printf("\\b");
    else if (c == '\\')
      printf("\\\\");
    else
      printf("%c", c);
  }
  return 0;
}
Spoiler
P. S. И ещё позволю себе замечание по стилю, возможно спорное. Стоит содержимое любого if/else/while/for заключать в фигурные скобки, даже если там всего один, как это разъяснили выше, statement. Причина: если код не на выброс, то со временем может понадобится добавить какие-то дополнительные действия, и тогда очень легко забыть скобки, которые уже будут нужны обязательно. Кроме того, даже если скобки не забыть, история изменений выглядела бы более аккуратно, если бы они стояли сразу: тогда было бы видно добавление только одной строчки, без изменения соседних. Сравните:

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

--- test.c.old	2018-09-07 15:55:13.964446308 +0300
+++ test.c	2018-09-07 15:57:21.321806176 +0300
@@ -6,16 +6,19 @@
 
 int main() {
   int c;
+  int ntabs = 0;
 
   while ((c = getchar()) != EOF) {
-    if (c == '\t')
+    if (c == '\t') {
       printf("\\t");
-    else if (c == '\b')
+      ntabs ++;
+    } else if (c == '\b')
       printf("\\b");
     else if (c == '\\')
       printf("\\\\");
     else
       printf("%c", c);
   }
+  printf("Number of tabs: %d\n", ntabs);
   return 0;
 }
и

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

--- test.c.old	2018-09-07 15:58:58.119799541 +0300
+++ test.c	2018-09-07 15:59:16.759413141 +0300
@@ -6,10 +6,12 @@
 
 int main() {
   int c;
+  int ntabs = 0;
 
   while ((c = getchar()) != EOF) {
     if (c == '\t') {
       printf("\\t");
+      ntabs ++;
     } else if (c == '\b') {
       printf("\\b");
     } else if (c == '\\') {
@@ -18,5 +20,6 @@
       printf("%c", c);
     }
   }
+  printf("Number of tabs: %d\n", ntabs);
   return 0;
 }
Во втором случае намного проще понять, что изменилось.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
bormant
Сообщения: 1328

Re: Начинаю осваивать C, появляются вопросы...

Сообщение bormant »

QWERTYASDF писала:
07.09.2018 15:33
Задание из B&D
Эту книжицу традиционно называют K&R ;-)

Желательно комментарии писать так, чтобы они помогали, а не запутывали ;-) -- это про \b и /b, \t и /t, \\ и //
Ну и раз switch был упомянут:

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

#include <stdio.h>

int main(void) {
  int c;

  while ((c = getchar()) != EOF) {
    switch (c) {
      case '\b': printf("\\b");  break;
      case '\t': printf("\\t");  break;
      case '\\': printf("\\\\"); break;
      default:   printf("%c",c); break;
    }
  }
  return 0;
}
Спасибо сказали:

QWERTYASDF
Сообщения: 985
Статус: Чайник со свистком
ОС: GNU/Linux

Re: Начинаю осваивать C, появляются вопросы...

Сообщение QWERTYASDF »

Спасибо, глупая ошибка была.
Спасибо сказали:

QWERTYASDF
Сообщения: 985
Статус: Чайник со свистком
ОС: GNU/Linux

Re: Начинаю осваивать C, появляются вопросы...

Сообщение QWERTYASDF »

Доброе время суток. Такой вопрос... Когда моя консольная C-программа выполняет scanf() или getchar(), и читает stdin, то что именно (механизм/библиотека/подсистема...) обрабатывает мой ввод с клавиатуры, что его копит перед отдачей функции? Было замечено, что, например, редактирование (как это бывает при работе в bash) не работает, однако и набираемая строка отдается функции только после нажатия "Enter" на клавиатуре. Этим занимается эмулятор терминала? Правильно ли называть такой ввод "обработанным"?

Раньше я долго пыталась разобраться со всякими tty, pptx и прочим, но уже давно благополучно это забыто. Сейчас понимаю, что скорей всего мой вопрос связан как-раз с этими сущностями.

Извините, что опять столь туманно, но надеюсь, что все-таки суть вопроса возможно уловить : ) Можете в самых общих чертах рассказать, что и как происходит при вводе символов и строк?...
Спасибо сказали:

Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8255
Статус: Маньяк
ОС: Arch, CentOS, Ubuntu

Re: Начинаю осваивать C, появляются вопросы...

Сообщение serzh-z »

QWERTYASDF
Буферизацией занимается libc. См. setbuf/setvbuf для настройки. По-умолчанию, для потоков, связанных с TTY (кроме stderr), устанавливается режим _IOLBF.
Спасибо сказали:

Аватара пользователя
/dev/random
Администратор
Сообщения: 5102
ОС: Gentoo

Re: Начинаю осваивать C, появляются вопросы...

Сообщение /dev/random »

serzh-z писал:
13.09.2018 09:55
QWERTYASDF
Буферизацией занимается libc. См. setbuf/setvbuf для настройки. По-умолчанию, для потоков, связанных с TTY (кроме stderr), устанавливается режим _IOLBF.
setbuf/setvbuf работают с потоками вывода, а не ввода. Описанной QWERTYASDF буферизацией занимается сам терминал (и позволяет пользователю удалять последние введённые символы из буфера бэкспэйсом). Отправить буфер приложению без завершения строки можно нажатием Ctrl+D. Если нажать эту комбинацию, когда буфер пуст, это будет воспринято как конец файла. Приложение может отключить буферизацию через вызов cbreak() из состава ncurses.
Спасибо сказали: