수색…


C에서 변수 초기화

명시 적 초기화가 없으면 외부 변수와 static 변수가 0으로 초기화되도록 보장됩니다. 자동 변수 ( register 변수 포함)에는 불확실한 1 (즉, 가비지) 초기 값이 있습니다.

스칼라 변수는 등호와 표현식으로 이름을 따라 정의 할 때 초기화 될 수 있습니다.

int x = 1;
char squota = '\'';
long day = 1000L * 60L * 60L * 24L; /* milliseconds/day */

외부 및 static 변수의 경우, 이니셜 라이저는 상수 표현식 2 여야합니다. 초기화는 프로그램이 실행되기 전에 개념적으로 한 번 수행됩니다.

자동 변수와 register 변수의 경우, 이니셜 라이저는 상수로만 제한되지 않습니다. 이전에 정의 된 값을 비롯하여 함수 호출을 포함하는 표현식이 될 수 있습니다.

예를 들어 아래 코드 스 니펫을 참조하십시오.

int binsearch(int x, int v[], int n)
{
   int low = 0;
   int high = n - 1;
   int mid;
   ...
}

대신에

   int low, high, mid;

   low = 0;
   high = n - 1;

실제로, 자동 변수의 초기화는 할당 문에 대한 축약 일뿐입니다. 선호하는 양식은 주로 취향의 문제입니다. 선언의 초기화 프로그램은 사용하기가 더 어렵고 멀리 떨어져 있기 때문에 일반적으로 명시 적 할당을 사용합니다. 반면 변수는 가능한 한 사용할 때만 선언해야합니다.

배열 초기화 중 :

배열은 괄호로 묶이고 쉼표로 구분 된 이니셜 라이저 목록을 사용하여 선언 한 다음 초기화하여 초기화 할 수 있습니다.

예를 들어, 배열 일을 매월 일 수로 초기화하려면 다음을 수행하십시오.

int days_of_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }

(1 월은이 구조에서 월이 0으로 인코딩됨에 유의하십시오.)

배열의 크기가 생략되면 컴파일러는 이니셜 라이저를 계산하여 길이를 계산합니다.이 경우 이니셜 라이저는 12 개입니다.

지정된 크기보다 배열에 대한 초기화 프로그램 수가 더 적 으면 다른 모든 유형의 변수에 대해 나머지는 0이됩니다.

너무 많은 초기화 프로그램이있는 것은 오류입니다. 이니셜 라이저의 반복을 지정하는 표준 방법은 없지만 GCC는이를 확장 할 수 있습니다.

C99

C89 / C90 또는 이전 버전의 C에서는 이전 값을 모두 제공하지 않고 배열의 중간에 요소를 초기화 할 수있는 방법이 없었습니다.

C99

C99 이상에서는 지정된 초기화 프로그램을 사용하여 배열의 임의 요소를 초기화하고 초기화되지 않은 값은 0으로 남겨 둡니다.

문자 배열 초기화 중 :

문자 배열은 초기화의 특별한 경우입니다. 중괄호와 쉼표 표기법 대신 문자열을 사용할 수 있습니다.

char chr_array[] = "hello";

더 길지만 동등한 것에 대한 속기입니다 :

char chr_array[] = { 'h', 'e', 'l', 'l', 'o', '\0' };

이 경우, 배열 크기는 6입니다 (5 문자 + 종료 '\0' ).

1 C에서 선언되고 초기화되지 않은 변수는 어떻게됩니까? 가치가 있습니까?

2 상수 표현식 은 컴파일 타임에 평가할 수있는 것으로 정의됩니다. 그래서, int global_var = f(); 유효하지 않다. 또 다른 일반적인 오해는 const 한정 변수를 상수 표현 으로 생각하는 것입니다. C에서 const 는 "컴파일 타임 상수"가 아니라 "읽기 전용"을 의미합니다. 그래서 전역 정의는 const int SIZE = 10; int global_arr[SIZE]; const int SIZE = 10; int global_var = SIZE; C에서 합법적이지 않다.

구조체 및 구조체 배열 초기화

구조체 및 구조체 배열은 중괄호로 묶인 일련의 값으로 초기화 할 수 있으며 구조체의 멤버 당 하나의 값입니다.

struct Date
{
    int year;
    int month;
    int day;
};

struct Date us_independence_day = { 1776, 7, 4 };

struct Date uk_battles[] =
{
    { 1066, 10, 14 },    // Battle of Hastings
    { 1815,  6, 18 },    // Battle of Waterloo
    { 1805, 10, 21 },    // Battle of Trafalgar
};

배열 초기화는 내부 중괄호없이 쓰여질 수 있으며, 과거 (1990 년 이전, 말하기)에는 종종 그것들없이 쓰여졌을 것이다 :

struct Date uk_battles[] =
{
    1066, 10, 14,    // Battle of Hastings
    1815,  6, 18,    // Battle of Waterloo
    1805, 10, 21,    // Battle of Trafalgar
};

이 방법이 효과적이긴하지만 좋은 현대적 스타일은 아닙니다. 새 코드에서이 표기법을 사용하지 말고 보통 컴파일러가 내리는 경고를 수정해야합니다.

지정된 이니셜 라이저를 참조하십시오.

지정된 이니셜 라이저 사용

C99

C99는 지정된 초기화 프로그램 의 개념을 도입했습니다 . 이를 통해 배열, 구조체 또는 공용체의 어떤 요소를 다음 값으로 초기화할지 지정할 수 있습니다.

배열 요소에 대한 지정된 초기화 프로그램

일반 int 와 같은 간단한 유형의 경우 :

int array[] = { [4] = 29, [5] = 31, [17] = 101, [18] = 103, [19] = 107, [20] = 109 };

대괄호 안에있는 용어는 상수 정수 표현식이 될 수 있으며 배열의 어느 요소가 = 기호 다음에 나오는 용어의 값으로 초기화 될지 지정합니다. 지정되지 않은 요소는 기본적으로 초기화되므로 0이 정의됩니다. 이 예제는 지정된 초기화 프로그램을 순서대로 보여줍니다. 그들은 순서대로있을 필요는 없습니다. 이 예는 갭을 보여줍니다. 그것들은 합법적이다. 이 예제에서는 동일한 요소에 대해 두 가지 초기화를 보여주지 않습니다. (ISO / IEC 9899 : 2011, §6.7.9 초기화, ¶19 ) 초기화는 초기화 목록 순서대로 이루어져야하며, 각 하위 객체는 동일한 하위 객체에 대해 이전에 나열된 이니셜 라이저를 덮어 씁니다.

이 예제에서는 배열의 크기가 명시 적으로 정의되어 있지 않으므로 지정된 초기화 프로그램에 지정된 최대 인덱스가 배열의 크기를 지정합니다.이 예제에서는 21 개의 요소가됩니다. 크기가 정의 된 경우 배열의 끝을 넘어 항목을 초기화하면 오류가 발생합니다.

구조물 용으로 지정된 초기화 장치

를 사용하여 초기화 할 구조의 요소를 지정할 수 있습니다 . element 표기법 :

struct Date
{
    int year;
    int month;
    int day;
};

struct Date us_independence_day = { .day = 4, .month = 7, .year = 1776 };

요소가 나열되지 않으면 기본적으로 초기화됩니다 (0으로 설정).

노조에 대한 지정된 초기화 프로그램

공용체의 어느 요소를 지정된 초기화 프로그램으로 초기화할지 지정할 수 있습니다.

C89

C 표준 이전에는 union 을 초기화 할 수있는 방법이 없었습니다. C89 / C90 표준을 사용하면 union 의 첫 번째 구성원을 초기화 할 수 있으므로 어떤 구성원이 먼저 선택되는지 선택해야합니다.

struct discriminated_union
{
    enum { DU_INT, DU_DOUBLE } discriminant;
    union
    {
        int     du_int;
        double  du_double;
    } du;
};

struct discriminated_union du1 = { .discriminant = DU_INT, .du = { .du_int = 1 } };
struct discriminated_union du2 = { .discriminant = DU_DOUBLE, .du = { .du_double = 3.14159 } };
C11

C11에서는 구조체 내에서 익명의 공용 멤버를 사용할 수 있으므로 앞의 예제에서 du 이름은 필요하지 않습니다.

struct discriminated_union
{
    enum { DU_INT, DU_DOUBLE } discriminant;
    union
    {
        int     du_int;
        double  du_double;
    };
};

struct discriminated_union du1 = { .discriminant = DU_INT, .du_int = 1 };
struct discriminated_union du2 = { .discriminant = DU_DOUBLE, .du_double = 3.14159 };

구조체 배열 등을위한 지정된 이니셜 라이저

배열 등의 요소를 포함하는 구조체의 배열에 대해 이러한 구조체를 결합 할 수 있습니다. 중괄호 세트를 사용하면 표기법이 명확합니다.

typedef struct Date Date;  // See earlier in this example

struct date_range
{
    Date    dr_from;
    Date    dr_to;
    char    dr_what[80];
};

struct date_range ranges[] =
{
    [3] = { .dr_from = { .year = 1066, .month = 10, .day = 14 },
            .dr_to   = { .year = 1066, .month = 12, .day = 25 },
            .dr_what = "Battle of Hastings to Coronation of William the Conqueror",
          },
    [2] = { .dr_from = { .month = 7, .day =  4, .year = 1776 },
            .dr_to   = { .month = 5, .day = 14, .year = 1787 },
            .dr_what = "US Declaration of Independence to Constitutional Convention",
          }
 };

배열 이니셜 라이저에서 범위 지정

GCC는 배열에서 동일한 초기화 프로그램을 제공해야하는 요소의 범위를 지정할 수있는 확장 을 제공합니다.

int array[] = { [3 ... 7] = 29, 19 = 107 };

삼중 점은 점들 중 하나가 부동 소수점 숫자의 일부로 해석되지 않도록 ( 최대 뭉크 규칙) 숫자와 분리되어야 합니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow