Де використовується ключове слово C auto?


104

У дні коледжу я читав про autoключове слово і з часом фактично забув, що це таке. Він визначається як:

визначає локальну змінну як таку, що має місцевий час життя

Я ніколи не виявив, що він використовується де-небудь, чи він справді використовується, і якщо так, то де він використовується і в яких випадках?

Відповіді:


90

autoє модифікатором, як static. Він визначає клас зберігання змінної. Однак, оскільки локальні змінні за замовчуванням є auto, вам зазвичай не потрібно вказувати його вручну.

На цій сторінці перераховані різні класи зберігання у C.


13
Просто дивився на це знову після того, як хтось підголосив мою відповідь. Ви кажете, що "зазвичай не потрібно вказувати це вручну". Мені просто потрібно запитати: чи є насправді обставина, за якої auto можна вказати, але не відбудеться за замовчуванням?
Джеррі Труну

2
@JerryCoffin Не в C. У C ++ 11 він перероблений, і ви можете використовувати його для ефективного отримання локального висновку змінних типів.
Мехрдад Афшарі

2
Одне можливе використання - це попереднє оголошення вкладених функцій у GNU C - хоча це викрадення вихідного визначення auto. tigcc.ticalc.org/doc/keywords.html#auto
josiah

2
Пов'язана сторінка застаріла. Так як C11, там також _Thread_localдеталі: en.cppreference.com/w/c/language/storage_duration і stackoverflow.com/a/14289720/6557621
MCCCS

132

Якщо ви читали список IAQ (нечасто задаються питання), ви знаєте, що авто корисно в першу чергу для визначення або декларування транспортного засобу:

auto my_car;

Транспортний засіб, який постійно паркується на вулиці:

extern auto my_car;

Для тих, кому не вистачає почуття гумору і хочеться "лише фактів, пані": коротка відповідь полягає в тому, що ніколи не існує жодної причини використовувати auto. Єдиний раз, коли вам дозволено використовувати auto, це змінна, яка вже має autoклас зберігання, тому ви просто вказуєте те, що все одно відбудеться. Спроба використовувати autoбудь-яку змінну, у якої вже немає autoкласу зберігання, компілятор відхилить ваш код. Я вважаю, що якщо ви хочете отримати технічну техніку, ваша реалізація не повинна бути компілятором (але це так) і теоретично вона може продовжувати компілювати код після видачі діагностики (але це не буде).

Невеликий додаток від kaz :

Є також:

static auto my_car;

яка вимагає діагностики відповідно до ISO C. Це правильно, оскільки вона заявляє, що машина розбита. Діагностика безкоштовна, але вимкнення світла на приладовій панелі обійдеться вам у вісімдесят доларів. (Двадцять і менше, якщо ви придбаєте власний USB-ключ для бортової діагностики з eBay).

Вищезазначене extern auto my_carтакож вимагає діагностики, і з цієї причини його ніколи не проводять через компілятор, крім службовців міста, які мають доручення виконувати паркування.

Якщо ви бачите багато extern static auto ...в будь-якій кодовій базі, ви перебуваєте в поганому сусідстві; шукайте кращу роботу негайно, перш ніж все місце звернеться до Руста.


@self .: ISO, схоже, не знає "ISO 2011". Як ви вважаєте, що це може стандартизувати?
Джеррі Труну

6
Добре, що у мене в роті не було кави, кола, матового чи якоїсь іншої рідини темного кольору. Ти повинен був би мені комп’ютерним екраном, @JerryCoffin. НАЙКРАЩИЙ ВІДПОВІДЬ!
Девід Хаммен

2
@Dan: Чесно вам знадобилося "досить багато часу", щоб прочитати 5 рядків тексту і отримати частину, де написано: "коротка відповідь полягає в тому, що ніколи не виникає причин використовувати авто"? Серйозно? З огляду на коментар, що безпосередньо передує вашому, здається, що принаймні кілька людей вважають це позитивним внеском.
Джеррі Труну

@JerryCoffin Я вже пояснив це, прочитайте мій коментар ще раз. Задні огляди - 20/20.
Ден Бешард

2
Нещодавно я пройшов серйозну пожежу (закрив дві смуги), що говорить про необхідністьchar auto my_car;
старий

46

autoКлючове слово марно в мові Сі. Це тому, що до мови C існувала мова B, в якій це ключове слово було необхідне для декларування локальних змінних. (B був розроблений в NB, який став C).

