Форум русскоязычного сообщества Ubuntu


Хотите сделать посильный вклад в развитие Ubuntu и русскоязычного сообщества?
Помогите нам с документацией!

Автор Тема: программа без #include<файл> (си)  (Прочитано 6155 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Sеrgеy

  • Автор темы
  • Новичок
  • *
  • Сообщений: 4
    • Просмотр профиля
программа без #include<файл> (си)
« : 26 Марта 2011, 00:13:28 »
допустим, мне нужно написать программу копирования входного потока в выходной.
вот как она должна выглядеть:
#include <stdio.h>
int main(void)
{
    int ch;
    while(1)
    {
        ch = getchar();
        if(ch!=EOF)putchar(ch);
        else break;
    }
}
Эта версия написана с подключенным stdio.h
Но мне нужно написать эту программу вообще без подключаемых библиотечных файлов.
У меня есть версия этой программы, когда используются фактически только системные вызовы, но это опять же подключение файла syscall.h
Никто не может помочь?
хотя бы советом ._.
« Последнее редактирование: 26 Марта 2011, 00:22:14 от Sеrgеy »

Оффлайн Мангуст

  • Любитель
  • *
  • Сообщений: 98
    • Просмотр профиля
Re: программа без #include<файл> (си)
« Ответ #1 : 26 Марта 2011, 05:40:59 »
Очень желательно различать и знать, что такое:

1. Библиотечный файл.
2. Подключаемый динамически или статически библиотечный файл.
3. Включаемый файл заголовка.

По теме - нужно объявить используемые функции, хотя это не обязательно, если функция возвращает int. Обе используемые функции так и делают, поэтому осталось узнать чему равен EOF (это целое - int - как узнать? чему?) и можно вместо #include<stdio> вставить
#define EOF ???и пример спокойно скомпилируется и будет работать.

Оффлайн Sеrgеy

  • Автор темы
  • Новичок
  • *
  • Сообщений: 4
    • Просмотр профиля
Re: программа без #include<файл> (си)
« Ответ #2 : 26 Марта 2011, 10:42:06 »
Мангуст, все не так просто.
ну, ЕОF имеет значение (-1), то бишь строка
#define EOF (-1)
работает в точности как надо.
но как мне сделать системный вызов без подключения библиотеки компилятора? вот в этом вся проблема.
мне нужно сделать только два системных вызова - read и  write
Функции, аналогичные этим системным вызовам и одноименные с ними находятся в БИБЛИОТЕЧНОМ файле syscall.h
я порылся немного в этой библиотеке, но все равно не понимаю, как сделать, написать эти функции, самому.
как мне сделать системный вызов без подключения библиотечных файлов?

Lifewalker

  • Гость
Re: программа без #include<файл> (си)
« Ответ #3 : 26 Марта 2011, 11:16:35 »
мне нужно сделать только два системных вызова - read и  write
Функции, аналогичные этим системным вызовам и одноименные с ними находятся в БИБЛИОТЕЧНОМ файле syscall.h

Шоб вы поняли, в syscall.h находится интерфейс к системным вызовам, но не сами вызовы. Их реализация находится глубоко в недрах ядра.

Без единого #include вы можете создать только "программу в себе", то есть нечто, использующее только средства языка программирования. Фактически, это минимальный набор операций типа размещения переменных в регистре или стеке, вычислительные операции и всё.

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

P.S. Кстати, вот и аргумент к моему настаиванию на использовании в преподовании Паскаля (вернее даже Модулы или ОП). Там в модулях чётко разделены интерфейсы и реализации. Сишник до понимания этой простейшей концепции допереть не может.
« Последнее редактирование: 26 Марта 2011, 11:21:03 от Lifewalker »

Оффлайн Sеrgеy

  • Автор темы
  • Новичок
  • *
  • Сообщений: 4
    • Просмотр профиля
Re: программа без #include<файл> (си)
« Ответ #4 : 26 Марта 2011, 11:37:12 »
Lifewalker, я это понимаю, я знаю, что сами вызовы в ядре, но как мне используя только средства языка сделать системный вызов?
Ведь вся библиотека так написана, значит есть способы.
Цитировать
Все прочие действия требуют обращения к системным вызовам, даже банальное выделение памяти под строку или массив. А ввод и вывод тем более.
я как раз хочу к ним обратится, но как мне обратится, используя только средства языка??
проблема то именно в этом.

Пользователь решил продолжить мысль 26 Марта 2011, 11:41:47:
в syscall.h находятся функции, которые по своему "оформлению" аналогичны системным вызовам, как бы интерфейс для них. они одноименны с ними и вызывают соответствующий системный вызов. Функция read(int fd, char *buf, int n) вызывает абсолютно аналогичный по виду системный вызов, "давая" ему данные из своих аргументов. КАК она это делает? Как она написана вообще?
« Последнее редактирование: 26 Марта 2011, 11:41:47 от Sеrgеy »

Оффлайн Мангуст

  • Любитель
  • *
  • Сообщений: 98
    • Просмотр профиля
Re: программа без #include<файл> (си)
« Ответ #5 : 26 Марта 2011, 11:50:42 »
Цитировать
Без единого #include вы можете создать только "программу в себе", то есть нечто, использующее только средства языка программирования. Фактически, это минимальный набор операций типа размещения переменных в регистре или стеке, вычислительные операции и всё.
  :o

Цитировать
Сишник до понимания этой простейшей концепции допереть не может.
   :'(

 :coolsmiley:

C - язык очень близкий к компьютеру вообще, и к UNIX, в частности. Чтобы понять, что такое библиотеки, системные вызовы, файлы, стек, и прочее - надо залезть чуть поглубже - рекомендую проштудировать Programming from Ground Up - свободная книга (ассемблера много). Там вся программная модель С по полочкам разложена.

А насчет Паскаля и прочих оберонов - мда... Крепка советская школа. ;)

===

2 Sergey - берешь и обращаешься - твоя программа:

#define BUFSIZ 512

main()
{
    char buf[BUFSIZ];
    int n;

    while((n = read(0, buf, BUFSIZ)) > 0)
        write(1, buf, n);

    return 0;
}


Пользователь решил продолжить мысль 26 Марта 2011, 12:13:14:
Включаемый файл с расширением .h - это простой текстовый файл и содержит в себе, как правило объявления макросов и функций. Они или физически присутствуют в папке /usr/include или компилятор "знает" содержание этих файлов.

При компиляции компилятор проверяет вызовы функций (количество и тип аргументов и тип возвращаемого значения) на соответствие объявлению данной функции. По историческим причинам, если функция не объявлена (т. е. не включен соответсвующий .h файл), аргументы не проверяются, а функция считается, что возвращает значение int. Если это не так - вываливаемся при попытке запуска скомпилированного файла.

Объявления необходимых функций и макросов можно сделать и самостоятельно, если их знать. Объявление write можно получить задав команду man 2 write или просмотрев заголовочный файл. syscalls.h - это для linux-а /usr/include/unistd.h

Код для вызова системных функций gcc встраивает непосредственно в исполняемый файл - никаких дополнительных библиотек (библиотечных файлов) не требуется.
« Последнее редактирование: 26 Марта 2011, 12:13:14 от Мангуст »

Оффлайн Sеrgеy

  • Автор темы
  • Новичок
  • *
  • Сообщений: 4
    • Просмотр профиля
Re: программа без #include<файл> (си)
« Ответ #6 : 26 Марта 2011, 12:23:32 »
о.о
я думал, что эти функции - read и write - перед использованием должны быть обьявлены, как и остальные.
я ошибаюсь?
но прога РАБОТАЕТ О.О

Пользователь решил продолжить мысль 26 Марта 2011, 13:22:12:
все, спасибо огромное, разобрался более-менее =)
« Последнее редактирование: 26 Марта 2011, 13:22:12 от Sеrgеy »

Оффлайн Yurror

  • Старожил
  • *
  • Сообщений: 1966
    • Просмотр профиля
Re: программа без #include<файл> (си)
« Ответ #7 : 26 Марта 2011, 19:19:33 »
Ни фига ты не разобрался а еще больше запутался. Не все ответы на форумах одинаково полезны... Стоит их проверять.
yurik@book:~$ cat test.c
#define BUFSIZ 512

int main()
{
    char buf[BUFSIZ];
    int n;

    while((n = read(0, buf, BUFSIZ)) > 0)
        write(1, buf, n);

    return 0;
}
yurik@book:~$ gcc test.c
yurik@book:~$ ldd a.out
linux-gate.so.1 =>  (0x00dfb000)
libc.so.6 => /lib/libc.so.6 (0x00b57000)
/lib/ld-linux.so.2 (0x00991000)
yurik@book:~$ gcc -nostdlib test.c
/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 00000000080480b8
/tmp/cc4V2mim.o: In function `main':
test.c:(.text+0x29): undefined reference to `write'
test.c:(.text+0x45): undefined reference to `read'
collect2: ld returned 1 exit status

я думал, что эти функции - read и write - перед использованием должны быть обьявлены, как и остальные.
Ты правильно думал. Компилятор Си на лету сам себе генерит их объявление. Ну типа размышления компилятора: "ну пусть будет так, а потом поищу подобное в библиотеках". и находит. в стандартной библиотеке. А вот когда отбираешь у него "читательский билет"...

Вообще идея верна. Есть системные вызовы read и write. И, ты уже, видимо, нашел правильное решение.
Цитировать
У меня есть версия этой программы, когда используются фактически только системные вызовы, но это опять же подключение файла syscall.h
И тут тебя угораздило спросить знатаков...
Заголовочные файлы это фигня. Вот разделяемые библиотеки это хуже. Они бывают разных версий, конфликтуют с друг другом, их может не хватать на компе соседа и прочее... То ли дело стабильный интерфейс системных вызовов ядра. Будет работать еще сто лет. Возникает желание сделать программу без использования библиотек. Даже стандарных. Один хрен read и write что мы все каждый день используем всего лишь обертки над этими самыми системными вывовами.

Или тебе пофиг что на самом деле stdio все равно отстался подключен. Просто заголовка в исходнике не стало. Экономия места на диске. Аж 18 байт. А то и 19 с переводом строки! Ну тогда флаг в руки и барабан на шею! Это победа!

Пользователь решил продолжить мысль 26 Марта 2011, 15:25:15:
Мангуст, а потом я внимательнее прочитал твой пост =) все верно. Просто я увидил твой пример кода и что топикстартер его радостно схватил и убежал думая что он "легко победил систему" =) так и родилась моя партянка.
« Последнее редактирование: 26 Марта 2011, 19:25:55 от Yurror »

Оффлайн Sеr

  • Любитель
  • *
  • Сообщений: 60
  • Познаю мир, пока не в вузе...
    • Просмотр профиля
Re: программа без #include<файл> (си)
« Ответ #8 : 26 Марта 2011, 21:27:55 »
так, обьясните пожалуйста поподробней, я теперь запутался по уши.
исходник я не хватал, у меня совершенно другая прога, эта нужна была, так сказать, для "понимания".
как мне написать программу, которая бы делала системный вызов и не подключала стандартных библиотек? вот, как будто бы их нету, просто сам компилятор, а папки include не существует на компе. проблема еще хуже стала, походу..

Пользователь решил продолжить мысль 26 Марта 2011, 21:36:58:
Цитировать
Код для вызова системных функций gcc встраивает непосредственно в исполняемый файл - никаких дополнительных библиотек (библиотечных файлов) не требуется.
это в буквальном смысле? я что то путаюсь.
« Последнее редактирование: 26 Марта 2011, 21:36:58 от Sеr »

Lifewalker

  • Гость
Re: программа без #include<файл> (си)
« Ответ #9 : 26 Марта 2011, 22:21:01 »
как мне написать программу, которая бы делала системный вызов и не подключала стандартных библиотек?
Это невозможно! Явно или не явно библиотеки будут подключены.

Цитировать
Код для вызова системных (не сами функции, а код вызова - Lw.) функций gcc встраивает непосредственно в исполняемый файл - никаких дополнительных библиотек (библиотечных файлов) не требуется
это в буквальном смысле? я что то путаюсь.
Это в буквальном смысле, важное выделенно мной. Компилятор тупо вставляет в таблицу импорта исполняемой программы вызов системного вызова с подходящим именем. При этом не делает никаких проверок, ни на число аргументов, ни на их тип, ни на возвращаемое значение. Вам просто повезло, что всё сработало.

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

P.S. Изучите как работают модули во ФриПаскале (Модулу не предлагаю). Когда разберётесь чем interface отличается от implementation, тогда можно переходить к Си. Если желание останется :)
« Последнее редактирование: 26 Марта 2011, 22:22:37 от Lifewalker »

Оффлайн Sеr

  • Любитель
  • *
  • Сообщений: 60
  • Познаю мир, пока не в вузе...
    • Просмотр профиля
Re: программа без #include<файл> (си)
« Ответ #10 : 26 Марта 2011, 23:09:46 »
Lifewalker, но ведь и библиотеки писались на чистом языке первоначально. другой вопрос, как ведет себя компилятор...
Цитировать
P.S. Изучите как работают модули во ФриПаскале (Модулу не предлагаю). Когда разберётесь чем interface отличается от implementation, тогда можно переходить к Си. Если желание останется
я не хочу лезть в паскаль, мне неинтересно...тем более я уже за си взялся.
я отличаю интерфейс от настоящих вызовов..=-=

Оффлайн cebrione

  • Любитель
  • *
  • Сообщений: 92
    • Просмотр профиля
Re: программа без #include<файл> (си)
« Ответ #11 : 26 Марта 2011, 23:36:11 »
Тут надо по-другому спрашивать, наверное. Хоть программированием я занимался поверхностно, но автора, кажется, понимаю.

Ему надо написать собственную библиотеку и включить ее в код программы.

Если вы скажете, что это невозможно, то позвольте возразить. Как тогда писались все эти библиотеки?

Оффлайн Sеr

  • Любитель
  • *
  • Сообщений: 60
  • Познаю мир, пока не в вузе...
    • Просмотр профиля
Re: программа без #include<файл> (си)
« Ответ #12 : 26 Марта 2011, 23:44:46 »
ну....не так, но близко.
я тут увлекся написанием своей оси...и решил сначала изучить, как работает система, как работает язык си. ну, как написать программу без стандартных библиотек...ну и так далее.
и сразу фактически на этом этапе остановился. прога то работает. но библиотеки, видимо, подключает.
и мне нужно знать, как настроить компилятор под ядро...блин, не так сказал. вобщем, я думаю, понятно.
мне сначала нужно написать прогу, использующую только собственные ресурсы, без использования стандартных библиотек языка.

Оффлайн hippi90

  • Активист
  • *
  • Сообщений: 433
    • Просмотр профиля
Re: программа без #include<файл> (си)
« Ответ #13 : 27 Марта 2011, 04:49:21 »
Собственно с этого и надо было начинать.
По операционным системам читать Таненбаума "Операционные системы: разработка и реализация", а так же "Архитектура компьютера". Две фундаментальных труда.
Чтобы gcc не линковал объектный код с библиотеками есть опция -c, подробнее опять же в манах.

Lifewalker

  • Гость
Re: программа без #include<файл> (си)
« Ответ #14 : 27 Марта 2011, 06:59:20 »
Ему надо написать собственную библиотеку и включить ее в код программы.
В принципе логично. В данном случае написать программу = создать собственную библиотеку.

Понимаете, у меня есть ощущение, что ТС никогда даже близко не занимался например разработкой программ для микроконтроллеров или не программировал для ДОС. Он представления не имеет (или не до конца понимает) где проходит граница между ОС и программой. Отсюда следует непонимание того, как эту границу двигать :) А ему нужно отодвинуть границу до уровня железа, то есть фактически он хочет написать операционную систему.

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

 

Страница сгенерирована за 0.042 секунд. Запросов: 25.