Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Язык Си Керниган, Ричи

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4

Открыть новую тему     Написать ответ в эту тему

S_Leha



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Читаю книгу Язык C Кернигана, Ричи. Помогите пожалуйста разобраться.
-----------------------------------------------------------
…программы распреде-
ления памяти. Имеются две функции: функция ALLOC(N) возвра-
щает в качестве своего значения указатель P, который указы-
вает на первую из N последовательных символьных позиций, ко-
торые могут быть использованы вызывающей функцию ALLOC прог-
раммой для хранения символов; функция FREE(P) освобождает
приобретенную таким образом память, так что ее в дальнейшем
можно снова использовать. программа является "элементарной",
потому что обращения к FREE должны производиться в порядке,
обратном тому, в котором производились обращения к ALLOC.
 
Простейшая реализация состоит в том, чтобы функция раз-
давала отрезки большого символьного массива, которому мы
присвоили имя ALLOCBUF. Этот массив является собственностью
функций ALLOC и FREE. Так как они работают с указателями, а
не с индексами массива, никакой другой функции не нужно
знать имя этого массива. Он может быть описан как внешний
статический, т.е. Он будет локальным по отношению к исходно-
му файлу, содержащему ALLOC и FREE, и невидимым за его пре-
делами. При практической реализации этот массив может даже
не иметь имени; вместо этого он может быть получен в резуль-
тате запроса к операционной системе на указатель некоторого
неименованного блока памяти.
 
Другой необходимой информацией является то, какая часть
массива ALLOCBUF уже использована. Мы пользуемся указателем
первого свободного элемента, названным ALLOCP. Когда к функ-
ции ALLOC обращаются за выделением N символов, то она прове-
ряет, достаточно ли осталось для этого места в ALLOCBUF. Ес-
ли достаточно, то ALLOC возвращает текущее значение ALLOCP
(т.е. Начало свободного блока), затем увеличивает его на N,
с тем чтобы он указывал на следующую свободную область. Фун-
кция FREE(P) просто полагает ALLOCP равным P при условии,
что P указывает на позицию внутри ALLOCBUF.
 
Объясните чтобы было понятно
 -----------------------------------------------------------
 
Вот сам код.
 
DEFINE NULL 0  /* POINTER VALUE FOR ERROR REPORT */
DEFINE ALLOCSIZE 1000  /* SIZE OF AVAILABLE SPACE */
 
STATIC CHAR ALLOCBUF[ALLOCSIZE];/* STORAGE FOR ALLOC */
STATIC CHAR *ALLOCP = ALLOCBUF; /* NEXT FREE POSITION */
 
CHAR *ALLOC(N)  /* RETURN POINTER TO N CHARACTERS  */
INT N;
{
 IF (ALLOCP + N <= ALLOCBUF + ALLOCSIZE)
   {
     ALLOCP += N;
     RETURN(ALLOCP - N); /* OLD P */
   }
 ELSE         /* NOT ENOUGH ROOM */
     RETURN(NULL);
}
FREE(P)    /* FREE STORAGE POINTED BY P */
CHAR *P;
{
 IF (P >= ALLOCBUF && P < ALLOCBUF + ALLOCSIZE)
    ALLOCP = P;
}

Всего записей: 108 | Зарегистр. 02-07-2003 | Отправлено: 22:06 30-07-2003
EAS



Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Странный код прямо скажем. Помоему у тебя K&R в очень поганой версии. Может так тебе понятней станет:
 
#define NULL 0  /* POINTER VALUE FOR ERROR REPORT */  
#define ALLOCSIZE 1000  /* SIZE OF AVAILABLE SPACE */  
 
static char ALLOCBUF[ALLOCSIZE];/* STORAGE FOR ALLOC */  
static char *ALLOCP = ALLOCBUF; /* NEXT FREE POSITION */  
 
char* ALLOC(int N)  /* RETURN POINTER TO N CHARACTERS  */  
{  
  if(ALLOCP + N <= ALLOCBUF + ALLOCSIZE)  
  {  
     ALLOCP += N;  
     return (ALLOCP - N); /* OLD P */  
  }  
  else         /* NOT ENOUGH ROOM */  
  {
     return NULL;  
  }
}  
 
void FREE(char *P)    /* FREE STORAGE POINTED BY P */  
{
  if(P >= ALLOCBUF && P < ALLOCBUF + ALLOCSIZE)
  {
    ALLOCP = P;  
  }
}  
 