Ось довідкове керівництво для B .

Як бачите, посібник рясніє прикладами, в яких autoвикористовується. Це так тому, що немає intключового слова. Для того, щоб сказати, "це декларація змінної", потрібне якесь ключове слово, і це ключове слово також вказує, чи є воно локальним чи зовнішнім ( autoпроти extrn). Якщо ви не використовуєте те чи інше, у вас є помилка синтаксису. Тобто x, y;не є декларацією сама по собі, але auto x, y;є.

Оскільки бази кодів, написані на B, потрібно було переносити на NB та на C у міру розвитку мови, новіші версії мови містили певний багаж для покращення зворотної сумісності, що перекладало на меншу кількість роботи. У випадку з autoпрограмістами не доводилося вишукувати кожне виникнення autoта видаляти його.

З посібника очевидно, що тепер устарілий "неявний int" суглоб у C (вміння писати main() { ... }без будь-якого intспереду) також походить від B. Це ще одна функція сумісності, що підтримується назад, для підтримки коду B. Функції не мають тип повернення, вказаний у B, оскільки не існує типів. Все це слово, як у багатьох мовах асемблерів.

Зауважте, як функцію можна просто оголосити, extrn putcharі тоді єдине, що робить її функцією, яка використовується ідентифікатором : вона використовується в виразі виклику функції, як putchar(x), і саме це підказує компілятору трактувати це безтипове слово як вказівник функції.


24

В C auto- ключове слово, яке вказує, що змінна є локальною для блоку. Оскільки це за замовчуванням для блокових змінних, це непотрібне і дуже рідко використовується (я не думаю, що я коли-небудь бачив його використання поза прикладами в текстах, які обговорюють ключове слово). Мені буде цікаво, якби хтось міг вказати на випадок, коли для використання autoправильного розбору чи поведінки потрібне використання .

Однак у стандарті C ++ 11 autoключове слово було викрадено для виводу типу вибору, де тип змінної можна взяти з типу її ініціалізатора:

auto someVariable = 1.5;   // someVariable will have type double

Висновки типу додаються в основному для підтримки оголошень змінних у шаблонах або повертаються з функцій шаблону, де типи, засновані на параметрі шаблону (або виведені компілятором, коли шаблон призначений), часто можуть бути досить болісними оголошувати вручну.


1
"Змінна локальна для блоку" - це зовсім не так. Усі змінні, оголошені в блоці, локальні для цього блоку (стосовно області). Вони можуть бути пов'язані з іншими змінними в програмі, але декларація видно лише в цьому блоці. autoйдеться про клас зберігання, який не має нічого спільного з видимістю.
fuz

12

За допомогою старого компілятора Aztec C можна було перетворити всі автоматичні змінні на статичні змінні (для збільшення швидкості адреси) за допомогою перемикача командного рядка.

