LINUX.ORG.RU
ФорумTalks

Изучить С

 , ,


5

5

Всем привет! Надоели мне эти скриптовые аркадные языки, повесточка, докеро-голанги и тп, решил заняться изучением С. Тем более что вспомнил о том, что по факту это единственный язык который доставлял удовольствие.

Посоветуйте пожалуйста книгу, которую можно почитать и порешать оттуда заодно задачи если есть.

Ответ на: комментарий от LightDiver

ЛОР, наконец, дорос до лора про «настоящих программистов»? Может, кто и «Историю Мэла» запилит, но на отечественном бэкграунде?

alegz ★★★★★
()
Ответ на: комментарий от Xintrea

потрать лет 10 чтобы английский как родной выучить

До понимания технической литературы можно добраться намного быстрее, даже если нет особых способностей к языкам. Придётся много зубрить, но программы для зубрёжки очень помогают.

Для изучения как родного десяти лет может и не хватить.

i-rinat ★★★★★
()

нужна реальная задача, ну и пиши код под задачу, возми stm32 какой и делай.

s-warus ★★★★
()
Ответ на: комментарий от windows10

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

как бы да, но эта дельта сохраняется будет 1000 и 1100, а может и сократится

s-warus ★★★★
()
Ответ на: комментарий от i-rinat

До понимания технической литературы можно добраться намного быстрее

Нет. Максимум до чего доберетесь - это читать инструкцию по эксплуатации на микроволновку.

Как только речь пойдет о принципах и парадигмах программирования, о тонкостях владения, отличиях объявления от инициализации, разницы в указателях и адресной адресации в массивах и прочих тонких моментах, на которых неясно кто на ком стоял, так сразу появится понимание что знаний языка не хватает, чтобы догнать что конкретно имел в виду автор.

Xintrea ★★★★★
()
Ответ на: комментарий от Xintrea

Максимум до чего доберетесь - это читать инструкцию по эксплуатации на микроволновку.

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

Легче всего читаются средние варианты, где знакомый большой контекст и тебе на пальцах объясняют без историй из жизни, анекдотов, аллюзий, метафор и прочей литературщины.

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

Как только речь пойдет о принципах и парадигмах программирования, о тонкостях владения, отличиях объявления от инициализации, разницы в указателях и адресной адресации в массивах и прочих тонких моментах, на которых неясно кто на ком стоял, так сразу появится понимание что знаний языка не хватает, чтобы догнать что конкретно имел в виду автор.

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

papin-aziat ★★★★★
()
Ответ на: комментарий от papin-aziat

Вот здесь и нужна грамматика научно-технического текста

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

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

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

Я могу посоветовать одно - искать нормальную русскоязычную литературу, либо адекватно переведенную, либо написанную вменяемым русскоязычным автором. Кроме того, надо научиться разбираться в издательствах. Например, издательству «Питер» можно доверять, а издательства «O'Relly» и «Williams» - лютое овнищще, поставившие переводы на бесконтрольный поток и плюющие на качество.

Xintrea ★★★★★
()
Последнее исправление: Xintrea (всего исправлений: 2)
Ответ на: комментарий от Xintrea

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

Могу. Грамматика науч-теха богаче литературной, там экономия (грандиозная экономия!) времени для изучающего идёт за счёт игнорирования несвойственного вокабуляра и идиоматики, а характерный *ляр и *матика конечно заучивается, так как имеет хоть и широкий, но ограниченный диапазон.

В реальных технических текстах намешано все: и литературщина, и аллюзии, и метафоры, и историй из жизни насыплют пачку.

К сожалению, да. Что делать? В первую очередь осознать, что любую вещь можно объяснить используя логику, то есть без метафор, аллюзий и историй из жизни. Значит первое: постараться выбирать авторов, которые не растекаются по древу. Второе: если другого, хорошего, варианта нет, то научиться вычленять эти самые растекания и сосредотачиваться на логике вопроса (автор всегда закончит этим тему, если не совсем дурак). Ну и сегодня благодаря ИИ можно разобраться в тёмных местах идиоматики почти без проблем.

Хорошие авторы есть и вот реальный пример. Я сам старался добывать книги переводные, но с некоторого времени стал чуять, что часто идёт какая-то путаница понятий и, скачивая и заглядывая в оригиналы, я обнаружил, что в них всё то же самое звучит более гладко и понятно. Так что технические переводы то ещё говнище местами… Тут решил наконец разобраться с sed & awk и купил репринт с оригинала одноименной книги от Dougherty & Robbins, — и это совсем другое дело! Вот люди умеют писать хорошо, читаю как роман — легко и свободно, а словарь и ИИ использую только чтобы устаканить терминологию на русский лад для себя.

Так что, с тезисом, что «надо знать как родной» категорически не согласен, но и переводить конечно надо, но хорошо, а с этим проблемы и далеко не только в науч-техе, что совсем угнетает веру в чтение переводов. А русские авторы… ну, это большая редкость чтобы хорошие, всё-таки мы как нация здесь на подсосе, увы, и не только в плане науки и техники. Что говорить… есть целый ряд книг из других областей, переводы которых читать просто невозможно для меня (дрянь!), либо они вообще никогда не будут переведены.

papin-aziat ★★★★★
()
Ответ на: комментарий от papin-aziat

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

Могу.

В реальных технических текстах намешано все: и литературщина, и аллюзии, и метафоры, и историй из жизни насыплют пачку.

К сожалению, да.

Взаимоисключающие параграфы. Хотя, возможно мы имеем дело с трансерфингом реальности.

Xintrea ★★★★★
()
Ответ на: комментарий от Xintrea

Взаимоисключающие параграфы.

Не, грамматика фикшна проще и целиком в пределах, подмножество получается. Проблема, на которую ты указываешь, лежит не в грамматике, а в вокабуляре и идиоматике, отсюда моё «могу», по сути шутка.

papin-aziat ★★★★★
()
Ответ на: комментарий от mittorn

видимо, в pdp-11

Так там такой MASM, что C даже и не нужен...

Shadow ★★★★★
()
Ответ на: комментарий от Xintrea

Техническая литература как раз на уровне инструкции для микроволновки, так что всё нормально.

Хотя если год потратить не на изучение языка, а на убеждение себя, что не справишься, то скорее всего действительно не справишься.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Техническая литература как раз на уровне инструкции для микроволновки

Только в твоих мечтах.

Xintrea ★★★★★
()
Ответ на: комментарий от Xintrea

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

Именно так. Поэтому, как я всегда пишу - сначала надо бросить все, и выучить английский. Как родной это некоторое преувеличение, но в целом да. Школы тут не хватит.

James_Holden ★★★★★
()
Ответ на: комментарий от James_Holden

Самая большая глупость в жизни - пытаться что-то изучать, не зная языка, на котором 90% информации для изучения. Это же просто смешно.

James_Holden ★★★★★
()
Ответ на: комментарий от James_Holden

Самая большая глупость в жизни - пытаться читать американскую фантастику, не зная языка, на котором 90% информации для изучения. Не так ли?

Люди, которые изучили американскую фантастику по книгам в переводе, смотрят на тебя с недоумением.

Xintrea ★★★★★
()
Последнее исправление: Xintrea (всего исправлений: 1)
Ответ на: комментарий от James_Holden

Следующим твоим действием ты будешь уберегать детей от народных сказок. Ведь так гораздо лучше!

Xintrea ★★★★★
()
Ответ на: комментарий от firkax

Можно разными способами эту задачку решить, у меня после некоторых раздумий получилось это:

#include <stdio.h>

/* Lesson 1.23. Write a program that removes all the comments from a C program. Don't forget */
/* to handle quoted strings and character constants properly. C comments don't nest. */

#define BUFSIZE  1024

int decomment(char buf[]);
int get_line(char line[], int lim);
void push(char chr);
char pop(void);

/* Characters */
#define NULLBYTE        '\0'
#define NEWLINE         '\n'
#define SLASH            '/'
#define ASTERISK         '*'
#define QUOTE_CHAR      '\''
#define QUOTE_STRING    '\"'

int main() {
  char buf[BUFSIZE];
  int len = 1; /* assume there is a new data, to enter a loop */

  while ((len = get_line(buf, BUFSIZE)) > 0) {
    if (decomment(buf) != NULLBYTE)
      printf("%s", buf);
  }

  return 0;
}

