LINUX.ORG.RU
ФорумTalks

Изучить С

 , ,


1

5

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

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

читай про Гарри Поттера

а для языков нужны задачи из повседневного личного окружения (чужие рекомендации не помогут). И на первых порах справочник

MKuznetsov ★★★★★
()

K&R The C Programming Language (1977) с соответствующей тулзой: https://paulnank.github.io/pdp11-js/pdp11.html

Boot> boot rp1

70Boot from xp(0,1,0) at 0176700
Press <CR> to boot, or any other key to abort: 0
: xp(0,1,0)unix
Boot: bootdev=05010 bootcsr=0176700

2.11 BSD UNIX #1: Oct 31 09:13:53 CST 1981  
    root@Sat:/usr/src/sys/VIXEN

attaching sl
attaching lo0

phys mem  = 3915776
avail mem = 3489088
user mem  = 307200

October 31 09:26:16 init: configure system

lp 0 csr 177514 vector 200 attached
rk 0 csr 177400 vector 220 attached
rl 0 csr 174400 vector 160 attached
tm 0 csr 172520 vector 224 attached
xp 0 csr 176700 vector 254 attached
cn 1 csr 176500 vector 310 attached
cn 2 csr 176510 vector 320 attached
Automatic reboot in progress...
Sat Oct 31 09:26:21 CST 1981
Sat Oct 31 09:26:21 CST 1981
checking quotas: done.
Assuming NETWORKING system ...
ifconfig: ioctl (SIOCGIFFLAGS): no such interface
vixen.skn.noip.me: bad value
add net default: gateway 127.0.0.1
starting system logger
checking for core dump... 
preserving editor files
clearing /tmp
standard daemons: update cron accounting.
starting network daemons: inetd rwhod printer.
Sat Oct 31 09:26:22 CST 1981
Oct 31 09:26:22 vixen October 31 09:26:22 init: kernel security level changed from 0 to 1


2.11 BSD UNIX (vixen.skn.noip.me) (console)

login: root
erase, kill ^U, intr ^C
# pwd
/
# ls
.cshrc      .tiprc      disklabel   lost+found  size.c      var
.hushlogin  README      etc         mdec        sys         vmunix
.kermrc     VERSION     generic     mnt         tmp
.login      bin         hanoi.c     netnix      toyset
.mailrc     boot        hello.c     pi.c        unix
.profile    dev         lib         sbin        usr
# more size.c
#include <stdio.h>

main(argc, argv)
    int argc;
    char * argv[];
{
    printf("Size of char: %d byte\n",sizeof(char));
    printf("Size of int: %d bytes\n",sizeof(int));
    printf("Size of long: %d bytes\n",sizeof(long));
    printf("Size of float: %d bytes\n",sizeof(float));
    printf("Size of double: %d bytes\n",sizeof(double));
}
# cc size.c
# ./a.out
Size of char: 1 byte
Size of int: 2 bytes
Size of long: 4 bytes
Size of float: 4 bytes
Size of double: 8 bytes
# 
luke ★★★★★
()

заняться изучением С

единственный язык который доставлял удовольствие

доставлял

То есть ты его знал?

Zhbert ★★★★★
()

Классику читай. Прям от авторов языка. «Язык Си» называется.

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

То есть ты его знал?

По-хорошему язык Си даже Кен Томпсон не знал.

А так, те кто утверждают что знают сишечку, пусть сначала покажут своё решение для дополнительной задачки под номером 1.23 из K&R 1977 (1.24 из второго издания). По словам авторов книжки, первой главы должно быть достаточно, чтобы решить эту задачу (и конечно же они вводят читателя в заблуждение, если предполагается полное решение задачи).

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

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

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

Я 1.23 решал, но мой способ неэффективный, там я разделил задачу на 2 подзадачи – сначала ищем, что где находится, потом стираем комментарии. И всë равно, если в каком-нибудь комментарии встретится что-то типа can't do this, программа сломается…

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

Не, там начинается со скобочек, потом комментарии, а потом вообще по факту написать свой фронтенд для компилятора.

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

Например, через взаимосвязь кэшей и мютексов.

А можно подробнее? А то я всё долбаюсь с этими мьютексами на кэшах…

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

rudimentary syntax errors

тут много чего весёлого можно добавить. Достаточно простого советского препроцессора.

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

Я не помню детали, ибо серьёзно на Си не пишу. Но один пример изначального тезиса привести смогу: почему не безопасен доступ к полям структуры из тредов, если каждый тред работает только с определённым полем, которое не трогают другие?

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

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

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

Это не протекающая абстракция, это нафантазированная абстракция песочницы, которой на самом деле нет и не нужно.

firkax ★★★★★
()

К&Р. Это книга.

А задачник любой, хоть по Паскалю.

Припоминаю, как я, будучи студнем, учил ЯП. Это было что-то, смертельный номер. Бразилиан system . 😁

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

А он и безопасен. А как же иначе? Каждое поле структуры - отдельная переменная, они объединены в структуру только на уровне синтаксиса.

firkax ★★★★★
()

Stephen Prata, «C Primer Plus»

Gary ★★★★★
()

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

o_O Ты видимо ничего серьёзного на нём не делал. Ну или тебе нравится страдать.

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

Идëм вдоль строки, копируя символы, пока не наткнëмся на '/', если встретилась косая черта, запоминаем еë, идëм дальше, если опять встретили косую черту, вставляем '\n', читаем следующую строку. Если же после первой косой черты нет ни '*', ни '/', обнуляем last_char и продолжаем рассматривать текущую строку, пока не дойдëм до конца.

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

задачи есть на leetcode и codewars, сам язык учить по Стивен Прата «язык программирования си», программирование в Linux изучать по «Advanced Linux Programming» Марк Митчел, Джефри Олдман, Алекс Самуэл и «Unix: Разработка сетевых приложений» У. Р. Стивенс.

На мой взгляд, лучшие книги, рекомендую не пропустить их, а скачать и хоть немного изучить, потом втянитесь

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

Вроде она, писал лет 15 назад, что тут не учтено?

#include <stdio.h>

#define IN_CODE 1
#define IN_POSSIBLE_COMMENT 2
#define IN_COMMENT 3
#define IN_POSSIBLE_END_OF_COMMENT 4
#define IN_END_OF_COMMENT 5
#define IN_STRING 6
#define IN_CHAR 7

int main()
{
    int state = IN_CODE;
    int c;
    
    while((c=getchar()) != EOF) {
	if (state == IN_END_OF_COMMENT)
	    state = IN_CODE;
	
	if (c == '"' || c == '/' || c == '*' || c == '\'') {
	    if (c == '"' && state == IN_CODE)
		state = IN_STRING;
	    else if (c == '"' && state == IN_STRING)
		state = IN_CODE;
	    else if (c == '/' && state == IN_CODE)
		state = IN_POSSIBLE_COMMENT;
	    else if (c == '/' && state == IN_POSSIBLE_COMMENT)
		putchar('/');
	    else if (c == '*' && state == IN_POSSIBLE_COMMENT)
		state = IN_COMMENT;
	    else if (c != '*' && state == IN_POSSIBLE_COMMENT) {
		putchar('/');
		state = IN_CODE;
	    }
	    else if (c == '*' && (state == IN_COMMENT || state == IN_POSSIBLE_END_OF_COMMENT))
		state = IN_POSSIBLE_END_OF_COMMENT;
	    else if (c == '/' && state == IN_POSSIBLE_END_OF_COMMENT)
		state = IN_END_OF_COMMENT;
	    else if (c != '/' && state == IN_POSSIBLE_END_OF_COMMENT)
		state = IN_COMMENT;
	    else if (c == '\'' && state == IN_CODE)
		state = IN_CHAR;
	    else if (c == '\'' && state == IN_CHAR)
		state = IN_CODE;
	}
	

	if (state == IN_CODE || state == IN_STRING || state == IN_CHAR){
	    putchar(c);
	}
	
	
    }

    return 0;
}
masa ★★★
()
Последнее исправление: masa (всего исправлений: 1)

еще одна, «Алгоритмы на си» Роберт Седжвик, только не на си++ и не на Java, первая его книга именно на си

IvanRia
()

K&R тоже ничего, но возможно, что Стивен Прата лучше, так как K&R писалось в те года, когда программистами становились в университетах, а не дома за компьютером, есть вероятность, что Прата написано для обычных людей и намного лучше воспринимается, я правда Прату не читал

IvanRia
()

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

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

В С давно есть enum вместо срани с #define, а лесенку из if else if на switch переделать как обычный конечный автомат будет выглядеть

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

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

masa ★★★
()

еще конечно лучше писать какие-то реально нужные программы, а не искуственные задачи с codewars и leetcode, раньше можно было искать что-то на upwork, теперь к сожалению нельзя

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

О, я видимо нашел ту про которую ты говоришь, в моей редакции задача звучит так:

Упражнение 1.24. Напишите программу, проверяющую Си-программы на элементарные синтаксические ошибки вроде несбалансированности скобок всех видов. Не забудьте о кавычках (одиночных и двойных), эскейп-последовательностях (...) и комментариях. (Это сложная программа, если писать ее для общего случая.)

#include <stdio.h>

#define ERROR 1
#define OK 0

#define IN_CODE 1
#define POSSIBLE 2
#define IN_COMMENT 4
#define END 8
#define IN_STRING 16
#define IN_CHAR 32
#define IN_ESCAPE_SEQUENCE 64
#define START 128

int check_input();
int get_new_state(int state, int c);
void count_symbol(int c);
int get_result();
int check_even(int num);
    
int quotes = 0;
int double_quotes = 0;
int open_braces = 0;
int close_braces = 0;
int open_round_brackets = 0;
int close_round_brackets = 0;

    
int main() 
{
    if (check_input() == ERROR) {
	printf("Error found\n");
	return ERROR;
    }
    else {
	printf("Syntax ok\n");
	return OK;
    }
}

int check_input() 
{
    int state, i, c;

    state = IN_CODE;
    while((c = getchar()) != EOF) {
	state = get_new_state(state, c);
	if (state == IN_CODE ||
	    state == IN_COMMENT + POSSIBLE||
	    state == IN_CHAR + START ||
	    state == IN_STRING + START ||
	    state == IN_CHAR + END ||
	    state == IN_STRING + END) {
	    count_symbol(c);
	}
    }
    
    return get_result();
}


void count_symbol(int c) 
{
    if (c == '\'')
	++quotes;
    else if (c == '\"')
	++double_quotes;
    else if (c == '{')
	++open_braces;
    else if (c == '}')
	++close_braces;
    else if (c == '(')
	++open_round_brackets;
    else if (c == ')')
	++close_round_brackets;
}

int get_new_state(int state, int c) 
{
    if (state == IN_COMMENT + END ||
	state == IN_STRING + END ||
	state == IN_CHAR + END)
	state = IN_CODE;
    else if (state == IN_STRING + START)
	state = IN_STRING;
    else if (state == IN_CHAR + START)
	state = IN_CHAR;
    else if (state == IN_CHAR + IN_ESCAPE_SEQUENCE ||
	     state == IN_STRING + IN_ESCAPE_SEQUENCE)
	state = state - IN_ESCAPE_SEQUENCE;
    else if (state == IN_CHAR + IN_ESCAPE_SEQUENCE + END ||
	     state == IN_STRING + IN_ESCAPE_SEQUENCE + END)
	state = state - IN_ESCAPE_SEQUENCE - END;

    if (c == '"' && state == IN_CODE)
	state = IN_STRING + START;
    else if (c == '"' && state == IN_STRING)
	state = IN_STRING + END;
    else if (c == '/' && state == IN_CODE)
	state = IN_COMMENT + POSSIBLE;
    else if (c == '*' && state == IN_COMMENT + POSSIBLE)
	state = IN_COMMENT;
    else if (c != '*' && state == IN_COMMENT + POSSIBLE) 
	state = IN_CODE;
    else if (c == '*' && (state == IN_COMMENT || state == IN_COMMENT + END + POSSIBLE))
	state = IN_COMMENT + END + POSSIBLE;
    else if (c == '/' && state == IN_COMMENT + END + POSSIBLE)
	state = IN_COMMENT + END;
    else if (c != '/' && state == IN_COMMENT + END + POSSIBLE)
	state = IN_COMMENT;
    else if (c == '\'' && state == IN_CODE)
	state = IN_CHAR + START;
    else if (c == '\'' && state == IN_CHAR)
	state = IN_CHAR + END;
    else if (c == '\\' && (state == IN_CHAR || state == IN_STRING))
	state = state + IN_ESCAPE_SEQUENCE + START;
    else if (state == IN_CHAR + IN_ESCAPE_SEQUENCE + START ||
	     state == IN_STRING + IN_ESCAPE_SEQUENCE + START)
	state = state - START + END;
	  

    return state;    
}

int get_result() 
{
    /* printf("quotes: %d\ndouble_quotes: %d\nopen_braces: %d\nclose_braces: %d\nopen_round_brackets: %d\nclose_round_brackets: %d\n", */
    /* 	   quotes, double_quotes, open_braces, close_braces, open_round_brackets, close_round_brackets); */

    if (check_even(quotes) == OK &&
	check_even(double_quotes) == OK &&
	open_braces == close_braces &&
	open_round_brackets == close_round_brackets)
	return OK;
    else
	return ERROR;
}

int check_even(int num)
{
    int m;
    m = num / 2;
    if (m * 2 == num)
	return OK;
    else
	return ERROR;
}

PS: на знание си не претендую, дальше второй главы не читал

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

А. В. Столяров. «Программирование: введение в профессию»

vbr ★★★★★
()

Искусство программирования на Си

Только это книга не про язык Си, это про то, как писать на нём программы.

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