Показаны сообщения с ярлыком C. Показать все сообщения
Показаны сообщения с ярлыком C. Показать все сообщения

четверг, 19 июля 2012 г.

lseek

Роберт Лав, как оказалось, пишет довольно увлекательно. Узнал для себя немало нового из его книги "Linux. Системное программирование". Одним из открытий хочу поделиться.
Системный вызов lseek() предназначен для установки позиции в файле, соответствующем файловому дескриптору. Однако у него есть одно забавное применение. Возможно использовать lseek() для 'перемотки' файла за его(файла) предел. Если после этого записать что-то в текущую позицию, место между концом файла и позицией заполнится нулями.

воскресенье, 8 июля 2012 г.

Main

Прогуливаясь по файловой системе, обнаружил в закромах небольшой файл с кодом. Взглянув на него, я вспомнил, что некоторое время назад пытался понять можно ли в Си вызвать функцию main рекурсивно. Тогда я не закончил исследование - вероятно, не хватило навыка работы с указателями.
Оказывается, main ничем от других функций не отличается (помимо того, что является точкой входа в программу). Приведённый ниже код компилируется с самыми "жёсткими" флагами и успешно работает (печатает переданные аргументы).

#include <stdio.h>

int main(int argc, char *argv[]) {
    if (argc > 1) {
        printf("%s\n", argv[1]);
        main(argc - 1, argv + 1);
    }
    return 0;
}

четверг, 5 июля 2012 г.

KISS

Давайте взглянем на код пары простых программ. Первая поставляется с пакетом GNU coreutils во множестве дистрибутивов Linux. Программа называется true и обычно устанавливается в /bin/true :

/* Exit with a status code indicating success.
   Copyright (C) 1999-2012 Free Software Foundation, Inc.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include <config.h>
#include <stdio.h>
#include <sys/types.h>
#include <system.h>

/* Act like "true" by default; false.c overrides this.  */
#ifndef EXIT_STATUS
# define EXIT_STATUS EXIT_SUCCESS
#endif

#if EXIT_STATUS == EXIT_SUCCESS
# define PROGRAM_NAME "true"
#else
# define PROGRAM_NAME "false"
#endif

#define AUTHORS proper_name ("Jim Meyering")

void
usage (int status)
{
  printf (_("\
Usage: %s [ignored command line arguments]\n\
  or:  %s OPTION\n\
"),
          program_name, program_name);
  printf ("%s\n\n",
          _(EXIT_STATUS == EXIT_SUCCESS
            ? N_("Exit with a status code indicating success.")
            : N_("Exit with a status code indicating failure.")));
  fputs (HELP_OPTION_DESCRIPTION, stdout);
  fputs (VERSION_OPTION_DESCRIPTION, stdout);
  printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
  emit_ancillary_info ();
  exit (status);
}

int
main (int argc, char **argv)
{
  /* Recognize --help or --version only if it's the only command-line
     argument.  */
  if (argc == 2)
    {
      initialize_main (&argc, &argv);
      set_program_name (argv[0]);
      setlocale (LC_ALL, "");
      bindtextdomain (PACKAGE, LOCALEDIR);
      textdomain (PACKAGE);

      atexit (close_stdout);

      if (STREQ (argv[1], "--help"))
        usage (EXIT_STATUS);

      if (STREQ (argv[1], "--version"))
        version_etc (stdout, PROGRAM_NAME, PACKAGE_NAME, Version, AUTHORS,
                     (char *) NULL);
    }

  exit (EXIT_STATUS);
}

Вторая относится к пакету "sbase" проекта suckless.org.

/* See LICENSE file for copyright and license details. */
#include <stdlib.h>

int
main(void)
{
 return EXIT_SUCCESS;
}

Обе программы делают одну вещь. Ничего. Просто выходят, возвращая значение "успешно". Кто следует идеям UNIX? Кто следует здравому смыслу? Решайте сами.

Ссылки:

среда, 20 апреля 2011 г.

Declarations


Чтение объявлений¹ типов Си.

 
Перевод статьи Reading C type declarations, увидел у Alenacpp.
Даже для новичков программирования на Си не представляется проблемой прочесть простые описания Си наподобие

int foo[5];        // foo это массив из пяти int (целых)
char *foo;        // foo это указатель на char (символ)
double foo();   // foo это функция, возвращающая double (вещественное с двойной точностью)

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

char *(*(**foo[][8])())[]; // чтоо ?????

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

Данная технологическая записка расскажет, как это сделать.

четверг, 17 марта 2011 г.

Game

Тема нашей курсовой по Операционным системам — создание клиент-серверного приложения игры «Крестики-нолики». Первую часть, практически готовый клиент, мы должны показать в ближайшее время. У меня получилось нечто такое:

вторник, 1 февраля 2011 г.

Integrity

В качестве темы для курсовой работы я выбрал "проверку целостности информации". Программе в качестве аргументов передаются директория и файл. Она работает в двух режимах, регулируемых ключами. В первом программа вычисляет хэш-коды для всех файлов директории и записывает их в заданный файл, во втором — открывает заданный файл на чтение и сверяет записанные в нём хэш-коды с заново вычисленными для файлов директории. Программу следует в будущем доработать — она слишком жестко действует. При добавлении, удалении, либо изменении любого файла она сообщает пользователю о нарушении целостности и завершает работу. Нужно будет прикрутить к ней запись в файл имен файлов и проверку по ним, чтобы сообщалось подробно о каждом изменении. Когда писал, не мог найти нужную функцию. А преподаватель подсказал потом её название — strtoken.
В остальном же программа работает довольно мудро.

среда, 26 января 2011 г.

Switch

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

Итак, сколько дней до Нового года?

#include <stdio.h> 
#include <stdlib.h> 
int main(int argc, char *argv[]){ 
        int day, month, year; 
        int n = 0; 

        if (argc > 2) { 
                day = atoi(argv[1]); 
                month = atoi(argv[2]); 
                year = atoi(argv[3]); 
        } else { 
                printf("Type date: day month year.\n"); 
                scanf("%d%d%d", &day, &month, &year); 
        } 

        switch (month) { 
                case 1: n += 31; 
                case 2: n += (year % 400 == 0 ||(year % 4 == 0 &&
                        year % 100 != 0)) ? 29 : 28; 
                case 3: n += 31; 
                case 4:  n += 30; 
                case 5:  n += 31; 
                case 6:  n += 30; 
                case 7:  n += 31; 
                case 8:  n += 31; 
                case 9:  n += 30; 
                case 10:  n += 31; 
                case 11:  n += 30; 
                case 12:  n += 31; 
        } 
        n -= day; 
        printf("%d days before New Year's day\n", n); 
        return 0; 
}

Запуск:
jightuse@jightuse-N-A:~$ gcc -Wall ny.c -o ny.o
jightuse@jightuse-N-A:~$ ./ny.o 26 01 2011
339 days before New Year's day
jightuse@jightuse-N-A:~$