/* decomment: removes all the comments from a C program, returns new length of its text */
int decomment(char buf[]) {
  char tmp[BUFSIZE];
  char test1[] = "/* string may contain a C style comment */\n";
  char test2[] = "// string also may contain a C++ style comment\n";
  char chr = NULLBYTE;
  int i;     /* iterators */
  int bi;

  /* prepare temporary buffer to work */
  for (i = 0; i <= BUFSIZE; ++i) tmp[i] = NULLBYTE;

  /* move contents of main buffer to temporary buffer and prepare the main buffer for new data */
  for (i = 0; buf[i] != NULLBYTE; ++i) {
    tmp[i] = buf[i];
    buf[i] = NULLBYTE;
  }

  /* then, work on contents of temporary buffer, decomment it, placing the result in the main buffer */
  bi = 0;
  i = 0;
  while (tmp[i] != NULLBYTE) {
    if (tmp[i] == SLASH) {
      push(tmp[i]);
      ++i;
    }
    else if (tmp[i] == QUOTE_CHAR || tmp[i] == QUOTE_STRING) {
      buf[bi] = tmp[i];
      push(tmp[i]);
      ++bi;
      ++i;
    }

    while ((chr = pop()) != NULLBYTE) {
      /* qouted text should be stored to main buffer */
      if (chr == QUOTE_CHAR || chr == QUOTE_STRING) {
        while ((tmp[i] != chr || tmp[i] == chr) && tmp[i] != NULLBYTE) {
          buf[bi] = tmp[i];
          ++bi;
          ++i;
        }
      }

      else if (chr == SLASH && tmp[i] == SLASH) { // this serves a CPP style comments
        buf[bi] = NEWLINE;
        ++bi;
        return bi;
      }
      else if (chr == SLASH && tmp[i] == ASTERISK) { /* this is for C ctyle comments */
        while (tmp[i] != chr && tmp[i] != NULLBYTE) {
          ++i;
        }
        if (tmp[i] == chr) ++i;
      }
    }

    buf[bi] = tmp[i];
    ++bi;
    ++i; // next character
  }

  return bi;
}

/* get_line: read the line into input buffer, return its length */
int get_line(char line[], int  lim) {
  int c, i;

  for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
    line[i] = c;

  if (c == '\n') {
    line[i] = c;
    ++i;
  }

  line[i] = '\0';
  return i;
}

/* stack of characters */
char stack[BUFSIZE] = { 0 };
int sp = 0; /* stack pointer */

/* push: place the character to the stack */
void push(char chr) {
  if (sp < (BUFSIZE)) {
    ++sp;
    stack[sp] = chr;
  }
}

/* pop: extract the character from stack */
char pop(void) {
  char chr = NULLBYTE;

  if (sp > 0) {
    chr = stack[sp];
    --sp;
  }
  return chr;
}


:-D

yars068 ★★★★★
()
Ответ на: комментарий от alegz

Может, кто и «Историю Мэла» запилит, но на отечественном бэкграунде?

меллстроя?

NorthernBlow
() автор топика

я программировал на с++. делал игру ГО. сделал доску, меню и автоудаление фишек по алогоритму окружения.

Основные версии стандарта:

ANSI C (C89) - первая официальная спецификация, выпущенная в 1989 году
C90 - версия стандарта ISO, выпущенная в 1990 году
C99 - обновленный стандарт, вышедший в 1999 году
C11 - версия 2011 года
C17 - актуальная версия стандарта на 2025 год
C23 - планируемая версия стандарта

в интернете мало документации по си. ИИ подсказывает: Книги - классические издания: “Язык программирования C” Брайана Кернигана и Денниса Ритчи “C Programming: A Modern Approach” К. Н. Кинга

вроде накопал оригинал стандарта https://open-std.org/JTC1/SC22/WG14/www/docs/n3220.pdf

jura12 ★★
()
Последнее исправление: jura12 (всего исправлений: 1)
Ответ на: комментарий от jura12

ИИ

Если ты склонен читать вывод бредогенераторов, но от Си тебе лучше держаться подальше. А то hateyoufeel получит ещё один наглядный пример для своих утверждений что все сишники устраивают битьё памяти и прочие проблемы.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от firkax

ИИ

Если ты склонен читать вывод бредогенераторов

я читаю и то и другое. оригинал стандарта предложил я в конце. сейчас на с не программирую. иногда генерю скрипты.

jura12 ★★
()
Ответ на: комментарий от yars068

Ладно, выдам свою версию. Кстати да, выяснилась ужасная вещь - если вход читаем не из файла (либо нельзя seek ещё почему-то), и если мы хотим поддерживать и \n и \r\n в качестве концов строк и не хотим чтобы при некоторых обстоятельствах эти \r\n превращались в \n (ведь нам сказали только убрать комментарии, а конвертировать концы строк задачи не стояло), то без стека и правда не обойтись. Но вообще - второй вариант в родной ОС языка Си не принят, в задаче уточнений на этот счёт нет - так что его можно с чистой совестью выкинуть. Так же там, кажется, нет запрета на seek, так что тоже можно без стека. Ниже вариант, который хоть и поддерживает \r\n, но при редких обстоятельствах (никогда не встречающихся к нормальных исходниках) может изменить тип конца строки.

#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>

static void handle_char(char c);
int main() {
  char buf[1024];
  ssize_t r;
  size_t j;
  while(r = read(0, buf, sizeof(buf))) {
    if(r<0) {
      if(errno==EINTR || errno==EAGAIN || errno==EWOULDBLOCK) continue;
      fprintf(stderr, "read error %d\n", errno); return -1;
    }
    for(j=0; j<(size_t)r; j++) handle_char(buf[j]);
  }
  return 0;
}

#define STATE_SLASH     1
#define STATE_SLASH_BS  2
#define STATE_SLASH_BS1 3
#define STATE_COMMENT   4
#define STATE_COMM1     5
#define STATE_COMM1_BS  6
#define STATE_COMM1_BS1 7
#define STATE_COMM1_CR  8
#define STATE_CHAR      9
#define STATE_CHAR_BS   10
#define STATE_CHAR_BS1  11
#define STATE_STR       12
#define STATE_STR_BS    13
#define STATE_STR_BS1   14
#define STATE_COMM2     15
#define STATE_COMM2_BS  16
#define STATE_COMM2_BS1 17

static int state, bst;
static size_t bs;

static void handle_char(char c) {
  switch(state) {
  case 0: case0:
    if(c=='/') { state=STATE_SLASH; bs=0; bst=0; return; }
    if(c=='\'') state=STATE_CHAR;
    else if(c=='"') state=STATE_STR;
    break;
  case STATE_CHAR: if(c=='\'') state=0; else if(c=='\\') state++; break;
  case STATE_STR: if(c=='\"') state=0; else if(c=='\\') state++; break;
  case STATE_CHAR_BS: case STATE_STR_BS: state--; break;
  case STATE_SLASH:
    if(c=='*') { state=STATE_COMMENT; return; }
#ifndef NO_CPP
    if(c=='/') { state=STATE_COMM1; return; }
#endif
    if(c=='\\') { state++; return; }
    putchar('/');
    while(bs) { bs--; putchar('\\'); if(bst) putchar('\r'); putchar('\n'); }
    state=0; goto case0;
  case STATE_SLASH_BS:
    if(c=='\r') { state++; return; }
    if(c=='\n') { state--; bs++; return; }
    putchar('/');
    while(bs) { bs--; putchar('\\'); if(bst) putchar('\r'); putchar('\n'); }
    putchar('\\');
    state=0; goto case0;
  case STATE_SLASH_BS1:
    if(c=='\n') { state-=2; if(!(bs++)) bst=1; return; }
    putchar('/');
    while(bs) { bs--; putchar('\\'); if(bst) putchar('\r'); putchar('\n'); }
    putchar('\\');
    putchar('\r');
    state=0; goto case0;
  case STATE_COMMENT:  if(c=='*') state=STATE_COMM2; return;
  case STATE_COMM2:    if(c=='/') state=0; else if(c=='\\') state++; else state=STATE_COMMENT; return;
  case STATE_COMM2_BS: if(c=='\r') state++; else if(c=='\n') state--; else state=STATE_COMMENT; return;
  case STATE_COMM2_BS1:if(c=='\\') state--; else if(c=='\n') state-=2; else state=STATE_COMMENT; return;
  case STATE_COMM1:    if(c=='\n') { state=0; break; } if(c=='\r') state+=3; else if(c=='\\') state++; return;
  case STATE_COMM1_CR: if(c=='\n') { state=0; putchar('\r'); break; } if(c=='\\') state-=2; else if(c!='\r') state-=3; return;
  case STATE_COMM1_BS: if(c=='\r') state++; else if(c!='\\') state--; return;
  case STATE_COMM1_BS1:if(c=='\\') state--; else state-=2; return;
  }
  putchar(c);
}
firkax ★★★★★
()
Ответ на: комментарий от firkax

