6. Derived data types

C에서 기본 자료형에서 파생되는 자료형은 크게 4종류가 있다. 집합 자료형인 배열과 구조체, 집합 자료형이 아닌 포인터와 공용체이다.

6.1. Arrays.

Takeaway 1.6.1.1. 배열은 포인터가 아니다.

6.1.1. Array declaration.

배열은 기본 자료형을 가진 오브젝트의 선언문 뒤에 []를 붙여 선언한다. 배열의 기본 자료형은 또 다시 배열일 수 있는데, 이를 다차원 배열이라 한다. 배열에는 지정 초기화자를 사용할 수 있다.

6.1.2. Array operations.

Takeaway 1.6.1.2. 조건문에서 배열의 값은 true이다.

Takeaway 1.6.1.3. 배열은 오브젝트로서 존재하나 오브젝트로의 평가값은 없다.

Takeaway 1.6.1.4. 배열끼리 비교될 수 없다.

Takeaway 1.6.1.5. 배열끼리 대입될 수 없다.

6.1.3. Array length.

배열에는 고정 길이 배열(FLA)가변 길이 배열(VLA)로 두 가지 종류가 있다.

Takeaway 1.6.1.6. 가변 길이 배열은 초기화자를 사용할 수 없다.

Takeaway 1.6.1.7. 가변 길이 배열은 함수 밖에서 선언될 수 없다.

Takeaway 1.6.1.8. 고정 길이 배열의 길이는 정수형 상수 표현식이나 초기화자에 의해 정해진다.

Takeaway 1.6.1.9. 배열 길이를 명시하는 식은 양수여야 한다.

다음은 고정 길이 배열로, 길이는 4가 된다.

double E[] = {[3] = 42.0, [2] = 37.0, };
double F[] = {22.0, 17.0, 1, 0.5, };

Takeaway 1.6.1.10. 길이가 정수형 상수 표현식으로 주어지지 않은 배열은 가변 길이 배열이다.

Takeaway 1.6.11. 배열 A의 길이는 (sizeof A) / (sizeof A[0]) 이다.

6.1.4. Arrays as pointers.

Takeaway 1.6.12. 배열이 함수 인자로 전달될 때 가장 안쪽의 크기 정보는 손실된다.

Takeaway 1.6.13. 함수 인자로 전달된 배열에 대해 sizeof 연산자를 쓰지 마라.

Takeaway 1.6.14. 배열 인자는 참조에 의한 전달것처럼 행동한다.

6.1.5. Strings are special.

Takeaway 1.6.15. 문자열은 0으로 끝나는 char형 배열이다.

다음은 모두 같은 문자열이다.

char jay0[] = "jay";
char jay1[] = {"jay"};
char jay2[] = {'j', 'a', 'y', 0};
char jay3[4] = {'j', 'a', 'y',};

다음은 문자열이 아니다.

char jay4[3] = {'j', 'a', 'y',};
char jay5[3] = "jay";

char형은 기본 문자 집합을 다루는 자료형이다.

char 배열에 적용될 수 있는 함수는 다음과 같다.

  • memcpy(target, source, len) source에서 target으로 len개의 문자를 복사한다. 두 배열은 달라야 한다.
  • memcmp(s0, s1, len) 두 배열을 길이 len만큼 사전순으로 비교한다.
  • memchr(s, c, len) 배열 s에서 문자 c를 찾는다.

다음은 문자열 함수이다.

  • strlen(s) 는 문자열 s의 길이를 구한다. 이는 배열의 길이가 아니라 0이 등장하는 첫번째 위치이다. s가 문자열이 아니라면 정의되지 않은 행동이 일어난다.
  • strcpy(target, source)는 문자열 source를 target에 복사한다. source는 문자열이어야 하며 target은 source의 복사본을 저장할 수 있을 만큼 커야 한다.
  • strcmp(s0, s1)은 두 배열을 사전순으로 비교한다. s0, s1은 모두 문자열이어야 한다.
  • strcoll(s0, s1)은 두 배열을 비교하는 것은 비슷하지만 언어에 따른 환경 설정을 고려한다.
  • strchr(s, c)는 s가 문자열이어야 한다는 조건이 추가된 memchr이다.
  • strspn(s0, s1)은 s0의 앞부분 중 s1에서도 등장하는 문자들로 이루어진 부분의 길이를 구한다.
  • strcspn(s0, s1)은 s0의 앞부분 중 s1에서 등장하지 않는 문자들로 이루어진 부분의 길이를 구한다.

