Глобальная переменная инициализирована на 1 вместо 0 в моей программе на C - PullRequest
0 голосов
/ 07 июня 2018

Если я, предположим, инициализировал глобальную переменную F и напечатал ее значение в основной функции, будет напечатано 0 (как и должно быть).

Но когда я передам аргумент int F вФункция main, объявляя глобальную переменную F точно так же, как и раньше, печатая значение F с помощью gcc print 1.

Может кто-нибудь объяснить, почему это так?

Это мой код ниже.

#include<stdio.h>

int F;

int main(int F){
    printf("F is %d\n", F);
    return 0;
}

Ответы [ 4 ]

0 голосов
/ 07 июня 2018

Вы должны заставить main() соответствовать требованиям стандарта, и вы должны напечатать глобальный F, а также аргумент F:

#include <stdio.h>

int F;

int main(int F, char **G)
{
    printf("F is %d\n", F);
    {
    extern int F;
    printf("%s: F is %d\n", G[0], F);
    }
    return 0;
}

При компиляции (из исходного файлаquirky43.c для программирования quirky43) и запуска, я получаю:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror quirky43.c -o quirky43 
$ ./quirky43
F is 1
quirky43: F is 0
$ ./quirky43 this is why you get command line arguments
F is 9
quirky43: F is 0
$

Первый printf() выводит первый аргумент в main() (условно называемый argc, но в этом нет ничего плохогос вызовом F за исключением того, что это неожиданно).Второй выводит глобальную переменную F (а также имя программы, условно argv[0], но опять-таки нет ничего плохого в использовании G, за исключением того, что это неожиданно).extern int F; внутри набора фигурных скобок означает, что F в этом блоке операторов относится к переменной F, определенной за пределами охватывающей области, что означает переменную области действия файла F - что, как можно заметить, является правильныминициализируется до 0.1 появляется потому, что вы вызвали программу без аргументов, а количество аргументов включает в себя имя программы.По этой же причине напечатанное значение было 9, когда в командную строку было добавлено 8 аргументов.

Обратите внимание, что другой хороший вариант компиляции - -Wshadow:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wshadow quirky43.c -o quirky43
quirky43.c: In function ‘main’:
quirky43.c:6:14: error: declaration of ‘F’ shadows a global declaration [-Werror=shadow]
 int main(int F, char **G)
          ~~~~^
quirky43.c:4:5: note: shadowed declaration is here
 int F;
     ^
cc1: all warnings being treated as errors
$

(Компиляцияс GCC 8.1.0 на Mac под управлением macOS High Sierra 10.13.5.)

0 голосов
/ 07 июня 2018

Но когда я передаю аргумент int F в главной функции? , что F - это ничто иное, как число аргументов, т.е. argc.

В конкретном случае вы упомянули глобальный F и F, которые вы объявили в аргументе main(), отличаются.

int main(int F){ printf("F is %d\n", F); return 0; }

Здесь printf() печатает 1, потому что при запуске вашего исполняемого файла, например ./a.out нетввод командной строки 1, он похож на argc.

Ваш компилятор мог бы предупредить вас об аргументе, предоставленном main(), скомпилировать с флагом -Wall и прочитать предупреждение.Также проверьте прототип main().Из стандарта C

ISO / IEC 9899: 1999

§5.1.2.2.1 Запуск программы

¶1 Функция, вызываемая при запуске программы, называется main,Реализация не объявляет прототип для этой функции.Он должен быть определен с типом возвращаемого значения intand без параметров:

int main (void) {/ * ... * /}

или с двумя параметрами (именуемыми здесь как argcи argv, хотя могут использоваться любые имена, так как они являются локальными для функции, в которой они объявлены):

int main (int argc, char argv []) {/ ... * /}

или эквивалентный; 9) или другим способом, определяемым реализацией.

0 голосов
/ 07 июня 2018

В опубликованном вами коде main имеет аргумент с именем F.Внутри main любые ссылки на F ссылаются на эту переменную, а не на глобальную.

Используя ненужные имена переменных, вы излишне усложняете жизнь.В большинстве случаев аргументы main имеют имена argc и argv - количество аргументов и значения аргументов.

int main(int argc, char** argv) { ... }

Хорошо использовать имена переменных, которые имеют значение.Использование int F; в качестве глобальной переменной также не имеет смысла.Назовите это так, чтобы оно имело смысл.Тогда вы столкнетесь с такими же проблемами, как и вы.

0 голосов
/ 07 июня 2018

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

 #include <stdio.h>

    static int F;

    int main(){
        printf("F is %d", F);
        return 0;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...