Ну, я свой вариант писал, исходя из того, что рассматривалось в первой главе подробно, например, про switch в первой главе лишь упомянули, что да, есть такой, и что он подходит, если условием выбора одного из альтернативных вариантов является число, а подробно его рассмотрели в главе 3. Также в первой главе читатель еще даже с stdio.h толком не знаком, не говоря уже о всей стандартной библиотеке. Именно поэтому у меня, например, getline() самописная, а не библиотечная. Хотя, конечно, книга писалась для тех, кто с программированием уже знаком, и об этом в ней сказано. Я изучаю Си по второму изданию K&R (англоязычному), там упор делается на ANSI C.

Исходник программы довольно тяжело читается, и есть, на мой взгляд, спорные моменты, например, инкремент-декремент state. И да, про поддержку \r\n в задании ничего не говорилось, а я и не задумывался над тем, что кто-то захочет собрать мой кусок учебного кода в системе, отличной от одного из современных линуксов :)

yars068 ★★★★★
()
Последнее исправление: yars068 (всего исправлений: 2)

Исходный код openBSD, или хотя бы Фряхи.

Hertz ★★★★★
()
Ответ на: комментарий от yars068

Инкремент-декремент, согласен, спорные, но тут они для двух целей:

1) избавиться от тавтологического повторения одних и тех же констант по несколько раз подряд

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

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

На самом деле я забыл ещё одну штуку - вот этот пережиток древности, который до сих пор поддерживается компиляторами. А конкретно - последовательность из трёх символов ??/, которая в любом месте исходника парсится как обратный слэш. То есть '??/'' это легальный способ записать символ одинарной кавычки. А вот это

/??/
\
??/
* qwe *??/
/
то же самое что /* qwe */. Чтобы парсить ещё и это, пришлось бы ввести ещё 2 то ли 3 вспомогательных статуса везде где статусы _BS есть, и тогда уж точно либо seek по файлу исходника либо временный буфер неограниченного размера придётся использовать т.к. надо где-то запоминать вот это
/??/
\
??/
на случай если дальше окажется не звёздочка и надо всё вывести на экран.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 2)
Ответ на: комментарий от yars068

А это мой первый вариант, на гит{хаб,флик}е у меня он лежит:

#include <stdio.h>

/* Write a program that removes the comments from the C program */

#define BUFSIZE 1000
#define FALSE -1

/* Map assignments: */
#define OTHER 0
#define SINGLE_QUOTE 1
#define DOUBLE_QUOTE 2
#define SLASH 3
#define ASTERISK 4
#define SINGLE_STRING_COMMENT 5
#define MULTI_STRING_COMMENT_BEGIN 6
#define MULTI_STRING_COMMENT_END 7

int get_line(char buf[], int lim) {
  int c, len;
  c = len = 0;

  while ((len < (lim - 1)) && (c = getchar()) != EOF && c != '\n')
    buf[len++] = c;

  if (c == '\n') buf[len++] = c;
  
  buf[len] = '\0';
  return len;
}

