C Language
초기화
수색…
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는이를 확장 할 수 있습니다.
C89 / C90 또는 이전 버전의 C에서는 이전 값을 모두 제공하지 않고 배열의 중간에 요소를 초기화 할 수있는 방법이 없었습니다.
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는 지정된 초기화 프로그램 의 개념을 도입했습니다 . 이를 통해 배열, 구조체 또는 공용체의 어떤 요소를 다음 값으로 초기화할지 지정할 수 있습니다.
배열 요소에 대한 지정된 초기화 프로그램
일반 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으로 설정).
노조에 대한 지정된 초기화 프로그램
공용체의 어느 요소를 지정된 초기화 프로그램으로 초기화할지 지정할 수 있습니다.
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에서는 구조체 내에서 익명의 공용 멤버를 사용할 수 있으므로 앞의 예제에서 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 };
삼중 점은 점들 중 하나가 부동 소수점 숫자의 일부로 해석되지 않도록 ( 최대 뭉크 규칙) 숫자와 분리되어야 합니다.