C 구문
C syntax이 문서는 갱신할 필요가 있습니다.(2021년 7월) |
C 프로그래밍 언어의 구문은 C 언어의 소프트웨어 쓰기를 관리하는 규칙 세트입니다.이는 매우 간결하고 결과 객체 코드와 밀접한 관계를 가지면서도 비교적 높은 수준의 데이터 추상화를 제공하는 프로그램을 지원하도록 설계되었습니다.C는 휴대용 운영 체제 개발에서 널리 성공한 최초의 고급 언어입니다.
C 구문은 최대 뭉크의 원리를 이용한다.
데이터 구조
원시 데이터 유형
C언어는 정수, 실수, 복소수의 3가지 형태로 숫자를 나타냅니다.이러한 차이는 대부분의 중앙 처리 장치의 명령 집합 아키텍처에서 유사한 차이를 반영합니다.적분 데이터 유형은 정수 집합에 숫자를 저장하는 반면, 실수와 복소수는 부동 소수점 형식의 실수 집합(또는 숫자 쌍)을 나타냅니다.
모든 C 정수형은signed
그리고.unsigned
변종입니다.한다면signed
또는unsigned
대부분의 경우 명시적으로 지정되어 있지 않습니다.signed
상정하고 있습니다.하지만 역사적인 이유로 분명합니다.char
둘 다와는 다른 타입입니다.signed char
그리고.unsigned char
컴파일러 및 문자 세트에 따라 부호 있는 타입 또는 부호 없는 타입이 될 수 있습니다(C는 C 기본 문자 집합의 멤버가 양의 값을 갖는 것을 보증합니다).또한 비트 필드 유형이 플레인으로 지정됨int
는 컴파일러에 따라 서명되거나 서명되지 않을 수 있습니다.
정수형
C의 정수형은 다양한 범위의 숫자를 나타낼 수 있는 다양한 고정 크기로 제공됩니다.종류char
는 정확히 1바이트(주소 지정 가능한 최소 스토리지 유닛)를 점유하고 있으며, 일반적으로는 8비트 너비입니다.(단,char
는 C의 "기본" 문자 중 하나를 나타낼 수 있습니다.국제 문자 집합에는 더 넓은 유형이 필요할 수 있습니다.대부분의 정수형에는 부호 있는 종류와 부호 없는 종류가 있으며,signed
그리고.unsigned
키워드를 지정합니다.부호 있는 정수형은 2의 보, 1의 보 또는 부호 및 크기 표현을 사용할 수 있습니다.대부분의 경우 유형을 지정하는 방법은 여러 가지가 있습니다. 예를 들어 다음과 같습니다.signed short int
그리고.short
동의어입니다.
일부 유형의 표현에는 스토리지를 사용하지만 너비에 포함되지 않는 사용되지 않는 "패딩" 비트가 포함될 수 있습니다.다음 표는 표준 정수 유형과 최소 허용 폭(부호 비트 포함)의 전체 목록을 보여 줍니다.
지정자의 최단 형식 | 최소 폭(비트) |
---|---|
_Bool | 1 |
char | 8 |
signed char | 8 |
unsigned char | 8 |
short | 16 |
unsigned short | 16 |
int | 16 |
unsigned int | 16 |
long | 32 |
unsigned long | 32 |
long long [1] | 64 |
unsigned long long [1] | 64 |
그char
타입은 양쪽 모두와 다르다signed char
그리고.unsigned char
단, 이들 중 하나와 동일한 표현이 보장됩니다.그_Bool
그리고.long long
타입은 1999년부터 표준화되어 오래된 C 컴파일러에서는 지원되지 않을 수 있습니다.유형_Bool
통상, 에 액세스 할 수 있습니다.typedef
이름.bool
표준 헤더 stdbool.h에 의해 정의됩니다.
일반적으로, 임의의 플랫폼에 실장된 폭과 표현 스킴은 기계 아키텍처에 근거해 선택되며, 다른 플랫폼용으로 개발된 소스 코드 Import의 용이성을 어느 정도 고려한다.의 폭int
타입은 특히 C 구현에 따라 크게 다릅니다.대부분은 특정 플랫폼의 가장 자연스러운 워드사이즈에 대응합니다.standard header limits.h는 특정 플랫폼에 구현되어 있는 표준 정수 유형의 최소값 및 최대값 매크로를 정의합니다.
표준 정수형 외에 다음과 같은 "확장" 정수형이 있을 수 있습니다.typedef
표준 헤더에 있습니다.폭의 보다 정확한 사양을 위해 프로그래머는 다음을 사용할 수 있습니다.typedef
s는 표준 헤더 stdint.h에서 생성됩니다.
정수 상수는 여러 가지 방법으로 소스 코드에서 지정할 수 있습니다.숫자 값은 10진수로 지정할 수 있습니다(예:1022
, 프리픽스로서 제로(0)의 8진수(01776
또는 프리픽스로 0x(0x)를 사용하는 16진수(0x3FE
작은 따옴표로 둘러싸인 문자(예:'R'
'문자 상수'라고 불리는)는 실행 문자 집합의 해당 문자 값을 type으로 나타냅니다.int
문자 상수를 제외하고 정수 상수의 유형은 지정된 값을 나타내기 위해 필요한 너비에 의해 결정되지만 항상 최소 너비는 다음과 같습니다.int
이는 명시적인 길이 및 부호 수식자를 추가하는 것으로 덮어쓸 수 있습니다.예를 들어 다음과 같습니다.12lu
타입이 있다unsigned long
음의 정수 상수는 없지만 단항 부정 연산자 "-"를 사용하면 동일한 효과를 얻을 수 있습니다.
열거형
C에 열거된 유형.enum
키워드(일반적으로 ee'-num /senumi.n'm/ 또는 e'-noom /senumi.n'm/로 발음됨)는 일련의 명명된 상수에 걸쳐 값을 나타내도록 설계된 유형입니다.열거된 각 상수에 유형이 있습니다.int
.각각enum
타입 자체는 와 호환성이 있습니다.char
또는 부호 있는 정수 타입 또는 부호 없는 정수 타입이지만, 각 실장에서는 타입 선택에 관한 독자적인 룰이 정의됩니다.
일부 컴파일러는 열거형 객체에 상수가 아닌 값이 할당되면 경고합니다.단, 이러한 오브젝트에는 호환 가능한 타입의 범위에서 임의의 값을 할당할 수 있습니다.enum
상수는 정수가 예상되는 모든 곳에서 사용할 수 있습니다.이런 이유로enum
값은 종종 프리프로세서 대신 사용됩니다.#define
명명된 상수를 생성하는 지시사항을 참조하십시오.이러한 상수는 특정 식별자 네임스페이스 내에 존재하기 때문에 일반적으로 매크로보다 사용하기에 안전합니다.
열거형 타입은 다음과 같이 선언됩니다.enum
지정자 및 열거형 옵션 이름(또는 태그) 뒤에 콤마로 구분된 하나 이상의 상수 목록 및 변수 이름 목록이 표시됩니다.열거된 특정 유형에 대한 후속 참조에서는enum
키워드 및 열거형 이름.디폴트로는 열거의 첫 번째 상수는 값 0이 할당되어 후속 각 값은 이전 상수보다 1씩 증가합니다.선언의 상수에 특정 값을 할당할 수도 있으며, 특정 값이 없는 후속 상수에는 해당 시점부터 증분 값이 지정됩니다.예를 들어, 다음의 선언을 생각해 보겠습니다.
열거하다 색채 { 빨간., 초록의, 파랑색 = 5, 노란 색 } 페인트_color;
이것에 의해,enum colors
타이프;int
상수RED
(최소값은 0),GREEN
(예측값은 다음 값보다1 큼)RED
, 1),BLUE
(최소값은 지정된 값, 5) 및YELLOW
(예측값은 다음 값보다1 큼)BLUE
, 6) 및enum colors
변수paint_color
. 상수는 열거의 컨텍스트 밖에서 사용할 수 있으며(정수 값은 모두 허용됨), 정수 이외의 값은 에 할당할 수 있습니다.paint_color
, 또는 기타 유형의 변수enum colors
.
부동 소수점 유형
부동소수점 형식은 소수점 구성 요소로 숫자를 나타내기 위해 사용됩니다.그러나 그것들은 가장 합리적인 숫자를 정확히 나타내지는 않는다. 대신에 그들은 가까운 근사치이다.실측값에는 3가지 타입이 있으며, 지정자로 나타납니다.단일 정밀도(single precision)float
), 2배의 정밀도)double
2배의 정밀도(long double
)는, 각각 다른 형식(통상은 IEEE 부동 소수점 형식)으로 값을 나타낼 수 있습니다.
유형 지정자 | 정밀도(10진수) | 지수 범위 | ||
---|---|---|---|---|
최소 | IEEE 754 | 최소 | IEEE 754 | |
float | 6 | 7.2(24비트) | ±37 | ±38(8비트) |
double | 10 | 15.9 (53 비트) | ±37 | ±307 (11 비트) |
long double | 10 | 34.0 (표준 비트) | ±37 | ±4931(15비트) |
부동소수점 상수는 10진수 표기법(예:1.23
. 10진수 과학적 표기법은 다음을 추가하여 사용할 수 있다.e
또는E
E 표기법이라고도 하는 10진수 지수 뒤에 나옵니다.1.23e2
(이 값은 1.23 × 102 = 123.0이다.)소수점 또는 지수가 필요합니다(그렇지 않으면 숫자는 정수 상수로 해석됩니다).16진수 부동소수점 상수는 동일한 규칙을 따르지만 프레픽스에는 다음과 같이 부가되어야 합니다.0x
및 사용p
또는P
이진수 지수를 지정합니다(예:0xAp-2
(A × 2−2 = 10 × 2−2 = 10 4 4이므로h 2.5의 값을 가진다.)10진수 및 16진수 부동소수점 상수는 모두 다음과 같이 접미사가 붙을 수 있습니다.f
또는F
활자의 상수를 나타내다float
,타고l
(레터l
) 또는L
활자를 나타내다long double
또는 고정되지 않은 상태로 두거나double
일정한.
표준 헤더 파일은 구현 부동소수점 유형의 최소값과 최대값을 정의합니다.float
,double
,그리고.long double
또한 부동 소수점 숫자의 처리와 관련된 다른 제한도 정의합니다.
저장소 클래스 지정자
모든 개체에는 저장소 클래스가 있습니다.기본적으로 저장 기간을 지정합니다. 저장 기간은 다른 기능(링크 및 레지스터 힌트)과 함께 정적(글로벌의 경우 기본값), 자동(로컬의 경우 기본값) 또는 동적(할당됨)일 수 있습니다.
지정자 | 라이프 타임 | 범위 | 디폴트 이니셜라이저 |
---|---|---|---|
auto | 블록(스택) | 블록 | 초기화되지 않음 |
register | 블록(스택 또는 CPU 레지스터) | 블록 | 초기화되지 않음 |
static | 프로그램. | 블록 또는 컴파일 유닛 | 영 |
extern | 프로그램. | 글로벌(전체 프로그램) | 영 |
(없음)1 | 동적(히프) | 초기화되지 않음(초기화됨)0 사용한다면calloc() ) |
- 1 를 사용하여 할당 및 할당 해제
malloc()
그리고.free()
라이브러리 기능.
기본적으로 블록 내에서 선언된 변수에는 또는 스토리지 클래스 지정자를 사용하여 명시적으로 선언된 변수와 마찬가지로 자동 저장소가 있습니다.그auto
그리고.register
지정자는 함수 및 함수 인수 선언 내에서만 사용할 수 있습니다.따라서,auto
지정자는 항상 중복됩니다.모든 블록 외부에 선언된 개체와 스토리지 클래스 지정자를 사용하여 명시적으로 선언된 개체는 정적 저장 기간을 가집니다.정적 변수는 컴파일러에 의해 기본적으로 0으로 초기화됩니다.
자동 저장소가 있는 개체는 선언된 블록에 대해 로컬이며 블록이 종료될 때 삭제됩니다.또한 오브젝트는 다음과 같이 선언되었습니다.register
스토리지 클래스는 레지스터에 액세스하기 위해 컴파일러에 의해 더 높은 우선순위가 부여될 수 있습니다. 그러나 컴파일러는 레지스터에 실제로 저장하지 않을 수도 있습니다.이 스토리지 클래스를 가진 개체는 주소 지정( )와 함께 사용할 수 없습니다.&
) 단항 연산자.정적 저장소가 있는 개체는 프로그램의 전체 기간 동안 유지됩니다.이와 같이 여러 콜에 걸쳐 함수를 통해 동일한 오브젝트에 액세스할 수 있습니다.스토리지 기간이 할당된 개체는 를 사용하여 명시적으로 생성 및 파기됩니다.free
, 및 관련 기능.
저장소 클래스 지정자는 개체의 저장소가 다른 위치에 정의되었음을 나타냅니다.블록 내에서 사용되는 경우 해당 블록 외부의 선언에 의해 스토리지가 정의되었음을 나타냅니다.모든 블록 외부에서 사용되는 경우 스토리지가 컴파일 유닛 외부에서 정의되었음을 나타냅니다.그extern
스토리지 클래스 지정자는 함수 선언에 사용되는 경우 중복됩니다.선언된 함수가 컴파일 유닛 외부에 정의되었음을 나타냅니다.
스토리지 지정자는 함수 및 개체에만 적용되며, 유형 및 열거 선언과 같은 다른 항목은 해당 지정자가 나타나는 컴파일 단위에는 비공개로 적용됩니다.한편, 타입에는 한정자가 있습니다(아래 참조).
유형 한정자
데이터의 특수 속성을 나타내도록 유형을 한정할 수 있습니다.유형 한정자const
는, 초기화가 끝난 후에는 값이 변경되지 않는 것을 나타냅니다.수정 시도 중const
정규화된 값은 정의되지 않은 동작을 생성하므로 일부 C 컴파일러는 이러한 동작을 로다타 또는 (임베디드 시스템의 경우) 읽기 전용 메모리(ROM)에 저장합니다.유형 한정자volatile
최적화 컴파일러에 대해 표현식이나 스테이트먼트에 의해 값이 변경되지 않았더라도 명백한 중복 읽기 또는 쓰기가 제거되지 않을 수 있음을 나타냅니다.메모리 매핑 I/O 등 여러 쓰기가 필요할 수 있습니다.
불완전한 유형
불완전한 유형은 멤버가 아직 지정되지 않은 구조체 또는 결합 유형, 차원이 아직 지정되지 않은 배열 유형 또는void
를 입력합니다.void
유형을 완료할 수 없습니다).이러한 유형은 인스턴스화할 수 없습니다(크기는 알 수 없음). 또한 해당 멤버에 액세스할 수 없습니다(이들 역시 알 수 없음). 단, 파생된 포인터 유형을 사용할 수 있습니다(참조되지 않음).
포워드 선언 또는 외부 선언으로 포인터와 함께 사용되는 경우가 많습니다.예를 들어 코드는 다음과 같은 불완전한 유형을 선언할 수 있습니다.
구조 것 *pt;
이것은 선언합니다.pt
에 대한 지침으로서struct thing
그리고 불완전한 타입struct thing
데이터에 대한 포인터는 무엇을 가리키든 항상 같은 바이트 폭을 가지므로 이 문장은 그 자체로 유효합니다(단,pt
참조되지 않습니다).불완전한 유형은 나중에 다시 클리어하여 같은 범위에서 완료할 수 있습니다.
구조 것 { 인트 숫자; }; /* that structure type이 완료되었습니다*/
불완전한 유형은 재귀 구조를 구현하기 위해 사용됩니다.유형 선언의 본문은 변환 단위의 후반으로 미뤄질 수 있습니다.
유형화된 구조 버트 버트; 유형화된 구조 윌마 윌마; 구조 버트 { 윌마 *할 수 있다; }; 구조 윌마 { 버트 *버트; };
불완전한 유형은 데이터 숨김에도 사용됩니다. 불완전한 유형은 헤더 파일에 정의되며 본문은 관련 소스 파일 내에서만 정의됩니다.
포인터
선언에서는 아스타리스크 수식자(*
)는 포인터 타입을 지정합니다.예를 들어, 지정자는int
integer 타입, 즉 지정자를 참조합니다.int*
는 "정수" 타입을 나타냅니다.포인터 값은 메모리 주소와 데이터 유형의 두 가지 정보를 연결합니다.다음 코드 행은 ptr이라는 이름의 정수 포인터 변수를 선언합니다.
인트 *ptr;
참조하다
비 스태틱 포인터가 선언되면 비 스태틱 포인터에 지정되지 않은 값이 관련지어집니다.이러한 포인터와 관련된 주소는 사용하기 전에 할당에 의해 변경해야 합니다.다음 예제에서는 ptr이 변수 a와 관련된 데이터를 가리키도록 설정됩니다.
인트 a = 0; 인트 *ptr = &a;
이를 실현하기 위해 "address-of" 연산자(단일)&
)가 사용됩니다.그 후 데이터 객체의 메모리 위치를 생성합니다.
디레퍼런스
포인터 값을 통해 포인터 데이터에 액세스할 수 있습니다.다음 예제에서는 정수 변수 b를 정수 변수 a 값(10)으로 설정합니다.
인트 a=10; 인트 *p; p = &a; 인트 b = *p;
이 작업을 수행하기 위해 아스타리스크(*)로 표시되는 단항 디레퍼런스 연산자가 사용됩니다.오퍼랜드(포인터 타입이어야 함)가 가리키는 데이터를 포인터 타입으로 해야 합니다.따라서 식 *p는 a와 같은 값을 나타냅니다.늘 포인터의 참조 해제는 불법입니다.
어레이
어레이 정의
배열은 같은 유형의 연속된 요소의 구조를 나타내기 위해 C에서 사용됩니다.(고정 크기) 배열의 정의에는 다음과 같은 구문이 있습니다.
인트 배열[100];
기본 유형의 100개의 값을 저장하기 위해 어레이라는 이름의 배열을 정의합니다.int
함수 내에서 선언된 경우 어레이 치수는 일정하지 않은 식일 수도 있습니다.이 경우 지정된 수의 요소에 대한 메모리가 할당됩니다.나중에 사용되는 대부분의 컨텍스트에서 변수 배열의 언급은 배열의 첫 번째 항목에 대한 포인터로 변환됩니다.연산자는 예외입니다.sizeof array
전체 어레이의 크기를 산출합니다(즉, 100배).int
,그리고.sizeof(array) / sizeof(int)
는 100을 반환합니다).또 다른 예외는 &(주소) 연산자로, 예를 들어 어레이 전체에 대한 포인터를 생성합니다.
인트 (*ptr_to_array)[100] = &배열;
요소 접근
어레이 요소의 값에 액세스하는 주요 기능은 어레이 첨자 연산자입니다.어레이의 i 인덱스 요소에 액세스하려면 구문은 다음과 같습니다.array[i]
이 값은 해당 배열 요소에 저장된 값을 나타냅니다.
어레이의 서브스크립트 번호는 0부터 시작합니다(제로 기반 인덱싱 참조).따라서 허용되는 최대 배열 첨자는 배열 내의 요소 수에서 1을 뺀 값과 같습니다.이를 설명하기 위해 어레이는 10개의 요소를 가진 것으로 간주합니다.첫 번째 요소는 다음과 같습니다.a[0]
그리고 마지막 요소는a[9]
.
C는 어레이 사용률을 자동으로 확인하는 기능을 제공하지 않습니다.논리적으로는 10개 요소의 배열에서 마지막 첨자는 9이지만, 첨자 10, 11 등이 실수로 지정되고 결과가 정의되지 않을 수 있습니다.
어레이와 포인터가 교환 가능하기 때문에 각 어레이 요소의 주소는 동등한 포인터 산술로 표현될 수 있습니다.다음 표에서는 기존 어레이의 두 가지 방법을 보여 줍니다.
요소 | 첫번째 | 둘째 | 셋째 | n번째 |
---|---|---|---|---|
어레이 서브스크립트 | array[0] | array[1] | array[2] | array[n - 1] |
참조된 포인터 | *array | *(array + 1) | *(array + 2) | *(array + n - 1) |
그 표현 이후a[i]
의미적으로는 와 동등하다.*(a+i)
즉, 에 해당합니다.*(i+a)
, 이 표현은 다음과 같이 쓸 수도 있습니다.i[a]
단, 이 형식은 거의 사용되지 않습니다.
가변 길이 어레이
C99 블록 범위 내에서 VLA(Variable-Length Array)를 표준화.이러한 배열 변수는 블록에 진입할 때 런타임에 정수 값을 기반으로 할당되며 블록 [3]끝에 할당 해제됩니다.C11부터는 이 기능을 컴파일러에 의해 구현할 필요가 없습니다.
인트 n = ...; 인트 a[n]; a[3] = 10;
이 구문은 블록이 끝날 때까지 크기가 고정된 배열을 생성합니다.
동적 어레이
C 표준 라이브러리를 사용하여 동적으로 크기를 조정할 수 있는 어레이를 생성할 수 있습니다.그malloc
함수는 메모리를 할당하는 간단한 방법을 제공합니다.할당하는 메모리의 양(바이트 단위)이라는1개의 파라미터를 사용합니다.할당이 성공하면malloc
범용(void
포인터 값. 할당된 공간의 시작을 나타냅니다.반환된 포인터 값은 할당에 의해 암묵적으로 적절한 유형으로 변환됩니다.할당을 완료할 수 없는 경우malloc
늘 포인터를 반환합니다.따라서 다음 세그먼트는 위의 원하는 선언과 기능이 유사합니다.
#실패하다 <stdlib.h>/*가 malloc */를 선언합니다. ... 인트 *a = 마로크(n * 크기 *a); a[3] = 10;
그 결과, 「에의 포인트」가 됩니다.int
n개의 연속된 첫 번째 변수를 가리키는 변수(a)int
오브젝트: 어레이와 어레이의 등가성으로 인해 마지막 줄에 나타나 있듯이 실제 어레이 이름 대신 사용할 수 있습니다.이 동적 할당을 사용하는 장점은 할당되는 메모리의 양을 런타임에 실제로 필요한 양으로 제한하고 필요에 따라 변경할 수 있다는 것입니다(표준 라이브러리 기능을 사용).
동적으로 할당된 메모리가 더 이상 필요하지 않은 경우 런타임 시스템에 다시 릴리스해야 합니다.이것은, 에의 콜에 의해서 행해집니다.free
기능.이전에 할당된 메모리에 대한 포인터라는 단일 매개 변수를 사용합니다.이 값은 에 대한 이전 호출에서 반환된 값입니다.malloc
.
보안 대책으로서 일부 프로그래머는[who?] 포인터 변수를 다음과 같이 설정합니다.NULL
:
공짜(a); a = 특수한 순서;
그러면 대부분의 시스템에서 포인터를 참조 해제하려고 하면 프로그램이 크래시됩니다.이렇게 하지 않으면 변수는 use-after-free 버그로 이어질 수 있는 덩글링 포인터가 됩니다.단, 포인터가 로컬 변수인 경우 포인터를 다음과 같이 설정합니다.NULL
는, 프로그램이 포인터의 다른 카피를 사용하는 것을 금지하지 않습니다.로컬 사용 후 버그는 일반적으로 정적 분석기가 쉽게 인식할 수 있습니다.따라서, 이 접근법은 로컬 포인터에는 덜 유용하며 긴 수명 구조에 저장된 포인터와 함께 더 자주 사용됩니다.단, 일반적으로 포인터 설정NULL
프로그래머가 할 수 있는 좋은[according to whom?] 프랙티스입니다.NULL
-비참조 전에 포인터를 체크하여 크래시를 방지합니다.
어레이의 예를 호출하면 동적 할당을 통해 고정 크기의 어레이를 생성할 수도 있습니다.
인트 (*a)[100] = 마로크(크기 *a);
...어레이 포인터를 생성합니다.
어레이 포인터에 액세스 하려면 , 다음의 2개의 방법이 있습니다.
(*a)[색인]; 색인[*a];
반복은 다음 두 가지 방법으로도 수행할 수 있습니다.
위해서 (인트 i = 0; i < > 100; i++) (*a)[i]; 위해서 (인트 *i = a[0]; i < > a[1]; i++) *i;
두 번째 예제를 사용하면 첫 번째 예제의 숫자 제한이 필요하지 않다는 장점이 있습니다. 즉, 배열에 대한 포인터는 임의의 크기로 사용할 수 있으며 두 번째 예제는 수정 없이 실행할 수 있습니다.
다차원 어레이
또한 C는 행 줄자 순서로 저장되는 다중 차원의 어레이를 지원합니다.기술적으로 C 다차원 배열은 요소가 배열인 1차원 배열일 뿐입니다.다차원 배열을 선언하는 구문은 다음과 같습니다.
인트 어레이2d[행][열];
여기서 ROWS 및 COLUMNS는 상수입니다.이것은 2차원 배열을 정의합니다.첨자를 왼쪽에서 오른쪽으로 읽을 때, array2d는 길이 ROWS의 배열이며, 각 요소는 COLUMNS 정수의 배열입니다.
이 다차원 배열의 정수 요소에 액세스하려면
어레이2d[4][3]
다시 왼쪽에서 오른쪽으로 읽으면 5번째 행과 그 행의 4번째 요소에 액세스합니다.표현array2d[4]
는 배열입니다.이 배열에 [3]을 붙여서 네 번째 정수에 액세스합니다.
요소 | 첫번째 | 두 번째 행, 두 번째 열 | ith 행, j번째 열 |
---|---|---|---|
어레이 서브스크립트 | array[0][0] | array[1][1] | array[i - 1][j - 1] |
참조된 포인터 | *(*(array + 0) + 0) | *(*(array + 1) + 1) | *(*(array + i - 1) + j - 1) |
고차원 어레이도 같은 방법으로 선언할 수 있습니다.
다차원 어레이는 어레이에 대한 참조 배열(Iliffe 벡터 또는 어레이 배열이라고도 함)과 혼동해서는 안 됩니다.전자는 항상 직사각형(모든 하위 배열은 같은 크기여야 함)이며 연속된 메모리 영역을 차지합니다.후자는 포인터의 1차원 배열이며, 각 배열은 메모리 내의 다른 위치에 있는 서브 배열의 첫 번째 요소를 가리킬 수 있으며, 서브 배열의 크기가 같을 필요는 없습니다.후자는 여러 가지 방법으로 생성할 수 있습니다.malloc
.
줄들
C에서는 스트링 리터럴은 큰따옴표로 둘러싸여 있습니다."
), 예:"Hello world!"
지정된 배열로 컴파일됩니다.char
값에는 문자열의 끝을 마킹하기 위한 추가 늘 끝 문자(0-값) 코드가 포함됩니다.
문자열 리터럴에는 삽입된 줄바꿈이 포함되지 않을 수 있습니다.이 proscription은 언어의 해석을 다소 간소화합니다.문자열에 새 줄을 포함하려면 백슬래시 이스케이프 \n
다음과 같이 사용할 수 있습니다.
문자열 데이터(반드시 일정하지는 않음)를 사용하여 동작하기 위한 몇 가지 표준 라이브러리 함수가 있습니다.char
이 null-terminated 형식을 사용합니다.아래를 참조해 주세요.
C의 스트링 리터럴 구문은 매우 영향력이 있으며, C++, Objective-C, Perl, Python, PHP, Java, Javascript, C#, Ruby와 같은 다른 언어에도 진출했습니다.오늘날 거의 모든 새로운 언어는 C-스타일 문자열 구문을 채택하거나 기반으로 합니다.이 구문이 없는 언어는 C보다 우선하는 경향이 있습니다.
백슬래시 이스케이프
특정 문자는 리터럴 문자열 표현에 직접 포함될 수 없으므로 대신 백슬래시로 시작하는 이스케이프 시퀀스로 식별됩니다( ).\
예를 들어, 는 에 백슬래시 됩니다."This string contains \"double quotes\"."
(컴파일러에 대해) 내부 따옴표 쌍이 문자열 자체의 딜리미터(슬리미터)로서의 기본값이 아닌 실제 문자열 부분으로 의도되었음을 나타냅니다.
백슬래시를 사용하여 다양한 제어 문자 등을 문자열에 입력할 수 있습니다.
탈출하다 | 의미. |
---|---|
\\ | 리터럴 백슬래시 |
\" | 큰따옴표 |
\' | 작은따옴표 |
\n | 줄바꿈(줄바꿈) |
\r | 캐리지 리턴 |
\b | 백스페이스 |
\t | 가로 탭 |
\f | 폼 피드 |
\a | 경보(벨) |
\v | 세로 탭 |
\? | 물음표(삼각문자 이스케이프에 사용) |
%% | 퍼센티지 마크, printf 형식의 문자열만 (주\%는 표준이 아니므로 항상 인식되는 것은 아닙니다) |
\OOO | 8진수 값이 OOO인 문자(OOO는 1-3자리 8진수, '0'-'7') |
\xHH | 16진수 값 HH를 가진 문자(여기서 HH는 1자리 이상의 16진수 숫자, '0'-'9', 'A'-'F', 'a'-'f' |
다른 백슬래시 이스케이프의 사용은 C 표준으로 정의되어 있지 않지만 컴파일러 벤더는 언어 확장자로 추가 이스케이프 코드를 제공하는 경우가 많습니다.그 중 하나는 탈출 시퀀스입니다\e
ASCII 16진수 값이 1B인 이스케이프 문자의 경우 다른 문자 세트(EBCDIC 등)의 표현이 부족하기 때문에 C 표준에 추가되지 않았습니다.GCC, clang, tcc로 이용할 수 있습니다.
문자열 리터럴 연결
C에는 스트링 리터럴 접속이 있습니다.즉, 컴파일 시에 인접한 스트링 리터럴이 접속됩니다.이를 통해 긴 스트링을 여러 줄에 걸쳐 분할할 수 있습니다.또, C 프리프로세서 정의나 매크로에 의한 스트링 리터럴을 컴파일시에 스트링에 부가할 수도 있습니다.
인쇄물(__FILE__ ": %d: 안녕하세요" "세계\n", __LINE__);
로 확장됩니다.
인쇄물("안녕하세요.c" ": %d: 안녕하세요" "세계\n", 10);
통사적으로 보면
인쇄물("hellowolld.c: %d: Hello world\n", 10);
문자 상수
개별 문자 상수는 단일 따옴표로 묶습니다.'A'
, 및 타입이 있습니다.int
(C++에서는,char
)의 차이는 다음과 같습니다."A"
는, 「A」와 「\0」의 2 문자의 늘 종단 배열을 나타냅니다.'A'
는 문자값을 직접 나타냅니다(ASCII 가 사용되고 있는 경우는 65).스트링과 동일한 백슬래시 에스케이프가 지원되지만 (물론)"
는 이스케이프 없이 문자로 사용할 수 있지만,'
이제 탈출해야 합니다.
문자 상수는 비워 둘 수 없습니다(예:''
는 비활성 구문입니다.단, 문자열은 다음과 같습니다(아직은 늘 끝문자가 붙어 있습니다).다중 문자 상수(예:'xy'
는 유효합니다만, 거의 도움이 되지 않습니다.예를 들어 32비트 정수에 여러 문자를 저장할 수 있습니다(예를 들어 4개의 ASCII 문자를 64비트 정수에 저장할 수 있습니다).캐릭터가 빽빽이 들어찬 순서부터int
를 지정하지 않았습니다(정의하는 구현에 맡겨져 있습니다).다문자 상수의 포터블 사용은 어렵습니다.
그럼에도 불구하고 특정 플랫폼과 컴파일러 구현으로 제한된 상황에서는 다중 문자 상수가 시그니처를 지정하는 데 사용됩니다.일반적인 사용 예로는 OSType이 있습니다.클래식 Mac OS 컴파일러와 그 고유의 빅 엔디안을 조합하면 정수 내의 바이트가 리터럴에 정의된 문자의 정확한 순서로 표시됩니다.GCC, Clang 및 Visual C++에서는 일반적인 "실장"에 의한 정의는 실제로 일치합니다.'1234'
수율0x31323334
ASCII를 사용합니다.[5][6]
와이드 문자열
이후 유형char
폭은 1바이트, 1바이트입니다.char
값은 일반적으로 최대 255개의 고유 문자 코드를 나타낼 수 있으며, 전 세계에서 사용되는 모든 문자에는 거의 부족합니다.국제 문자에 대한 지원을 강화하기 위해 첫 번째 C 표준(C89)에서는 와이드 문자(타입으로 인코딩됨)가 도입되었습니다.wchar_t
와이드 문자열은 다음과 같습니다.L"Hello world!"
와이드 문자는 보통 2바이트(UTF-16 등의 2바이트 부호화 사용) 또는4바이트(통상은 UTF-32) 중 하나이지만 표준 C에서는 다음과 같은 너비는 지정되어 있지 않습니다.wchar_t
선택권은 실장자에게 맡깁니다.Microsoft Windows 에서는 일반적으로 UTF-16 이 사용되고 있기 때문에, 상기의 문자열은 Microsoft 컴파일러에서는 26 바이트가 됩니다.유닉스 월드에서는 UTF-32 가 우선되기 때문에, GCC 등의 컴파일러에서는 52 바이트의 문자열이 생성됩니다.2바이트 폭wchar_t
과 같은 제약을 받다char
특정 문자(BMP 이외의 문자)는 1개의 문자로 나타낼 수 없습니다.wchar_t
; 단, 대리 쌍을 사용하여 표현해야 합니다.
원래 C 표준은 넓은 문자열로 작동하기 위한 최소한의 기능만을 규정했습니다. 1995년에 표준은 다음과 같은 훨씬 더 광범위한 지원을 포함하도록 수정되었습니다.char
줄들.관련 함수는 대부분 다음 함수의 이름을 따서 명명됩니다.char
"w"를 추가하거나 "str"를 "wcs"로 대체한 등가물.<wchar.h>
,와 함께<wctype.h>
와이드 문자 분류 및 매핑 기능을 포함합니다.
현재 일반적으로 권장되는[7] 국제 캐릭터 지원 방법은 UTF-8을 사용하는 것입니다.UTF-8은 UTF-8에 저장되어 있습니다.char
UTF-8은 직접 ASCII 확장자이기 때문에 UTF-8 에디터를 사용하는 경우 소스 코드로 직접 쓸 수 있습니다.
가변 폭 문자열
에 대한 일반적인 대안wchar_t
는 가변폭 부호화를 사용하는 것입니다.이것에 의해, 1개의 논리 문자가 문자열의 복수의 위치에 걸쳐 확장되는 일이 있습니다.가변폭 문자열은 컴파일러를 혼란스럽게 하거나 숫자 백슬래시 이스케이프를 사용할 위험이 있으므로 문자 그대로 인코딩할 수 있습니다(예:"\xc3\xa9"
(UTF-8의 'e'에 대해)UTF-8 인코딩은 표준 라이브러리 문자열 함수와의 호환성을 위해 특별히 설계되었습니다(플랜 9). 인코딩의 지원 기능에는 임베디드 늘의 부족, 후속 해석의 유효한 없음 및 사소한 재동기화가 포함됩니다.이러한 기능이 없는 인코딩은 표준 라이브러리 함수와 호환되지 않을 수 있습니다.인코딩 대응 문자열 함수가 사용되는 경우가 많습니다.
라이브러리 기능
문자열은 상수 및 변수 모두 표준 라이브러리를 사용하지 않고 조작할 수 있습니다.그러나 라이브러리에는 늘 종단 문자열로 작업하는 데 유용한 함수가 많이 포함되어 있습니다.
구조 및 조합
구조물들
C의 구조와 결합은 다양한 유형의 명명된 구성원으로 구성된 데이터 컨테이너로 정의된다.다른 프로그래밍 언어의 레코드와 유사합니다.컴파일러는 효율을 위해 멤버 간 또는 멤버 뒤에 (첫 번째 멤버 앞은 아님) 패딩을 삽입하거나 타겟 아키텍처에 의한 적절한 정렬에 필요한 패딩으로 삽입할 수 있지만 구조의 멤버는 메모리의 연속된 위치에 저장됩니다.구조물의 크기는 해당 구성원의 크기 합계와 패딩 크기와 동일합니다.
유니언
C의 결합은 구조물과 관련이 있으며 다양한 유형 및 크기의 물체를 (다른 시간에) 보유할 수 있는 물체로 정의된다.다른 프로그래밍 언어의 변형 레코드와 유사합니다.구조와는 달리 유니언의 컴포넌트는 모두 메모리 내의 같은 위치를 참조합니다.이렇게 하면 새로운 유형별로 별도의 객체를 작성할 필요 없이 다양한 시간에 결합을 사용하여 다른 유형의 객체를 유지할 수 있습니다.유니언의 크기는 가장 큰 성분 유형의 크기와 같습니다.
선언.
구조물은 키워드로 선언되고 조합은 다음과 같이 선언됩니다.union
키워드를 지정합니다.specifier 키워드 뒤에 임의의 ID 이름이 붙습니다.이 ID는 구조체 또는 유니언 형식을 식별하기 위해 사용됩니다.식별자 뒤에는 구조체 또는 유니언 본문의 선언이 이어집니다.각 선언은 세미콜론으로 끝납니다.멤버 선언 리스트는 중괄호로 둘러싸여 있습니다.마지막으로 선언은 구조체 또는 결합의 인스턴스로 선언되는 식별자 이름의 선택적 목록으로 끝납니다.
예를 들어, 다음 문장은 다음과 같은 구조를 선언합니다.s
3개의 멤버를 포함하고 있다.또한 다음과 같이 알려진 구조의 인스턴스를 선언한다.tee
:
구조 s { 인트 x; 흘러가다 y; 차 *z; } 티;
그리고 다음 진술은 다음과 같은 이름의 유사한 결합을 선언할 것입니다.u
그리고 그 예로는n
:
조합 u { 인트 x; 흘러가다 y; 차 *z; } n;
구조 및 결합의 구성원은 불완전하거나 기능 유형을 가질 수 없습니다.따라서 멤버는 선언되는 구조 또는 유니언의 인스턴스가 될 수 없지만(그 시점에서 불완전하기 때문에) 선언되는 유형에 대한 포인터가 될 수 있습니다.
구조체 또는 유니언 본체가 선언되고 이름이 지정되면 지정자를 사용하여 새 데이터 유형으로 간주할 수 있습니다.struct
또는union
, 및 이름을 지정합니다.예를 들어, 위의 구조 선언이 주어진 다음 문은 구조의 새 인스턴스를 선언합니다.s
이름 지어진r
:
구조 s r;
또, 통상,typedef
지정자를 지정해, 필요 없게 합니다.struct
또는union
키워드를 지정합니다.구조체 본문 뒤의 첫 번째 식별자가 구조체 유형의 새 이름으로 사용됩니다(구조체 인스턴스는 이 컨텍스트에서 선언할 수 없습니다).예를 들어, 다음 명령문은 일부 구조를 포함하는 s_type이라고 하는 새로운 유형을 선언합니다.
유형화된 구조 {...} s_type;
이후 문에서는 확장 대신 s_type 지정자를 사용할 수 있습니다.struct
... specifier)는 구조를 참조합니다.
구성원 접근
구성원은 구조 또는 결합 인스턴스 이름, 마침표를 사용하여 액세스합니다..
멤버 이름.예를 들어, 위에서 tee 선언이 주어진 경우, y로 알려진 부재(타입의 경우)float
)에는, 다음의 구문을 사용해 액세스 할 수 있습니다.
티.y
구조는 일반적으로 포인터를 통해 액세스됩니다.다음 예에서는 ptr_to_tee로 알려진 티에 대한 포인터를 정의합니다.
구조 s *ptr_to_tee = &티;
그런 다음 ptr_to_tee를 참조하고 결과를 왼쪽 피연산자로 사용하여 tee의 부재 y에 액세스할 수 있습니다.
(*ptr_to_tee).y
어떤 것이 더 간단한 것과 같습니까?tee.y
ptr_to_tee가 티를 가리키는 한 위.연산자 우선순위(".")가 "*"보다 높으면 짧을수록*ptr_to_tee.y
이 목적에는 적합하지 않습니다.*(ptr_to_tee.y)
그래서 괄호가 필요합니다.이 조작은 일반적이기 때문에 C는 포인터에서 직접 멤버에 액세스하기 위한 간략한 구문을 제공합니다.이 구문을 사용하면 인스턴스 이름이 포인터 이름으로 바뀌고 마침표는 문자 시퀀스로 바뀝니다.->
따라서 다음과 같은 y 액세스 방법은 앞의 두 가지 방법과 동일합니다.
ptr_to_tee->y
조합원들도 같은 방법으로 접근한다.
예를 들어 링크된 목록에서는 다음을 참조할 수 있습니다.n->next->next
다음 두 번째 노드의 경우(이러한 경우)n->next
null이 아닙니다).
과제
구조 및 결합의 개별 구성원에 값을 할당하는 것은 구문적으로 다른 개체에 값을 할당하는 것과 동일합니다.유일한 차이점은 할당의 lvalue는 위에서 설명한 구문에 의해 접근되는 멤버의 이름이라는 것입니다.
구조물은 같은 유형의 다른 구조물에 단위로서 할당될 수도 있다.구조(및 구조에 대한 포인터)는 함수 파라미터 및 반환 유형으로도 사용할 수 있습니다.
예를 들어, 다음 문장은 위에서 구조 티의 x라는 이름의 부재에 74(문자 't'의 ASCII 코드 포인트)의 값을 할당합니다.
티.x = 74;
tee 대신 ptr_to_tee를 사용하면 다음과 같이 됩니다.
ptr_to_tee->x = 74;
조합원들과의 배정은 동일하다.
기타 작업
C 표준에 따르면 구조물에 대해 수행할 수 있는 유일한 법적 작업은 해당 구조물을 복사하여 유닛으로 할당(또는 초기화)하고 주소(address-of)를 사용하여 주소를 받는 것입니다.&
) 단항 연산자 및 해당 구성원에 액세스합니다.조합에도 같은 제한이 있습니다.암묵적으로 금지된 작업 중 하나는 비교이다. 구조와 결합은 C의 표준 비교 설비를 사용하여 비교할 수 없다.==
,>
,<
등).
비트 필드
C는 비트 필드라고 불리는 특별한 유형의 구조 부재도 제공합니다.이것은 명시적으로 지정된 비트 수를 가진 정수입니다.비트 필드가 유형의 구조 멤버로 선언됩니다.int
,signed int
,unsigned int
, 또는_Bool
멤버 이름 뒤에 콜론을 붙입니다( ).:
) 및 점유해야 하는 비트 수.단일 비트 필드의 총 비트 수는 선언된 유형의 총 비트 수를 초과할 수 없습니다.
일반적인 C 구문 규칙에 대한 특별한 예외로서 비트필드가 type으로 선언되었는지 여부가 구현 정의됩니다.int
(지정하지 않고)signed
또는unsigned
는 서명되어 있거나 서명되어 있지 않습니다.따라서 명시적으로 지정할 것을 권장합니다.signed
또는unsigned
모든 구조 멤버에 대해 이동성을 확보합니다.
콜론 뒤에 다수의 비트로 이루어진 이름 없는 필드도 허용됩니다.이러한 필드는 패딩을 나타냅니다.이름 없는 필드의 너비를 0으로 지정하면 새 [8]단어로 정렬됩니다.
비트 필드의 멤버에는 주소가 없기 때문에 address-of ()와 함께 사용할 수 없습니다.&
) 단항 연산자.그sizeof
연산자를 비트 필드에 적용할 수 없습니다.
다음 선언은 다음과 같이 알려진 새로운 구조 유형을 선언합니다.f
그리고 그 일례는 로 알려져 있다.g
. 코멘트는 각 멤버에 대한 설명을 제공합니다.
구조 f { 서명되어 있지 않다 인트 깃발 : 1; /* 비트 플래그: 켜짐(1) 또는 꺼짐(0) */ 서명된 인트 숫자 : 4; /* 부호 있는 4비트 필드, 범위 -7...7 또는 -8...7 */ 서명된 인트 : 3; /* 3비트의 패딩으로 8비트로 반올림 */ } g;
초기화
기본 초기화는 위에서 설명한 스토리지 클래스 지정자에 따라 달라집니다.
언어의 문법상 스칼라 이니셜라이저는 임의의 수의 곱슬 괄호 쌍으로 묶을 수 있습니다.그러나 대부분의 컴파일러는 이러한 쌍이 여러 개 있는 경우 경고를 보냅니다.
인트 x = 12; 인트 y = { 23 }; //법적, 경고 없음 인트 z = { { 34 } }; //Legal, 경고 예상
구조, 결합 및 배열은 이니셜라이저 목록을 사용하여 선언에서 초기화할 수 있습니다.지정자를 사용하지 않는 한 이니셜라이저의 컴포넌트는 정의 및 저장되는 순서대로 요소와 일치하므로 모든 선행 값을 특정 요소의 값보다 먼저 제공해야 합니다.지정되지 않은 요소는 모두 0으로 설정됩니다(연합 제외).너무 많은 초기화 값을 언급하면 오류가 발생합니다.
다음 명령문은 pi로 알려진 구조의 새 인스턴스를 초기화합니다.
구조 s { 인트 x; 흘러가다 y; 차 *z; }; 구조 s 파이 = { 3, 3.1415, '파이' };
지정 이니셜라이저
지정된 이니셜라이저를 사용하면 이전 값을 명시적으로 지정하지 않고 임의의 순서로 구성원을 초기화할 수 있습니다.다음의 초기화는, 전회의 초기화와 같습니다.
구조 s 파이 = { .z = '파이', .x = 3, .y = 3.1415 };
이니셜라이저에서 지정자를 사용하면 초기화 "커서"가 이동합니다.다음 예에서는 다음과 같습니다.MAX
10보다 크면 중간에는 몇 가지 제로값 요소가 있습니다.a
; 이 값이 10보다 작을 경우 첫 번째 5개의 이니셜라이저가 제공하는 값 중 일부는 두 번째 5개로 덮어씁니다.MAX
컴파일 에러가 발생합니다).
인트 a[맥스.] = { 1, 3, 5, 7, 9, [맥스.-5] = 8, 6, 4, 2, 0 };
C89년에 유니언은 첫 번째 멤버에게 단일 값을 적용하여 초기화되었습니다.즉, 위에서 정의한 union u는 int x 멤버만 초기화할 수 있습니다.
조합 u 가치 = { 3 };
지정된 이니셜라이저를 사용하면 초기화할 멤버가 첫 번째 멤버가 될 필요는 없습니다.
조합 u 가치 = { .y = 3.1415 };
어레이의 크기를 알 수 없는 경우(즉, 어레이가 불완전한 유형)에는 이니셜라이저의 수에 따라 어레이의 크기가 결정되고 유형이 완전해집니다.
인트 x[] = { 0, 1, 2 } ;
복합 지정자를 사용하면 꾸미지 않은 이니셜라이저 목록이 잘못 인식될 수 있는 경우 명시적으로 초기화할 수 있습니다.다음 예에서는w
구조물 배열로 선언되며, 각 구조물은 구성원으로 구성됩니다.a
(3개의 배열)int
)와 멤버b
(어느쪽이든)int
initializer는, 다음의 사이즈를 설정합니다.w
2로 설정하고 각 요소의 첫 번째 요소 값을 설정합니다.a
:
구조 { 인트 a[3], b; } w[] = { [0].a = {1}, [1].a[0] = 2 };
이는 다음과 같습니다.
구조 { 인트 a[3], b; } w[] = { { { 1, 0, 0 }, 0 }, { { 2, 0, 0 }, 0 } };
표준 C에서는 이니셜라이저의 반복을 지정할 수 없습니다.
복합 리터럴
초기화 방법을 빌려 복합 구조와 배열 리터럴을 생성할 수 있습니다.
// 배열 리터럴에서 포인터가 생성되었습니다. 인트 *ptr = (인트[]){ 10, 20, 30, 40 }; // 배열 포인터. 흘러가다 (*후우)[3] = &(흘러가다[]){ 0.5도, 1.f, - 0.5도 }; 구조 s 파이 = (구조 s){ 3, 3.1415, '파이' };
복합 리터럴은 선언을 [3]읽기 쉽게 하기 위해 지정된 이니셜라이저와 조합되는 경우가 많습니다.
파이 = (구조 s){ .z = '파이', .x = 3, .y = 3.1415 };
연산자
제어 구조
C는 자유형 언어입니다.
브레이싱 스타일은 프로그래머마다 다르며 토론의 주제가 될 수 있습니다.자세한 내용은 스타일 들여쓰기를 참조하십시오.
복합문
이 섹션의 항목에서는 <statement>를 복합문으로 대체할 수 있습니다.복합문의 형식은 다음과 같습니다.
{ < >선택적.-선언.-목록.> < >선택적.-진술-목록.> }
함수 또는 단일 문장이 예상되는 모든 부분의 본문으로 사용됩니다.declaration-list는 해당 범위에서 사용되는 변수를 선언하고 statement-list는 실행하는 액션입니다.각 괄호는 자체 범위를 정의하며, 이러한 괄호 안에 정의된 변수는 닫힘 괄호에서 자동으로 할당 해제됩니다.선언과 스테이트먼트는 (C++와 같이) 복합 스테이트먼트 내에서 자유롭게 혼재할 수 있습니다.
선택문
C에는 두 가지 유형의 선택 문(문 및 문)이 있습니다.
그if
문의 형식은 다음과 같습니다.
한다면 (< >표현>) < >스테이트먼트 1> 또 다른 < >스테이트먼트 2>
에서if
스테이트먼트, 만약<expression>
괄호 안은 0이 아닙니다(true).컨트롤은 다음으로 넘어갑니다.<statement1>
. 만약else
절이 존재하며<expression>
0(false)입니다.컨트롤은 다음으로 넘어갑니다.<statement2>
.그else <statement2>
부품은 옵션이며 없는 경우 false입니다.<expression>
그 결과, 단순히 넘어가는 것이 됩니다.<statement1>
. ANelse
항상 이전에 일치하지 않은 가장 가까운 항목과 일치합니다.if
; 중괄호는 필요할 때 또는 명확성을 위해 이를 재정의하기 위해 사용할 수 있습니다.
그switch
statement를 지정하면 식 값에 따라 제어가 여러 문 중 하나로 이전됩니다.식 값은 정수형이어야 합니다.스위치에 의해 제어되는 서브스테이트먼트는 일반적으로 복합적입니다.진술서 내의 모든 문장은 하나 이상의 라벨로 표시될 수 있습니다.case
라벨: 키워드로 구성됩니다.case
상수 표현 뒤에 콜론(:)이 이어집니다.구문은 다음과 같습니다.
전환하다 (< >표현>) { 사례. < >라벨 1> : < >진술들 1> 사례. < >라벨 2> : < >진술들 2> 브레이크.; 체납 : < >진술들 3> }
같은 스위치에 관련되어 있는2개의 케이스 상수는 같은 값을 가질 수 없습니다.많아야 하나일 것이다default
스위치와 관련된 라벨다음 괄호 안의 식과 동일한 케이스 라벨이 없는 경우switch
제어는 에 전달됩니다.default
라벨 또는 라벨이 없는 경우default
라벨, 실행이 전체 구성보다 조금 늦게 재개됩니다.
스위치는 네스트 할 수 있습니다.case
또는default
라벨은 가장 안쪽과 관련지어져 있습니다.switch
그 안에 있어요.스위치 스테이트먼트는 "실패"할 수 있습니다.즉, 1개의 케이스 섹션이 실행을 완료하면 스테이트먼트는 아래쪽으로 계속 실행됩니다.break;
스테이트먼트가 검출되었습니다.폴 스루는 상황에 따라 유용하지만 일반적으로는 바람직하지 않습니다.위의 예에서는 다음과 같습니다.<label2>
도달, 스테이트먼트<statements 2>
가 실행되고 괄호 안쪽에 아무것도 없습니다.단, 만약<label1>
도달했습니다.둘 다<statements 1>
그리고.<statements 2>
가 없기 때문에 실행됩니다.break
두 개의 케이스 스테이트먼트를 구분합니다.
비일상적이긴 하지만 삽입할 수 있습니다.switch
라벨을 다른 제어 구조의 하위 블록에 넣습니다.그 예로는 더프의 디바이스와 사이먼 태텀의 퍼티 [9]코루틴 구현이 있다.
반복문
C에는 다음 3가지 형식의 반복문이 있습니다.
하다 < >진술> 하는 동안에 ( < >표현> ) ; 하는 동안에 ( < >표현> ) < >진술> 위해서 ( < >표현> ; < >표현> ; < >표현> ) < >진술>
및do
스테이트먼트, 서브스테이트먼트가 반복적으로 실행되는 한 그 값은expression
는 0이 아닌 채로 있습니다(true와 동일).와 함께while
테스트(모든 부작용 포함)<expression>
는 각 반복 전에 발생합니다(의 경우).<statement>
);와 함께do
각 반복 후에 테스트가 실행됩니다.따라서,do
스테이트먼트는 항상 서브스테이트먼트를 1회 이상 실행합니다.while
는 서브스테이트먼트를 전혀 실행하지 않을 수 있습니다.
스테이트먼트:
위해서 (e1; e2; e3) s;
는 다음과 같습니다.
e1; 하는 동안에 (e2) { s; 콘텐트: e3; }
의 행동을 제외하고continue;
스테이트먼트(이것이for
로의 루프 점프e3
대신e2
)의 경우e2
공백으로 되어 있습니다.이 경우, 이 명령어는1
.
의 3가지 표현 중 하나for
루프를 생략할 수 있습니다.두 번째 표현이 누락되면while
테스트는 항상 0이 아니므로 무한 루프가 발생할 수 있습니다.
C99 이후 첫 번째 표현은 선언 형식을 취할 수 있습니다.일반적으로 다음과 같은 이니셜라이저를 포함합니다.
위해서 (인트 i = 0; i < > 제한.; ++i) { // ... }
선언의 범위는 다음과 같은 범위로 제한됩니다.for
고리.
점프문
점프문은 무조건 제어를 전송합니다.C에는 4종류의 점프문이 있습니다.continue
,break
, 및.
그goto
스테이트먼트는 다음과 같습니다.
에 가다 < >식별자> ;
식별자는 현재 기능에 위치한 라벨(콜론 뒤에 있음)이어야 합니다.라벨이 붙은 스테이트먼트로의 전송을 제어합니다.
A continue
문은 반복문 내에서만 나타날 수 있으며 가장 안쪽을 감싸는 반복문의 루프 연속 부분에 제어가 전달됩니다.즉, 각 문장에서
하는 동안에 (표현) { /* ... */ 콘텐트: ; } 하다 { /* ... */ 콘텐트: ; } 하는 동안에 (표현); 위해서 (expr1; expr2; expr3) { /* ... */ 콘텐트: ; }
a continue
중첩된 반복문에 포함되지 않은 것은 다음과 같습니다.goto cont
.
그break
스테이트먼트를 사용하여for
고리,while
고리,do
루프 또는switch
진술.제어는 종료된 스테이트먼트 뒤에 스테이트먼트로 넘어갑니다.
함수는 에 의해 발신자에게 반환됩니다.return
진술.언제return
그 뒤에 식(expression)이 붙으면 그 값이 함수의 값으로 발신자에게 반환됩니다.함수의 끝부분을 발견하는 것은return
무표정하게이 경우 함수가 값을 반환하는 것으로 선언되어 발신자가 반환된 값을 사용하려고 하면 결과는 정의되지 않습니다.
레이블 주소 저장
GCC는 단항으로 C언어를 확장합니다.&&
라벨의 주소를 반환하는 연산자.이 주소는 에 저장할 수 있습니다.void*
변수 유형으로 나중에 사용할 수 있습니다.goto
설명.예를 들어, 다음과 같은 인쇄물이 있습니다."hi "
무한 루프:
무효 *ptr = & &J1; J1: 인쇄물("안녕"); 에 가다 *ptr;
이 기능은 점프 테이블을 구현하기 위해 사용할 수 있습니다.
기능들
구문
C 함수 정의는 반환 유형(void
값이 반환되지 않는 경우), 하나의 이름, 괄호 안의 파라미터 목록 및 다양한 문장이 표시됩니다.
< >돌아가다-유형> 기능명( < >파라미터-목록.> ) { < >진술들> 돌아가다 < >표현 의 유형 돌아가다-유형>; }
다음을 포함하지 않는 함수void
반환 유형에는 하나 이상의 항목이 포함되어야 합니다.return
진술.파라미터는 에 의해 지정됩니다.<parameter-list>
, 파라미터 선언의 쉼표로 구분된 목록입니다.목록 내의 각 항목은 데이터 유형 뒤에 식별자가 이어집니다.<data-type> <variable-identifier>, <data-type> <variable-identifier>, ...
.
파라미터가 없는 경우<parameter-list>
공백으로 두거나 선택적으로 단일 단어로 지정할 수 있습니다.void
.
함수를 변수 개수의 파라미터를 취득하는 것으로 정의할 수 있습니다....
데이터 유형 및 변수 ID 대신 마지막 매개 변수로 키워드를 지정합니다.이를 위해 일반적으로 사용되는 함수는 표준 라이브러리 함수입니다.printf
다음과 같은 선언이 있습니다.
인트 인쇄물 (컨스턴트 차*, ...);
이러한 파라미터의 조작은 표준 라이브러리 헤더 내의 루틴을 사용하여 실행할 수 있습니다.
함수 포인터
함수에 대한 포인터는 다음과 같이 선언할 수 있습니다.
< >돌아가다-유형> (*<기능.-이름.>)(< >파라미터-목록.>);
다음 프로그램에서는 더하기와 빼기 중 하나를 선택하기 위한 함수 포인터의 사용을 보여 줍니다.
#실패하다 <stdio.h> 인트 (*작동)(인트 x, 인트 y); 인트 더하다(인트 x, 인트 y) { 돌아가다 x + y; } 인트 빼다(인트 x, 인트 y) { 돌아가다 x - y; } 인트 주된(인트 argc, 차* args[]) { 인트 후우 = 1, 막대기 = 1; 작동 = 더하다; 인쇄물(%d + %d = %d\n", 후우, 막대기, 작동(후우, 막대기)); 작동 = 빼다; 인쇄물(%d - %d = %d\n", 후우, 막대기, 작동(후우, 막대기)); 돌아가다 0; }
글로벌 구조
전처리 후 C 프로그램은 파일 스코프에서 일련의 선언으로 구성됩니다.이러한 파일은 여러 개의 개별 소스 파일로 분할되어 따로 컴파일할 수 있습니다.그 후 오브젝트 모듈은 구현에 의해 제공되는 런타임 지원 모듈과 함께 링크되어 실행 가능한 이미지를 생성합니다.
선언문은 함수, 변수 및 유형을 소개한다.C 기능은 Fortran의 서브루틴 또는 Pascal의 절차와 유사합니다.
정의는 특별한 유형의 선언입니다.변수 정의는 스토리지를 확보하여 초기화할 수 있으며 함수 정의는 해당 본문을 제공합니다.
모든 표준 라이브러리 기능을 제공하는 C의 구현을 호스트 구현이라고 합니다.호스트 실장용으로 작성된 프로그램은 프로그램 실행을 시작할 때 호출되는 첫 번째 함수인 특수 함수를 정의하기 위해 필요합니다.
호스트된 구현은 다음 명령을 호출하여 프로그램 실행을 시작합니다.main
다음 프로토타입 중 하나에 따라 정의해야 하는 기능:
인트 주된() {...} 인트 주된(무효) {...} 인트 주된(인트 argc, 차 *argv[]) {...} 인트 주된(인트 argc, 차 **argv) {...}
처음 두 정의는 동일합니다(둘 다 C++와 호환됩니다).어떤 것이 사용되는지는 개인의 취향에 따라 다를 수 있습니다(현재 C 규격은 다음 두 가지 예를 포함합니다).main()
그리고 두 개main(void)
단, 드래프트 C++ 규격에서는main()
)의 반환값main
(그것은,int
)는, 호스트 환경에 반환되는 종료 스테이터스로 기능합니다.
C 표준은 반환 값을 정의합니다.0
그리고.EXIT_SUCCESS
성공을 나타내는 것으로서EXIT_FAILURE
에러를 나타냅니다.(EXIT_SUCCESS
그리고.EXIT_FAILURE
에 정의되어 있습니다.다른 반환값은 구현 정의 의미를 가집니다. 예를 들어 Linux에서 신호에 의해 죽은 프로그램은 신호의 숫자 값에 128을 더한 반환 코드를 생성합니다.
최소한의 올바른 C 프로그램은 공백으로 구성됩니다.main
루틴, 인수 없이 아무것도 하지 않음:
인트 주된(무효){}
왜냐면 아니거든return
스테이트먼트가 존재합니다.main
종료 [3]시 0을 반환합니다.(이는 C99에서 도입된 특별한 케이스 기능으로,main
.)
그main
함수는 보통 다른 함수를 호출하여 작업을 수행할 수 있도록 도와줍니다.
일부 구현은 일반적으로 운영 체제에서 사용하도록 설계되지 않았기 때문에 호스팅되지 않습니다.이러한 실장은 C 표준에서는 free-standding이라고 불립니다.독립형 실장은 프로그램 부팅을 처리하는 방법을 자유롭게 지정할 수 있습니다.특히, 프로그램을 정의할 필요는 없습니다.main
기능.
함수는 프로그래머가 작성하거나 기존 라이브러리에서 제공할 수 있습니다.후자의 인터페이스는 보통 헤더 파일을 포함함으로써 선언됩니다.#include
라이브러리 오브젝트는 최종 실행 가능 이미지로 링크됩니다.등의 특정 라이브러리 함수는 C 표준에 의해 정의되며, 이를 표준 라이브러리 함수라고 합니다.
함수는 값을 호출자에게 반환할 수 있습니다(보통 다른 C 함수 또는 함수의 호스팅 환경).main
).printf
위에서 언급한 함수는 인쇄된 문자 수를 반환하지만 이 값은 무시되는 경우가 많습니다.
인수 전달
C에서는 인수는 값에 의해 함수에 전달되지만 다른 언어는 참조에 의해 변수를 전달할 수 있습니다.즉, 수신 함수는 값의 복사본을 가져오며 원래 변수를 직접 변경할 수 없습니다.다른 함수로부터 전달된 변수를 변경하기 위한 함수의 경우, 발신자는 주소(포인터)를 전달해야 합니다.이 주소는 수신함수에서 참조되지 않을 수 있습니다.자세한 내용은 포인터를 참조하십시오.
무효 인틴트(인트 *y) { (*y)++; // 아래 'main'의 'x' 값을 1씩 늘립니다. } 인트 주된(무효) { 인트 x = 0; 인틴트(&x); // 참조를 var 'x'로 전달합니다. 돌아가다 0; }
scanf 함수는 다음과 같은 방식으로 작동합니다.
인트 x; 스캔(%d, &x);
함수(예를 들어 할당된 배열을 호출 코드로 되돌리기 위해)에 편집 가능한 포인터를 전달하려면 해당 포인터(주소)에 포인터를 전달해야 합니다.
#실패하다 <stdio.h> #실패하다 <stdlib.h> 무효 allocate_array(인트 ** 컨스턴트 a_p, 컨스턴트 인트 A) { /* A int 배열 할당 *a_p에 할당하면 main()의 'a'가 변경됩니다. */ *a_p = 마로크(크기(인트) * A); } 인트 주된(무효) { 인트 * a; /* 1개 이상의 int에 대한 포인터를 만듭니다.이것이 어레이*/가 됩니다. /* "a" 주소를 전달합니다 */ allocate_array(&a, 42); /* 'a'는 이제 길이 42의 배열이 되었으므로 여기서 조작하여 해방할 수 있습니다.*/ 공짜(a); 돌아가다 0; }
파라미터int **a_p
에 대한 포인터입니다.int
포인터의 주소입니다.p
이 경우 주요 함수에 정의됩니다.
배열 파라미터
어레이 유형의 함수 매개 변수는 언뜻 C의 값별 규칙에 대한 예외로 보일 수 있습니다.다음 프로그램은 1이 아닌 2를 인쇄합니다.
#실패하다 <stdio.h> 무효 setArray(인트 배열[], 인트 색인, 인트 가치) { 배열[색인] = 가치; } 인트 주된(무효) { 인트 a[1] = {1}; setArray(a, 0, 2); 인쇄물 ("a[0]=%d\n", a[0]); 돌아가다 0; }
그러나 이 동작에는 다른 이유가 있습니다.실제로 어레이 타입으로 선언된 함수 파라미터는 포인터로 선언된 파라미터와 동일하게 취급됩니다.즉, 이전 선언은setArray
는 다음과 같습니다.
무효 setArray(인트 *배열, 인트 색인, 인트 가치)
동시에 식에서 어레이를 사용하기 위한 C 규칙은 다음과 같은 값을 발생시킵니다.a
을 요구하여setArray
배열의 첫 번째 요소에 대한 포인터로 변환되다a
따라서 이는 실제로도 pass-by-value의 한 예이며 어레이의 내용이 아닌 값에 의해 전달되는 첫 번째 요소의 주소라는 점에 유의해야 합니다.
여러가지 종류의
예약 키워드
다음 단어는 예약되어 있으므로 식별자로 사용할 수 없습니다.
|
|
|
|
구현에서는 다음과 같은 다른 키워드를 예약할 수 있습니다.asm
단, 실장에서는 일반적으로1개 또는 2개의 밑줄로 시작하는 비표준 키워드가 제공됩니다.
대소문자의 구별
C 식별자는 대소문자를 구분합니다(예:foo
,FOO
,그리고.Foo
는 다양한 객체의 이름입니다).일부 링커는 외부 ID를 단일 케이스에 매핑할 수 있지만, 이는 대부분의 최신 링커에서는 드문 일입니다.
평.
토큰으로 시작하는 텍스트 /*
댓글로 처리되어 무시됩니다.코멘트는 다음에서 끝납니다.*/
; 표현식 내에서 발생할 수 있으며 여러 행에 걸쳐 발생할 수 있습니다.댓글 터미네이터를 실수로 누락하는 것은 문제가 있는데, 그 이유는 적절하게 구성된 다음 댓글 터미네이터를 사용하여 첫 번째 코멘트를 종료하고 댓글 사이에 있는 모든 코드를 댓글로 간주하기 때문이다.C스타일의 코멘트는 내포되지 않습니다.즉, 실수로 코멘트를 코멘트내에 배치하면, 의도하지 않은 결과가 됩니다.
/* 이 행은 무시됩니다. /* 여기서 컴파일러 경고가 발생할 수 있습니다.이러한 행도 무시됩니다. 위의 코멘트 오프닝 토큰은 새로운 코멘트를 시작하지 않았습니다. 그리고 다음 댓글 클로징 토큰은 1행에서 시작된 댓글을 닫습니다. */ 이것. 선 그리고. 그 선 아래 그것 할 것이다 것은 아니다. 있다 무시당했다. 둘다요. 할 것이다 할 것 같은 생산하다 컴파일하다 에러. */
C++ 스타일의 줄 코멘트는 다음과 같이 시작합니다.//
마지막까지 연장할 수 있습니다.이 코멘트 스타일은 BCPL에서 시작되어 C99에서 유효한 C 구문이 되었습니다.원래의 K&R C에서도 ANSI C에서도 사용할 수 없습니다.
// 이 행은 컴파일러에 의해 무시됩니다. /* 이 행들 무시당하다 컴파일러에 의한 */ x = *p/*q; /* 이 코멘트는 'p' 뒤에 시작합니다 */
명령줄 인수
명령줄에 지정된 파라미터는 2개의 사전 정의된 변수(의 명령줄 인수 수)와 함께 C 프로그램에 전달됩니다.argc
및 포인터 배열의 문자열로서 개개의 인수를 지정합니다.argv
명령어는 다음과 같습니다.
myFilt p1 p2 p3
다음과 같은 결과가 됩니다.
m | y | F | i | l | t | \0 | p | 1 | \0 | p | 2 | \0 | p | 3 | \0 |
argv[0] | argv[1] | argv[2] | argv[3] |
개별 문자열은 연속된 문자의 배열이지만 문자열이 연속된 그룹으로 저장된다는 보장은 없습니다.
프로그램 이름argv[0]
는 진단 메시지를 출력할 때 또는1개의 바이너리를 복수의 목적으로 사용할 때 도움이 됩니다.파라미터의 개개의 값은 다음과 같이 액세스 할 수 있습니다.argv[1]
,argv[2]
,그리고.argv[3]
(다음 프로그램에 나타나듯이)
#실패하다 <stdio.h> 인트 주된(인트 argc, 차 *argv[]) { 인쇄물("150c\t= %d\n", argc); 위해서 (인트 i = 0; i < > argc; i++) 인쇄물("v[%i]\t= %s\n", i, argv[i]); }
평가순서
합리적으로 복잡한 표현에서는 표현의 일부를 평가하는 순서에 대해 다음과 같은 선택지가 있습니다.(1+1)+(3+3)
순서대로 평가할 수 있다(1+1)+(3+3)
,(2)+(3+3)
,(2)+(6)
,(8)
또는 순서대로(1+1)+(3+3)
,(1+1)+(6)
,(2)+(6)
,(8)
형식적으로 C 컴파일러는 시퀀스 포인트 간에 임의의 순서로 식을 평가할 수 있습니다(이를 통해 컴파일러는 어느 정도 최적화를 수행할 수 있습니다).시퀀스 포인트는 다음과 같이 정의됩니다.
- 문은 세미콜론으로 끝납니다.
- 시퀀스 연산자: 쉼표.그러나 함수 인수를 구분하는 쉼표는 시퀀스 포인트가 아닙니다.
- 단락 연산자: 논리 및 (
&&
(읽고 나서 읽을 수 있습니다) 및 논리 또는 () - 삼원 연산자(
?:
): 이 연산자는 첫 번째 서브 표현식을 먼저 평가한 후 첫 번째 서브 표현식의 값을 기준으로 두 번째 또는 세 번째(둘 다 평가하지 않음)를 평가합니다. - 함수 호출에 대한 입력 및 종료(인수 평가 사이는 제외).
시퀀스 포인트 앞의 식은 항상 시퀀스 포인트 뒤의 식보다 먼저 평가됩니다.단락 평가의 경우 첫 번째 식의 결과에 따라 두 번째 식은 평가되지 않을 수 있습니다.예를 들어, 식에서(a() b())
첫 번째 인수가 0이 아닌 경우(true), 식 전체의 결과는 true 이외의 결과가 될 수 없습니다.b()
는 평가되지 않습니다.마찬가지로 다음 식에서(a() && b())
첫 번째 인수가 0(false)으로 평가될 경우 식 전체의 결과는 false가 될 수 없습니다.b()
는 평가되지 않습니다.
함수 호출에 대한 인수는 함수 입력 시간에 의해 모두 평가되는 한 임의의 순서로 평가할 수 있습니다.예를 들어 다음 식에서는 동작이 정의되지 않았습니다.
인쇄물(%s %s\n", argv[i = 0], argv[++i]);
정의되지 않은 동작
이 섹션은 어떠한 출처도 인용하지 않습니다.(2011년 11월 (이 및 을 확인) |
C 표준의 한 측면(C에 고유하지 않음)은 특정 코드의 동작이 "정의되지 않음"으로 간주된다는 것입니다.실제로, 이것은 이 코드에서 생성된 프로그램이 프로그래머의 의도대로 작동하는 것부터 실행될 때마다 크래시하는 것까지 모든 것을 할 수 있다는 것을 의미합니다.
예를 들어, 다음 코드는 변수 b가 여러 번 수정되고 시퀀스 포인트가 개입되지 않기 때문에 정의되지 않은 동작을 생성합니다.
#실패하다 <stdio.h> 인트 주된(무효) { 인트 b = 1; 인트 a = b++ + b++; 인쇄물(%d\n", a); }
"b++++"에서 b의 수정 사이에는 시퀀스 포인트가 없기 때문에 여러 순서로 평가 단계를 수행할 수 있어 애매한 문장이 발생한다.이 문제는 코드를 고쳐 시퀀스 포인트를 삽입함으로써 해결할 수 있습니다.다음은 예를 제시하겠습니다.
a = b++; a += b++;
「 」를 참조해 주세요.
- 블록(C 언어 확장자)
- C 프로그래밍 언어
- C 변수 유형 및 선언
- C 및 C++ 연산자
- C 표준 라이브러리
- C 패밀리 프로그래밍 언어 목록(C 영향을 받은 언어)
레퍼런스
- ^ a b 그
long long
C99 규격에서 수정자가 도입되었습니다. - ^ auto의 의미는 C++0x의 스토리지 클래스 지정자가 아닌 유형 지정자입니다.
- ^ a b c Klemens, Ben (2012). 21st Century C. O'Reilly Media. ISBN 978-1449327149.
- ^ Balagurusamy, E. Programming in ANSI C. Tata McGraw Hill. p. 366.
- ^ "The C Preprocessor: Implementation-defined behavior". gcc.gnu.org.
- ^ "String and character literals (C++)". Visual C++ 19 Documentation. Retrieved 20 November 2019.
- ^ UTF-8의 첫 번째 섹션을 참조해 주세요.
- ^ Kernighan & Richi
- ^ Tatham, Simon (2000). "Coroutines in C". Retrieved 2017-04-30.
- 일반
- Kernighan, Brian W.; Ritchie, Dennis M. (1988). The C Programming Language (2nd ed.). Upper Saddle River, New Jersey: Prentice Hall PTR. ISBN 0-13-110370-9.
- 미국 정보시스템 표준 - 프로그래밍 언어 - C - ANSI X3.159-1989