2014-08-30 3 views
3

К & R демонстрирует пример инициализации массива указателей следующим образом:Инициализация статических массивы указателей

char *month_name(int n) 
{ 
    static char *name[] = { 
    "Illegal month", 
    "January", "February", "March", 
    "April", "May", "June", 
    "July", "August", "September", 
    "October", "November", "December" 
    }; 

    return (n < 1 || n > 12) ? name[0] : name[n]; 
} 

К & Р гласит, что «это идеальное приложение для внутреннего статического массива». Но почему это так? Почему бы просто не сделать это автоматическим массивом указателей?

+4

Автоматический массив требует инициализации каждый раз, когда он вызывается. Я бы предложил: скомпилировать обе версии кода и посмотреть на сгенерированную сборку. – wildplasser

+1

Я недостаточно опыт, чтобы разобрать этот комментарий. Что это мне скажет? – George

+0

Большинство отладчиков позволят вам просмотреть код сборки, сгенерированный компилятором. Посмотрев на код сборки, вы можете много узнать о том, как работает компилятор, и вы обязательно научитесь тому, что сделает вас лучшим программистом на C. Конечно, предварительным условием является то, что вы узнаете, как читать язык ассемблера используемого вами процессора. – user3386109

ответ

3

Если массив был автоматической переменной, каждый вызов функции должен был инициализировать тринадцать указателей, а затем вернуть один из них в вызывающий код.

С массивом как статической переменной он инициализируется один раз (до того, как вызывается main(), я считаю, во всяком случае, прежде чем функция будет использоваться), а затем останется неизменной. Это, вероятно, будет более эффективным и, вероятно, значительно более эффективным (хотя это может и не иметь значения, если вы не используете функцию month_name() очень интенсивно).

Возможно, было бы лучше, если бы были какие-то const квалификаторы, скрывающиеся в коде; вызывающий объект должен обязательно не изменять строку результата:

const char *month_name(int n) 
{ 
    static const char * const name[] = 
    { 
     "Illegal month", 
     "January", "February", "March", 
     "April", "May", "June", 
     "July", "August", "September", 
     "October", "November", "December" 
    }; 

    return (n < 1 || n > 12) ? name[0] : name[n]; 
} 
Смежные вопросы