Чуть-чуть ближе к жизни привел . Все равно кривизна, конечно.
IMHO тебе надо нормальное издание взять.
 
ЗЫ: Или тебе что-то конкретно, по принципу работы не понятно?

Всего записей: 441 | Зарегистр. 18-07-2003 | Отправлено: 06:59 31-07-2003
S_Leha



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Или тебе что-то конкретно, по принципу работы не понятно?  

Мне не понятен смысл функции ALLOC
---------------------------------------------------------------------------------------------------------
#define NULL 0  
#define ALLOCSIZE 1000  
   
static char ALLOCBUF[ALLOCSIZE]; /* Правильно я понимаю, что в этот массив нужно забить символы? */
 
static char *ALLOCP = ALLOCBUF;    
 
char* ALLOC(int N)  /* Почему имя функции определенно как указатель?  */  
{  
  if(ALLOCP + N <= ALLOCBUF + ALLOCSIZE) /* Сравнение чего здесь происходит? */  
  {  
     ALLOCP += N;  
     return (ALLOCP - N);  
  }  
  else      
  {  
     return NULL;  
  }  
}  
 
void FREE(char *P)   /* С чем работает эта функция? */  
{  
  if(P >= ALLOCBUF && P < ALLOCBUF + ALLOCSIZE) /* Опять же, что здесь сравнивается?*/
  {  
    ALLOCP = P;  
  }  
}  
 

Всего записей: 108 | Зарегистр. 02-07-2003 | Отправлено: 13:47 31-07-2003
FireBrizz



Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
S_Leha

Цитата:
Правильно я понимаю, что в этот массив нужно забить символы?

неа, char - это тип данных, в ДОС размер 1 байт (просто так удобно задавать массивы - типа 1000 байт)

Цитата:
Почему имя функции определенно как указатель?

потомучто она возврашает указатель (ну или адрес первого из выделенных N байтов)

Цитата:
Сравнение чего здесь происходит?

Определяется достаточно ли в буфере места под еще N байт

Цитата:
С чем работает эта функция?

С указателем на область которую пользователь возвращает буфферу

Цитата:
Опять же, что здесь сравнивается?

проверяется лежит ли начало данной области в буффере
 
Ну а функция - выделяет N байт в своем буфере (ну нету в C оператора new - чтобы работать с массивом переменной длины к примеру)

Всего записей: 223 | Зарегистр. 19-02-2003 | Отправлено: 14:25 31-07-2003
S Leha



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Вот теперь я все понял! Спасибо.
 
Добавлено
У меня есть еще несколько вопросов, с которыми я не могу разобраться.
 
1. "При достижении конца файла функция getchar() возвращает значение EOF" - что за файл?
2. Чем double отличается от float ?
3. "if( c >= '0' && c <= '9' ) определяет, является ли символ в С цифрой, и если это так, то численное значение этой цыфры определяется по формуле  С - '0' " - разъясните пожалуйста, что за формула?  
 

Цитата:
тебе надо нормальное издание взять.  

 Книгу только в магазине можно купить или она есть в Интернете?

Всего записей: 108 | Зарегистр. 02-07-2003 | Отправлено: 21:10 31-07-2003
EAS



Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
S Leha
Извини конечно, но IMHО тебе надо либо СРОЧНО книжку менять, либо читать ее сначала (про синтаксис и т.п.).

Цитата:
"При достижении конца файла функция getchar() возвращает значение EOF" - что за файл?

getchar() возвращает EOF при ошибке чтения из stdin

Цитата:
Чем double отличается от float  

double -- 8 байт (1.7E+/-308, 15 значащих цифр); float -- 4 байта (3.4E+/-38, ~7 зн.цифр)

Цитата:
if( c >= '0' && c <= '9' ) определяет, является ли символ в С цифрой

Угу

Цитата:
по формуле  С - '0'

Символы цифр имеют ASCII-коды с 0x30 (0) по 0x39 (9). Написать '0' или 0x30 или 48 -- одно и тоже. Например, если char C = '8' (== 0x38) получаем в символах: '8' - '0' == 8; в числах: 0x38 - 0x30 == 0x08

Цитата:
Книгу только в магазине можно купить или она есть в Интернете?

Есть в магазине, есть в инете (напр. h**p://www.rusdoc.ru, h**p://www.citforum.ru и т.д.), здесь можешь спросить http://forum.ru-board.com/topic.cgi?forum=35&bm=1&topic=15098#1

Всего записей: 441 | Зарегистр. 18-07-2003 | Отправлено: 04:31 01-08-2003 | Исправлено: EAS, 04:38 01-08-2003
S Leha



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
...читать ее сначала

 Уже начал.

Цитата:
getchar() возвращает EOF при ошибке чтения из stdin  

 Да, но она также возвращает EOF при достижении конца файла ввода. Как достич этого конца?

Всего записей: 108 | Зарегистр. 02-07-2003 | Отправлено: 08:23 01-08-2003
f_serg



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
S Leha

Цитата:
Как достич этого конца?

Где? В Досе Ctrl-Z, в *nix-е Ctrl-D.

----------
Serg

Всего записей: 1706 | Зарегистр. 11-09-2002 | Отправлено: 09:51 01-08-2003
S Leha



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Подскажите, почему я не могу работать с функциями графики?
При попытки запуска вот что:
 
BGI ERROR: GRAPHICS NOT INITIALIZED (USE 'INITGRAPH')
Думаю, что нужно как то это инициализировать.
 
Работаю в Turbo C 2.01

Всего записей: 108 | Зарегистр. 02-07-2003 | Отправлено: 20:41 01-08-2003
rew



Full Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
читай хелп к initgraph

----------
плох тот error который не мечтает стать general`ом

Всего записей: 442 | Зарегистр. 09-09-2001 | Отправлено: 21:06 01-08-2003
S Leha



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Вопросик:  
Как описать внешнюю переменную в функции неявным описанием по контексту?

Всего записей: 108 | Зарегистр. 02-07-2003 | Отправлено: 17:14 02-08-2003
mymuss



Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
EAS

Цитата:
char - это тип данных, в ДОС размер 1 байт  

Я бы даже сказал: везде гарантировано 1 байт

Цитата:
double -- 8 байт (1.7E+/-308, 15 значащих цифр); float -- 4 байта (3.4E+/-38, ~7 зн.цифр)

Не факт.
 
S Leha

Цитата:
Как описать внешнюю переменную в функции неявным описанием по контексту?

Не понимаю: что такое "внешняя переменная" и что такое "описание по контексту".
Если тебе нужно описать переменную которая определена где-то в другом файле - используй модификатор extern. Если тебе нужно получить доступ к переменной, которая не находится в области видимости данной функции (т.е. не глобальная, не определенная в данной функции) то тебе остается лишь передавать ее как параметр.

----------
(a + b^n) / n = x, donc Dieu existe; répondez !
Euler

Всего записей: 709 | Зарегистр. 13-04-2003 | Отправлено: 19:11 02-08-2003
S Leha



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Не понимаю: что такое "внешняя переменная" и что такое "описание по контексту".

Внешняя, думаю глобальная, а "описание по контексту" - сам не понял.
 
   Вот текст из K&R:
Внешняя переменная должна быть определена вне всех функ-
ций; при этом ей выделяется фактическое место в памяти. Та-
кая переменная должна быть также описана в каждой функции,
которая собирается ее использовать; это можно сделать либо
явным описанием EXTERN, либо неявным по контексту.  
                                                               

Всего записей: 108 | Зарегистр. 02-07-2003 | Отправлено: 13:11 03-08-2003
mymuss



Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
S Leha
Мда, у тебя действительно ОЧЕНЬ плохая версия КР. Срочно найди другую.
 
Вот как это место выглядит в оригинале:

Цитата:
An external variable must be defined, exactly once, outside of any function; this sets aside
storage for it. The variable must also be declared in each function that wants to access it; this
states the type of the variable. The declaration may be an explicit extern statement or may be implicit from context.

("The C Programming Language. Second Edition" Prentice Hall).
 
А через 2 абзаца объясняется как обойтись без extern:

Цитата:
In certain circumstances, the extern declaration can be omitted. If the definition of the
external variable occurs in the source file before its use in a particular function, then there is
no need for an extern declaration in the function.


----------
(a + b^n) / n = x, donc Dieu existe; répondez !
Euler

Всего записей: 709 | Зарегистр. 13-04-2003 | Отправлено: 23:49 03-08-2003
BugFixer

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
S_Leha

Цитата:
if(ALLOCP + N <= ALLOCBUF + ALLOCSIZE) /* Сравнение чего здесь происходит? */    
......
void FREE(char *P)   /* С чем работает эта функция? */  
............
if(P >= ALLOCBUF && P < ALLOCBUF + ALLOCSIZE) /* Опять же, что здесь сравнивается?*/  

Основная проблема (с моей точки зрения): товариСЧ не понимает сути указателей и арифметики, с ними связаной.
 
А книжка действительно старая, там даже примеры на "оригинальном" C&R С (я на нём последний раз писал хоть что-нибудь году эдак в 87, однако!)

Всего записей: 482 | Зарегистр. 02-08-2003 | Отправлено: 10:05 04-08-2003
S Leha



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Основная проблема (с моей точки зрения): товариСЧ не понимает сути указателей и арифметики, с ними связаной.  

Да нет теперь я въехал. Я просто думал, что эти функции должны работать c символами, а не с памятью. А про        A = &s[0]; *(A + 1), A - I        - тоже пока все понимаю.  
 
Добавлено
С помощью этой тему передо мной открылось много нюансов языка. Теперь могу двигаться дальше и спокойно выполнять упражнения.  
Книгу(электронную) я пытался найти, но ничего не вышло, вот попробую счаЗ поискать.

Всего записей: 108 | Зарегистр. 02-07-2003 | Отправлено: 22:09 04-08-2003
BugFixer

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
S Leha

Цитата:
Я просто думал, что эти функции должны работать c символами, а не с памятью.  

А куда же эти символы засовывать, как не в память?  

Всего записей: 482 | Зарегистр. 02-08-2003 | Отправлено: 16:12 05-08-2003
BugFixer

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
S Leha

Цитата:
A = &s[0];  

Видимо, описано это так:
char *A;
char s[N];
тогда выражение A = &s[0]; абсолютно эквивалентно выражению A = s;
 
И вообще, байтовые массивы можно смело рассматривать как указатель на память, в которой это лежит

Всего записей: 482 | Зарегистр. 02-08-2003 | Отправлено: 05:35 06-08-2003 | Исправлено: BugFixer, 05:36 06-08-2003
mymuss



Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
S Leha

Цитата:
Книгу(электронную) я пытался найти, но ничего не вышло

Спросил бы у меня что-ли...
Смотри в ПМ

----------
(a + b^n) / n = x, donc Dieu existe; répondez !
Euler

Всего записей: 709 | Зарегистр. 13-04-2003 | Отправлено: 07:14 06-08-2003
S Leha



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Смотри в ПМ

 А ПМ это где?
 
 
Добавлено
Объясните мне вот эти упражнения. Мне не понятно само задание.
 
 Упражнение 1-19
   ---------------
    Напишите программу DETAB, которая заменяет табуляции во
вводе на нужное число пробелов так, чтобы промежуток дости-
гал следующей табуляционной остановки. Предположите фиксиро-
ванный набор табуляционных остановок, например, через каждые
N позиций.
 
    Упражнение 1-20
    ----------------
    Напишите программу ENTAB, которая заменяет строки пробе-
лов минимальным числом табуляций и пробелов, достигая при
этом тех же самых промежутков. Используйте те же табуляцион-
ные остановки, как и в DETAB.
 
    Упражнение 1-21
    ----------------
    Напишите программу для "сгибания" длинных вводимых строк
после последнего отличного от пробела символа, стоящего до
столбца N ввода, где N - параметр. убедитесь, что ваша прог-
рамма делает что-то разумное с очень длинными строками и в
случае, когда перед указанным столбцом нет ни табуляций, ни
пробелов.
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
 
А эти понятны, но не имею представления, как их выполнить. Намекните на нужные действия, но только намекните.
 
    Упражнение 1-22
    ----------------
    Напишите программу удаления из "C"-программы всех ком-
ментариев. Не забывайте аккуратно обращаться с "закавыченны-
ми" строками и символьными константами.
 
    Упражнение 1-23
    ----------------
    Напишите программу проверки "C"-программы на элементар-
ные синтаксические ошибки, такие как несоответствие круглых,
квадратных и фигурных скобок. Не забудьте о кавычках, как
одиночных, так и двойных, и о комментариях. (Эта программа
весьма сложна, если вы будете писать ее для самого общего
случая).

Всего записей: 108 | Зарегистр. 02-07-2003 | Отправлено: 21:43 06-08-2003
Открыть новую тему     Написать ответ в эту тему

Страницы: 1 2 3 4

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Язык Си Керниган, Ричи


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru