C эквивалент типа Python None

Есть ли тип данных C, эквивалентный типу Python None?

Я попытался найти его в Интернете, но ничего не нашел.

Спасибо,


person jschnieder    schedule 25.06.2020    source источник
comment
Связано: stackoverflow.com/questions/19473185/what-is -a-none-value   -  person Jerry Jeremiah    schedule 25.06.2020
comment
C статически типизирован, поэтому тип «None» действительно не имеет никакого смысла. Есть тип «пустота», который на самом деле совсем не одно и то же.   -  person Chris Dodd    schedule 25.06.2020
comment
Для указателей всегда NULL. Для float и double есть NaN. Но для int, short и long нет значения, которое вы можете присвоить, что означает, что целочисленная переменная не имеет значения - каждая последовательность битов является допустимым числом. Так что это работает не для всех типов.   -  person Jerry Jeremiah    schedule 25.06.2020
comment
@JerryJeremiah FWIW, существуют архитектуры, в которых целочисленные типы могут иметь недопустимые значения, называемые представлениями ловушек. За исключением битовой комбинации на основе unsigned char и _2 _ / _ 3_ или аналогичных, проверка или установка таких значений, вероятно, будет несколько проблематичной.   -  person Andrew Henle    schedule 25.06.2020


Ответы (1)


Python имеет динамическую типизацию, поэтому вы можете привязать имя переменной к любому типу, например строковому, числовому или NoneType. Поскольку C статически типизирован, переменные привязаны к определенному типу, но ничто не мешает вам создать тип, который может быть любым типом.

Например, объединение с полем тега для указания типа, как в следующей полной программе. Во-первых, типы тегов и объединений, которые позволяют сохранять и выбирать любой из типов:

enum uberType { ETYP_NONE, ETYP_INT, ETYP_DOUBLE, ETYP_CHARPTR };
typedef struct {
    enum uberType type;
    union { int valInt; double valDouble; char *valCharPtr; };
} tUberType;

Затем некоторые вспомогательные функции для установки uber-типа на определенное типизированное значение:

void makeNone(tUberType *ut) {
    ut->type = ETYP_NONE;
}

void makeInt(tUberType *ut, int val) {
    ut->type = ETYP_INT;
    ut->valInt = val;
}

void makeDouble(tUberType *ut, double val) {
    ut->type = ETYP_DOUBLE;
    ut->valDouble = val;
    }

void makeCharPtr(tUberType *ut, char *val) {
    ut->type = ETYP_CHARPTR;
    ut->valCharPtr = val;
}

И, наконец, тестовый набор, включающий функцию вывода:

#include <stdio.h>

void evalUber(tUberType *ut, char *post) {
    switch (ut->type) {
    case ETYP_NONE:
        printf("none:%s", post);
        break;
    case ETYP_INT:
        printf("int:%d%s", ut->valInt, post);
        break;
    case ETYP_DOUBLE:
        printf("double:%f%s", ut->valDouble, post);
        break;
    case ETYP_CHARPTR:
        printf("charptr:%s%s", ut->valCharPtr, post);
        break;
    default:
        printf("?%s", post);
        break;
    }
}

int main(void) {
    tUberType x;
    makeNone(&x); evalUber(&x, "\n");
    makeInt(&x, 42); evalUber(&x, "\n");
    makeDouble(&x, 3.14159); evalUber(&x, "\n");

    return 0;
}

Результат тестового жгута main, как и ожидалось:

none:
int:42
double:3.141590
person paxdiablo    schedule 25.06.2020