Але змінні, явно оголошені з, autoбули залишені такими як є в такому випадку. (Обов'язковий для рекурсивних функцій, які в іншому випадку не працюватимуть належним чином!)


7

autoКлючове слово аналогічно включення в Python з коми, були потрібні від попереднього мови ( B) , але розробники зрозуміли , що це було зайвим , так як більшість речей були auto.

Я підозрюю, що це допомогло перейти від B до C. Коротше кажучи, одне використання - це сумісність мови B.

Наприклад, в B і 80-х роках:

/* The following function will print a non-negative number, n, to
   the base b, where 2<=b<=10.  This routine uses the fact that
   in the ASCII character set, the digits 0 to 9 have sequential
   code values.  */

printn(n, b) {
        extrn putchar;
        auto a;

        if (a = n / b)        /* assignment, not test for equality */
                printn(a, b); /* recursive */
        putchar(n % b + '0');
}

1

Автоматичне ключове слово - приклад класу зберігання (певного роду прийоми, що визначають термін служби змінної та місця зберігання). Він має поведінку, згідно з якою змінна, створена довідкою цього ключового слова, має тривалість життя (термін експлуатації), що проживають лише у фігурних дужках.

{
    auto int x=8;        
    printf("%d",x);  // here x is 8

    { 
        auto int x=3;
        printf("%d",x);  // here x is 3
    }              

    printf("%d",x);  // here x is 8
}          

0

autoможе використовуватися лише для змінних, що охоплюють блок. extern auto intє сміттям, тому що компілятор не може визначити, чи використовує він зовнішнє визначення, чи замінює зовнішній вигляд із автоматичним визначенням (також auto та extern - це абсолютно різні тривалості зберігання, наприклад static auto int, очевидно також сміття). Він завжди міг вибрати його трактувати в одну сторону, але замість цього вирішив трактувати це як помилку.

Існує одна функція, autoяка забезпечує, і це дає можливість "все є цілим" всередині функції. На відміну від зовнішньої функції, де a=3інтерпретується як визначення, int a =3оскільки присвоєння не існує в області файлу, a=3є помилкою всередині функції, тому що, очевидно, компілятор завжди інтерпретує її як присвоєння зовнішній змінній, а не як визначення (навіть якщо існує нети extern int aфорвардних декларацій в функції або в області файлу), але специфікатор , як static, const, volatileабо autoбуде означати , що це визначення і компілятор приймає його в якості визначення, за винятком того, autoне має побічні ефекти інших специфікаторів. auto a=3тому неявно auto int a = 3. Справді,signed a = 3має однаковий ефект і unsigned a = 3завжди є неподписаним int.

Також зауважте, що " autoне впливає на те, чи буде об'єкт виділятися в регістр (якщо якийсь конкретний компілятор не звертає на це уваги, але це здається малоймовірним)"


-1

Я впевнений, що ви знайомі зі специфікаторами класу зберігання в C, які є "зовнішній", "статичний", "реєстр" та "автоматичний". Визначення "auto" в значній мірі дається в інших відповідях, але ось можливе використання ключового слова "auto", в якому я не впевнений, але я думаю, що це залежить від компілятора. Розумієте, щодо специфікаторів класу зберігання є правило. Неможливо використовувати декілька специфікаторів класу зберігання для змінної. Ось чому статичні глобальні змінні не можуть бути зовнішніми. Тому вони відомі лише їхньому файлу. Перейшовши до налаштування компілятора, ви можете включити прапор оптимізації для швидкості. один із способів оптимізації компілятора - він шукає змінні без специфікаторів класу зберігання, а потім робить оцінку на основі наявності кеш-пам'яті та деяких інших факторів, щоб побачити, чи слід обробляти цю змінну, використовуючи специфікатор реєстру чи ні. Тепер, що робити, якщо ми хочемо оптимізувати наш код для швидкості, знаючи, що певна змінна в нашій програмі не дуже важлива, і ми не хочемо, щоб компілятор навіть розглядав її як реєстр. Я, якщо, поставивши auto, компілятор не зможе додати специфікатор регістру до змінної, оскільки набрав "register auto int a;" АБО "автореєстр int a;" підвищує помилку використання декількох специфікаторів класу зберігання. Підсумовуючи це, я думав, що авто може заборонити компілятору обробляти змінну як регістр шляхом оптимізації. що робити, якщо ми хочемо оптимізувати наш код для швидкості, знаючи, що певна змінна в нашій програмі не дуже важлива, і ми не хочемо, щоб компілятор навіть розглядав її як реєстр. Я, якщо, поставивши auto, компілятор не зможе додати специфікатор регістру до змінної, оскільки набрав "register auto int a;" АБО "автореєстр int a;" підвищує помилку використання декількох специфікаторів класу зберігання. Підсумовуючи це, я думав, що авто може заборонити компілятору обробляти змінну як регістр шляхом оптимізації. що робити, якщо ми хочемо оптимізувати наш код для швидкості, знаючи, що певна змінна в нашій програмі не дуже важлива, і ми не хочемо, щоб компілятор навіть розглядав її як реєстр. Я, якщо, поставивши auto, компілятор не зможе додати специфікатор регістру до змінної, оскільки набрав "register auto int a;" АБО "автореєстр int a;" підвищує помилку використання декількох специфікаторів класу зберігання. Підсумовуючи це, я думав, що авто може заборонити компілятору обробляти змінну як регістр шляхом оптимізації. підвищує помилку використання декількох специфікаторів класу зберігання. Підсумовуючи це, я думав, що авто може заборонити компілятору обробляти змінну як регістр шляхом оптимізації. підвищує помилку використання декількох специфікаторів класу зберігання. Підсумовуючи це, я думав, що авто може заборонити компілятору обробляти змінну як регістр шляхом оптимізації.

Ця теорія не працює для компілятора GCC, проте я не пробував інших компіляторів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.