C: Поведение ключевого слова 'константы'

Все должно быть сделано максимально простым, но не более простое. - A. Эйнштейнов

Одной из самых недооцененных вещей о TDD является первое слово в нем. Тест. Вот почему BDD пришел. Поскольку люди действительно не поняли, что первый D был важным, а именно, Управляемым. Все мы склонны думать немного к очень о Тестировании, и немного к мало об управлении дизайна. И я предполагаю, что это - неопределенный ответ на Ваш вопрос, но необходимо, вероятно, рассмотреть, как управлять кодом, вместо того, что Вы на самом деле тестируете; это - что-то, с чем инструмент Покрытия может помочь Вам. Дизайн является вполне большей и более проблематичной проблемой.

7
задан Ande TURNER 13 September 2009 в 10:21
поделиться

6 ответов

Компилятор Java имеет небольшой объем логики потока, чтобы вы могли инициализировать final переменные после их объявления. Это законная Java:

final int something;

if ( today == Friday )
    something = 7;
else
    something = 42;

Java обнаружит, оставит ли какое-либо ветвление окончательное значение неопределенным. Он не будет анализировать условия, поэтому это незаконная Java, хотя она логически аналогична:

final int something;

if ( today == Friday )
    something = 7;

if ( today != Friday )
    something = 42;

В ANSI C89, const переменные (кроме extern ) должны быть инициализированы в заявлении, в котором они объявлены.

const int something = ( today == Friday ) ? 7 : 42;

Модификатор extern в объявлении сообщает компилятору, что переменная инициализируется в другом модуле компиляции (или где-либо еще в этом модуле компиляции).

В ANSI C99, вы можете смешивать объявления и код, поэтому вы можете объявить и инициализировать переменную const после блока утверждений и кода. Переносимость ANSI C 1999 года остается проблемой.

Обход C89 состоит в том, чтобы отметить, что правила для объявлений, предшествующих коду, работают в области видимости блока, а не функции, поэтому вы можете сделать это:

#include<stdio.h>

int main ( void )
{
    printf ( "wibble\n" );

    {
        const int x = 10;

        printf ( "x = %d\n", x );
    }

    return 0;
}
9
ответ дан 6 December 2019 в 09:20
поделиться

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

Этот код вызывает ошибку : присвоение переменной только для чтения 'foo' (gcc4):

const int foo;
foo = 4;

То же самое и для константных указателей (обратите внимание: const int * не константный указатель, а указатель на константу):

int * const foo;
foo = 4;
3
ответ дан 6 December 2019 в 09:20
поделиться

Имейте в виду что даже в C89 вы часто можете переместить определение ближе к точке первого использования, вводя пустой блок только для дополнительной области. До:

int a, b, c;

a = 12;
// do some stuff with a

b = 17;
// do some stuff with a and b

c = 23;
// do some stuff with a, b, and c

После:

int a = 12;
// do some stuff with a
{
    int b = 17
    // do some stuff with a and b
    {
        int c = 23;
        // do some stuff with a, b and c
    }
}

С C99, конечно, вы можете определять переменные, отличные от начала блока:

int a = 12;
// do some stuff with a

int b = 17
// do some stuff with a and b

int c = 23;
// do some stuff with a, b and c
3
ответ дан 6 December 2019 в 09:20
поделиться

Вы не можете инициализировать константу после объявления в теле функции, но вы можете просто открыть один блок после ваших утверждений:

void func()
{
    int y;
    //do assertions
    assert(something);
    {
        int const x = 5;
        // function body
     }
}
2
ответ дан 6 December 2019 в 09:20
поделиться

Если вы говорите о разделении определения

const int x = 2;

на две части:

const int x;

x=2;

Боюсь, что это невозможно в C.

На вашем месте я бы попытался убедитесь, что я понимаю цель описываемых вами правил кодирования. Я сомневаюсь, что разумные правила кодирования предотвратят инициализацию переменных (даже неконстантных переменных).

В ответ на различные комментарии:

const int * p;

НЕ является объявлением константной переменной. Это объявление переменной указателя, не являющейся константой, на const int.

Вы можете объявить

extern const int x;

, но вы все равно не можете инициализировать x после выполнения кода, проверок утверждения, ...

1
ответ дан 6 December 2019 в 09:20
поделиться

Если не считать области блока и других методов объявления C99, то ответ отрицательный; вы не можете отложить инициализацию константной переменной. В любом случае, const не очень полезна для локальных переменных. В основном я использую ключевое слово const в C:

  • Указатели в аргументах функции (или указатели на локальные переменные на основе аргументов), когда функция выполняет контракт, чтобы не изменять указанные данные. Ключевое слово const помогает гарантировать, что реализация функции соблюдает требование не изменять (для избавления от const требуются особые усилия) и позволяет этому требованию распространяться через несколько вызовов функций.
  • Для объявления таблиц констант времени компиляции (таблицы поиска, предопределенные постоянные объекты и т. Д.), Которые я хочу хранить в разделе двоичного файла, доступном только для чтения, чтобы они не использовали дополнительные физические ресурсы во время выполнения.

Иногда я объявляю локальные переменные const, если я думаю, что это поможет читателю понять функцию, но это довольно редко.

2
ответ дан 6 December 2019 в 09:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: