Программы
Ключевое слово Void в Си

Ключевое слово Void в Си

Значений у Void в Си несколько. Давайте рассмотрим их

– А есть ли в Си generic-и?
– Конечно! void pointer!

– диалог с одной из пар.

void - необычный специфиактор типа. Иногда он имеет смысл "что-то", иногда - "ничто".

Звучит немного запутанно, но что взять с бек-порта из C++...

Давайте разберёмся, когда void используется и чем он является!

Тип возвращаемого функцией значения

Мы помним, что при описании функции, нам нужно указать тип возвращаемого значения.

Но если мы не хотим ничего возвращать? Тогда нам нужен void!

#include <stdio.h>
#include <string.h>

void beautiful_print(char *text) {
  for (int i = 0; i < strlen(text) + 4; ++i) {
    printf("*");
  }

  printf("\n* %s *\n", text);

  for (int i = 0; i < strlen(text) + 4; ++i) {
    printf("*");
  }

  printf("\n");
}

int main(void) {
  beautiful_print("Hello world");
  return 0;
}

Декларация функции – указание на то, что функция не имеет параметров

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

#include <stdio.h>

int beautiful_read(void) {
  int digit;
  printf("Enter a number: ");
  scanf("%d\n", &digit);
  return digit;
}

int main(void) {
  int num = beautiful_read("some param");
  return 0;
}

Получаем:

→ clang 04-void-def.c
04-void-def.c:11:34: error: too many arguments to function call, expected 0, have 1
  int num = beautiful_read("some param");
	    ~~~~~~~~~~~~~~ ^~~~~~~~~~~~
04-void-def.c:3:6: note: 'beautiful_read' declared here
int beautiful_read(void) {
^
1 error generated.

Уоу! Я не буду это собирать – ты допустил ошибку!

В случае, если не указываем void в декларации функции - только warning:

→ clang 04-void-def.c
04-void-def.c:11:46: warning: too many arguments in call to 'beautiful_read'
    int num = beautiful_read("some param");
	      ~~~~~~~~~~~~~~             ^
1 warning generated.

– тут что-то не особо понятное... Но технически всё нормально – собираю.

Тип указателя "нечто".

А вот это просто нечто! Ой, то есть "замечательно"!

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

Использовать void полезно, когда могут быть использованы параметры разных типов:

#include <stdio.h>
#include <string.h>

/**
 * Функция выводит hex представление данных.
 * Согласитесь, такая функция не нуждается в типе данных.
 * Опять же, она полезна нам для просмотра того треша, который будет в переменных.
 */
void print_hex(void *a, int size) {
  // Преобразуем void указатель в указатель на байт (он же – указатель на символ).
  // Всё потому что арифметика указателей для void не работает – это же "нечто".
  char *byte = (char *)a;

  for (int i = 0; i < size; ++i) {
    printf("%02x ", *(byte + i));
  }

  printf("\n");
}

int main(void) {
  int a = 1025;
  print_hex(&a, sizeof(a));
  char *b = "abcd";
  print_hex(b, strlen(b));
  return 0;
}
Также может быть вам интересно:

Функции и структура программы

Общая структура функций в языке Си

Читать »

Колбеки и функции высших порядков

Немного функционального программирования в Си

Читать »
Фото Python: Встроенные типы данных (list, set, dict, etc)

Python: Встроенные типы данных (list, set, dict, etc)

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

Фото Python: типы данных, переменные, логическое ветвление и циклы

Python: типы данных, переменные, логическое ветвление и циклы

Первая часть заметок о Python. О базовых типах, переменных, ветвлении и циклах.

Фото Как сделать свою middleware в Django (с примерами)

Как сделать свою middleware в Django (с примерами)

Middleware или "промежуточное программное обеспечение" - элегантный способ установить общие правила обработки запросов и ответов приложения. Давайте напишем парочку middleware, чтобы понять, как они работают.

Фото Как настроить отправку почты из Django

Как настроить отправку почты из Django

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

Фото Добавляем постраничную пагинацию на Django сайт

Добавляем постраничную пагинацию на Django сайт

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

Фото Новый оператор match-case в Python

Новый оператор match-case в Python

В новой версии Python (3.10) появится новый оператор. Новый оператор сопоставления по шаблону (match-case).

Фото Нет слов, одни... однострочники

Нет слов, одни... однострочники

На днях вышел пост со списком полезных однострочников для JavaScript программистов. Памятуя Perl-овую молодость, заглянул туда.

Фото Добавляем переменные в контекст Django шаблонов (свой контекст-процессор)

Добавляем переменные в контекст Django шаблонов (свой контекст-процессор)

В Django вы можете передавать данные в шаблоны посредством контекстов. Контекст передаётся из контроллера (view в терминах Django), однако, если одни и те же данные нужны в разных местах, лучше сделать свой контекст-процессор.