int main(void) {
  char buf[BUFSIZE] = {'\0'};
  char res[BUFSIZE] = {'\0'};
  int map[BUFSIZE] = {FALSE};
  int i, j, len, state;

  while ((len = get_line(buf, BUFSIZE)) > 0) {
    for (i = 0; i < BUFSIZE; ++i) res[i] = 0;
    
    state = FALSE;
    
    for (i = 0; (i < len && buf[i] != '\0'); ++i) {
      if (state == SLASH && buf[i] == '*')
         map[i] = MULTI_STRING_COMMENT_BEGIN;

      else if (state == ASTERISK && buf[i] == '/')
        map[i] = MULTI_STRING_COMMENT_END;

      else if (state == SLASH && buf[i] == '/')
        map[i] = SINGLE_STRING_COMMENT;

      else if (buf[i] == '\'')
        map[i] = SINGLE_QUOTE;

      else if (buf[i] == '\"')
        map[i] = DOUBLE_QUOTE;

      else if (buf[i] == '*')
        map[i] = ASTERISK;

      else if (buf[i] == '/')
        map[i] = SLASH;

      else map[i] = OTHER;
      state = map[i];
    }

    i = j = 0;
    state = FALSE;
    while (i < len) {
      if (state != MULTI_STRING_COMMENT_BEGIN && state != SINGLE_STRING_COMMENT && map[i] == SINGLE_QUOTE) {
        res[j++] = buf[i];
        state = SINGLE_QUOTE;
      }
      else if (state != MULTI_STRING_COMMENT_BEGIN && state != SINGLE_STRING_COMMENT && map[i] == DOUBLE_QUOTE) {
        state = DOUBLE_QUOTE;
        res[j++] = buf[i];
      }
      else if (state != SINGLE_QUOTE && state != DOUBLE_QUOTE && map[i] == SLASH && map[i + 1] == MULTI_STRING_COMMENT_BEGIN) {
        state = MULTI_STRING_COMMENT_BEGIN;
        i+=2;
      }
      else if (state == MULTI_STRING_COMMENT_BEGIN && map[i] == ASTERISK && map[i + 1] == MULTI_STRING_COMMENT_END) {
        state = MULTI_STRING_COMMENT_END;
        i+=2;
        res[j++] = buf[i];
      }
      else if (map[i] == SLASH && map[i + 1] == SINGLE_STRING_COMMENT) {
        state == SINGLE_STRING_COMMENT;
        break; //drop the rest of line
      }
      else if (map[i] == SLASH && map[i + 1] != MULTI_STRING_COMMENT_BEGIN && map[i + 1] != SINGLE_STRING_COMMENT) {
        state = SLASH;
        res[j++] = buf[i];
      }
      else if (map[i] == ASTERISK && map[i + 1] != MULTI_STRING_COMMENT_END) {
        state = ASTERISK;
        //++i;
        res[j++] = buf[i];
      }
      else if (state != MULTI_STRING_COMMENT_BEGIN && state != SINGLE_STRING_COMMENT && (map[i] == OTHER || map[i] == ASTERISK)) {
        state = OTHER;
        res[j++] = buf[i];
      }

      ++i;
    }
    /* Print the result: */
    if (j > 1) printf("%s", res);
  }
  
  return 0;
}

Как говорится, сравните :)

yars068 ★★★★★
()
Ответ на: комментарий от firkax

Да, про триграфы я тоже в курсе, но опять же, в задании и вообще в первой главе про них нет ни слова, поэтому не стал заморачиваться. Если же писать программу для общего случая, то она, конечно, посложнее станет. Кстати, в вики пишут, что начиная с С++17 триграфы более не поддерживаются, а в чистом С перестанут поддерживаться начиная с C23.

yars068 ★★★★★
()
Последнее исправление: yars068 (всего исправлений: 1)
Ответ на: комментарий от jura12

C23 - планируемая версия стандарта

Это официальный стандарт, опубликованный международными организациями

ISO/IEC 9899:2024 https://www.iso.org/standard/82075.html

Черновики текущих, будущих и устаревших стандартов https://open-std.org/JTC1/SC22/WG14/www/projects

вроде накопал оригинал стандарта https://open-std.org/JTC1/SC22/WG14/www/docs/n3220.pdf

Это С23 (ISO/IEC 9899:2024) с небольшими изменениями. Оригинальный PDF можно купить онлайн за CHF 221 или приобрести официальное издание в национальном органе стандартизации.

vM ★★★
()
Ответ на: комментарий от lenin386

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

yars068 ★★★★★
()
Ответ на: комментарий от alegz

в интернете мало документации по си

cppreference.com это просто шутка, понимаю.

Речь по C а не про плюсы.

anc ★★★★★
()
Ответ на: комментарий от alegz

ъ по ссылкам не ходят, да.

Ъ по ссылкам даже ходят, но не нажимают кнопочку PgDown :)

anc ★★★★★
()
Ответ на: комментарий от hateyoufeel

если ты английский не можешь?

Существую переводчики - «Crow Translate», QTranslate, но кроме браузерных конечно же. Я до сих пор их использую общаясь на англоязычных форумах с 1500+2200 сообщений (только моих). А читаю хоткеем жму Alt+V и плаг s3 переводит мне всю страницу форума (мог бы сразу юзать весь форум переведенный, дочерние ссылки автоматом переводятся, но там код будет поломан). Справку на 2000 страниц переводил гуглом, скрипт скармливал ему страницы, после 500 страниц гугл блокирует, через 4 часа разблокировал, отправлял следующую партию и в течении дня любая справка переведена, а читать можно сразу не ждя перевода всей книги.

AZJIO
()
Ответ на: комментарий от LightDiver

Так напиши статью об этом. Все кто пишет на таких языках, где одна функция в 100 строк укладывается злые, потому что они столько страдали пока до этого дошли, то всех нубов они просто отшивают или вместо помощи говорят что дурак и т.д. Совета от таких не дождёшься. А если чел ещё и зарабатывает, то нафиг ему плодить конкурента и раскрывать все нюансы, или работы у него настолько полно, что тянуть за собой неудачников он не готов.
Вот я пытался для себя делал справки, чтобы поучить и так и не проникся.

AZJIO
()
Последнее исправление: AZJIO (всего исправлений: 2)
Ответ на: комментарий от papin-aziat

Чтобы переводить надо в совершенстве знать тему, а переводить слова без контекста, конечно же получиться гугл-перевод, учитывая, что сами авторы в своём описании могут так написать, что те, для которых англ.яз. родной сами не поймут. Я сколько не пробовал читать книги не могу и 5-ти минут усидеть. Во первых либо ты читаешь то что и без автора знаешь, а он воды льёт на целую статью, перейдёшь к примеру, видишь что он прост до нельзя, пропускаешь. Ну не видел я ещё ни одной книги которую можно читать, я думаю они для нубов, которые не собираются программировать, а только книжку читать. Самый идеальный способ раскрыть знания - справочник структурно/иерархически разделённый на главы/дерево/приоритеты, с качественными работающими примерами раскрывающими суть, с поисково системой (теги/указатели/сырой режим). Такой справочник будет использоваться на всём протяжении работы, он является дополнением мозговой памяти и перетекании справочной инфы в мозговую память или как инструмент для «освежить память». Так же думаю видео будет в тему, они показывают как работает автор, какие инструменты, как выполняет набор кода и т.д. и т.п.

AZJIO
()
Ответ на: комментарий от AZJIO

Самый идеальный способ раскрыть знания - справочник <…>

Дык не секрет, что хороших учебников днём с огнём… Поэтому постоянно приходится как-то выкручиваться с теми материалами, которые есть.

papin-aziat ★★★★★
()
Ответ на: комментарий от James_Holden

Самая большая глупость в жизни - пытаться что-то изучать, не зная языка, на котором 90% информации для изучения. Это же просто смешно.

Я не знаю и пишу. И даже помогаю англоязычным, видимо аура их языка не добавляет им ума. Логика это же математика, а она преподавалась в СССР на уровне, даже отличником взвоешь. А синтаксические лексемы это всего лишь конструкция и к логической математике не имеет никакого отношения. У нас также используются «если», просто подмени их лексемы на свои, какая в этом сложность. Если уж таблицу умножения выучили во 2-м классе, то уж таблицу лексем If-если, For-для выучить то думаю одного часа хватит.

AZJIO
()
Ответ на: комментарий от yars068

пока не наткнëмся на'/', если встретилась косая черта, запоминаем еë

А если символ встретился внутри кавычек или апострофов? А что если встретится экранированная кавычка \" или так \\\\\\\\" и нужно проверить количество, чтобы признать кавычку экранированной или нет. Так что посимвольный анализатор придётся усложнить. Просто я уже писал такой. Пришлось изучать как выглядят ассемблерные вставки, не является ли / каким нибудь вспомогательным символом в них.

Ой, в Си то немного другие заморочки.

AZJIO
()
Последнее исправление: AZJIO (всего исправлений: 1)
Ответ на: комментарий от AZJIO

Программа выше, сначала вариант со стеком, потом вариант с двумя проходами по строке. Экранированная кавычка может встретиться (ИЧСХ, таки встретилась в тексте программы), и ничего не сломалось.

так \\\\\\\\"

Да, на такие входные данные я новый вариант программы не рассчитывал, равно как и не проверял, но когда в проверяемом программой исходнике встречается кавычка, она копируется как есть, так что вся эта часть строки будет скопирована как есть, то есть, программа отработает ровно как задумано.

ассемблерные вставки

В данном случае это сбоку припёка, то есть, обращаться к их возможностям нет необходимости.

yars068 ★★★★★
()
Ответ на: комментарий от yars068

так что вся эта часть строки будет скопирована как есть

если мы встречаем кавычку, то мы перестаём искать «//» и ищем закрывающую кавычку, чтобы после этого снова искать «//». Поэтому не важно как эта часть копируется, важно найти конец строки. А \\\\\\\\\" (нечётное число наклонных черт) ложная кавычка и её надо пропустить, то есть при встрече \ мы начинаем переключать триггер чётный/нечётный и если чётный, то конец строки, если нечётный то ищем дальше кавычку. Как только нашли конечную кавычку, снова начинаем искать символ комментария. Сначала я дела общий посимвольный цикл с кучей флагов, в которых можно запутаться, но потом для строк я сделал отдельный цикл в цикле, нашли кавычку открывает цикл поиска заканчивающей кавычки со всеми правилам исключения экранированных, нашли закрывающуюся, выпрыгиваем из внутреннего цикла и продолжаем внешний цикл. А ещё бывает ошибка в коде, нет закрывающейся кавычки/апострофа, то есть апостроф теоретически должен быть через один символ, например ‘a’ и кажется просто пропусти 3 символа и ищи дальше, но не тут-то было, если ошибка в коде 'ab// открывающий есть, закрывающего нет, то мы можем убить строку отрезав не комментарий, а код.

AZJIO
()
Последнее исправление: AZJIO (всего исправлений: 1)
Ответ на: комментарий от AZJIO

Зачем такие сложности, ведь '\\' может встретиться только внутри строковой или символьной константы, к моменту появления в потоке данных бэкслеша кавычка уже в стеке и в выходном буфере. Копирование символов происходит до тех пор, пока не будет встречена такая же кавычка и, соответственно, стек не будет опустошён, или пока не будет достигнут конец строки.

мы можем убить строку отрезав не комментарий, а код.

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

yars068 ★★★★★
()
Последнее исправление: yars068 (всего исправлений: 2)
Ответ на: комментарий от yars068

Копирование символов происходит до тех пор, пока не будет встречена такая же кавычка и, соответственно, стек не будет опустошён, или пока не будет достигнут конец строки.

Не совсем понял, если только у вас определятор типа переменной, на первой странице я увидел код, где есть константа «IN_POSSIBLE_COMMENT», может в таком парсинге чтение лексемами легче определить, но я про чистый посимвольный анализ строк. В PureBasic тоже есть авторский анализатор для подсветки и там Callback-функция возвращает тип лексемы и эту либу можно настроить для всего-что угодно, но у неё был недостаток - она не была кроссплатформенной, а вырезать её функционал из IDE не представлялось возможности - ума не хватало, поэтому я попробовал сам написать. В этом плане код это текст и анализируется всё самостоятельно, без автоматического помещения чего-то в стек.

AZJIO
()
Ответ на: комментарий от yars068

Анализ текста посимвольно это вообще чит какой то. Есл бы все было везде так просто… А ты поанализируй побайтово с учетом кодировок.

LightDiver ★★★★★
()
Ответ на: комментарий от NorthernBlow

Иногда нет другого выхода, увы.. Зато после такого манипулирование чистым текстом - такой кайф.

LightDiver ★★★★★
()
Последнее исправление: LightDiver (всего исправлений: 1)

Изучить С

Тут любят рекомендовать изучить книгу про столяров. Но ты свою напиши. Так, про плотников и рыбаков уже есть. Тогда про злых жестянщиков.

slackwarrior ★★★★★
()
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)