Takeaway 1.6.1.16. 문자열 함수를 문자열이 아닌 배열에 사용하면 정의되지 않은 행동이 일어난다.

가장 흔한 버그는 다음과 같다.

  • strlen 등의 검색 함수를 문자열이 아닌 배열에 사용해 0을 찾지 못해 시간이 오래 걸리는 것
  • 함수가 배열 범위 밖의 원소에 접근해 세그멘테이션 결함이 일어나는 것
  • 함수가 배열 범위 밖의 원소에 쓰기를 해 데이터가 손상되는 것

6.2. Pointers as opaque types.

Takeaway 1.6.2.1. 포인터는 불명확 타입이다.

Takeaway 1.6.2.2. 포인터는 정상이거나, 널이거나, 부정형이다.

Takeaway 1.6.2.3. 포인터를 0으로 초기화하면 널 포인터가 된다.

Takeaway 1.6.2.4. 논리 표현식에서, 포인터는 널일 경우 false가 된다.

Takeaway 1.6.2.5. 부정형 포인터에 대한 접근은 정의되지 않은 행동이다.

Takeaway 1.6.2.6. 항상 포인터를 초기화하라.

6.3. Structures.

배열은 같은 기반 타입을 갖는 항목을 병합한다. 구조체는 같거나 다른 기반 타입을 갖는 항목을 병합한다. 구조체는 struct로 선언되며 각각의 항목은 멤버로 불린다. 각각의 멤버는 이름지어진다.

Takeaway 1.6.3.1. struct의 초기화자에서 초기화되지 않은 멤버는 0으로 초기화된다.

Takeaway 1.6.3.2. struct의 초기화자는 최소 하나의 멤버를 초기화해야 한다.

Takeaway 1.6.3.3. struct 인자는 값으로 전달된다.

Takeaway 1.6.3.4. 구조체는 대입될 수 있으나 비교될 수는 없다.

Takeaway 1.6.3.5. 구조체 레이아웃은 중요한 설계 결정이다.

Takeaway 1.6.3.6. 중첩 선언에서의 모든 struct 선언은 같은 가시 범위를 가진다.

6.4. New names for types: type aliases.

구조체의 이름은 언제나 struct를 같이 써 줘야 하므로 매우 귀찮다. 이를 방지하기 위해 typedef로 별칭을 써 준다. 심지어 이 때의 별칭이 struct 선언 시 썼던 태그명과 같아도 된다.

typedef struct bird bird_t;
typedef struct bird bird;
struct bird {
};

구조체 선언 앞에 전방 선언으로 쓰는 방법이 많이 쓰인다.

Takeaway 1.6.4.1. typedef 내의 struct를 같은 태그 네임을 갖는 식별자로 전방 선언하라.

Takeaway 1.6.4.2. typedef는 타입의 별칭을 만들 뿐, 새로운 타입을 만들지 않는다.

Takeaway 1.6.4.3. _t로 끝나는 식별자는 예약되어 있다.

요점 정리

  • 배열은 같은 자료형을 갖는 여러 값을 하나의 오브젝트로 병합한다.
  • 포인터는 다른 오브젝트를 참조하거나, 널이거나, 부정형이다.
  • 구조체는 서로 다른 자료형을 갖는 여러 값을 하나의 오브젝트로 병합한다.
  • typedef는 존재하는 타입에 대한 새로운 이름을 준다.

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google photo

Google의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중