1. 배열
배열이란 연속적인 항목들이 동일한 크기의 순서를 갖고 나열되어 있는 데이터의 집합이다.
2. 변수와 배열
변수를 단독주택이라고 표현을 한다면 배열은 같은 평수로 구성된 아파트라고 표현할 수 있다.
변수는 int x; 라고 쓰면 4byte짜리 단독주택 1가구라고 볼 수 있고 배열은 int x[5]; 라고 쓰기 때문에 4byte짜리 5가구라고 볼 수 있다.
3. 일차원 배열
배열명 다음에 구두점 대괄호 []를 쓰며 대괄호 안에 배열의 크기를 나타내는 수를 하나 쓴다.
-자료형 배열명[첨자];
배열명 만드는 규칙은 변수명 만드는 규칙과 동일하다. 배열 선언문에서 사용하는 첨자는 양의 정수이며 배열의 크기이다.
score배열은 정수형 자료 7개를 저장할 수 있다. 7개의 공간을 배열의 배열의 원소(element)라고 한다.
4. 배열의 원소
5. 일차원 배열 초기화
일차원 배열의 초기화 방법
int score[5]={10, 20, 30, 40, 50}; //변수 초기화 int x=10;
변수 초기화와 달리 원소가 많으므로 중괄호 {}로 묶어준다. score[0]에는 10이, score[1]에는 20등이 차례대로 초기화된다.
문자형 배열 초기화 방법
char name[ ]={'C','h','o',' ',S',' ','H','\0'};
배열 선언과 함께 초기화까지 할 경우 원소의 개수 8은 생략 가능하다.
문자 배열의 마지막 원소는 반드시 널(NULL)문자인 '\0를 추가해야 한다. 문자형 배열은 문자열과 관련이 있는데 C언어에서 문자열은 항상 널 문자로 끝나기 때문이다.
문자 배열은 문자열 형태로 초기화 가능
char name[ ]="Cho S H";
널 문자가 자동으로 마지막 원소에 할당된다. 이 배열의 원소의 개수는 8개이다.
(*주의* char name[7]="Cho S H"; //널 문자가 저장이 안 되므로 제대로 된 문자열이 아니다.)
6. 배열의 초기화 방법
배열 원소가 초기화 데이터 수보다 많으면 나머지 원소들은 0으로 초기화된다. 100개의 원소를 갖는 배열을 2개만 초기화하면 나머지 98개는 모두 0으로 자동 초기화된다.
-int cho[100]={10,20}
배열 원소의 수가 초기화한 데이터 수보다 적으면 "초기화 데이터가 너무 많다"는 에러가 발생
-int cho[2]={10,20,30} //이 경우 에러가 발생
배열을 선언과 동시에 초기화한 경우와 선언 먼저하고 값을 대입한 경우인데 각 원소에는 같은 값이 할당된다.
-int cho[3]={10,20,30}; // 배열 선언과 초기화
-int cho[3]; // 배열 선언
cho[0]=10; // 대입
cho[1]=20; // 대입
cho[2]=30; // 대입
7. 다차원 배열
다차원 배열은 2차원 배열, 3차원 배열 등 n차원 배열이 가능하다. 일반적으로 3차원 이상의 배열은 이해하기 어려워서 잘 사용하진 않는다.
-int x[3]; // 1차원 배열 -int x[4][3]; // 2차원 배열, int x[3]이 4개 -int x[5][4][3]; //3차원 배열, intx[4][3]이 5개 |
2차원 배열 x의 초기화 방법은 두 가지 방법이 있다.
-int x[3][2]={1,2,3,4,5,6}; -int x[3][2]={{1,2}, {3,4} {5,6}}; |
2차원 배열도 물리적으로는 1차원적으로 저장한다. 배열의 전체 크기는 선언시 사용한 첨자를 곱(3x2)하면 되고 마지막 원소는 x[3][2]가 아니라 x[2][1]인 것을 주의!
8. 문자형 배열
문자열은 문자형 배열에 두 가지 방법으로 초기화할 수 있다.
-char eng[4]={'A','B','C','\0'} //문자의 모임 -char eng[4]="ABC"; //문자열 |
문자열 상수에서는 문자열 끝을 의미하는 널 문자가 제일 뒤에 자동적으로 붙여진다. 'a'는 문자로 1바이트에 저장되고, "a"는 문자열로 뒤에 널 문자가 있으므로 2바이트에 저장된다.
9. 구조체
구조체는 다른 형(type)의 데이터들을 하나의 단위로 취급한다. 예를 들어 프로그램을 만들 때 이름과 나이와 몸무게를 사용하게 된다면 이 3가지를 따로따로 사용하는 것보단 일반적으로는 다 같이 사용하는 경우가 많기 때문에 하나의 묶음으로 만들어서 사용한다
(*h를 j에 대입하면 h의 모든 멤버가 복사된다)
10. 포인터
포인터는 C언어를 다른 언어와 차별화시키는 가장 큰 특징이다. 포인터를 이용하게 되면 기계어나 어셈블리 언어처럼 메모리의 주소를 이용해 메모리의 내용을 직접 접근할 수 있다. 포인터가 사용되는 경우는 call by reference로 함수로부터 한 개 이상의 값을 리턴할 때, 함수들 간에 배열이나 문자열을 전달할 때, 배열 조작을 쉽게 할 때, 연결 리스트(linked list)나 이진 트리(binary tree)등 복잡한 자료 구조를 만들 때, 메모리를 동적으로 할당할 때 사용된다.
11. 포인터의 주소
메모리에는 위치를 구분하기 위해 순서대로 번호가 붙어있는데 이것을 메모리 주소, 번지, address라 한다.
메모리의 주소를 저장하려면 일반 변수가 아닌 포인터를 사용한다. (포인터라고만 해도 되지만 주소를 저장하는 변수이므로 포인터 변수라고도 한다.)
12. 포인터 선언
포인터도 변수이므로 사용하기 전에 선언해야 한다. 자료형과 변수명 사이에 구두점 *를 더 쓰면 된다. 선언문에서 쓰는 *는 곱하기 연산자와 전혀 관계없는 구두점이다. *는 자료형과 변수병 사이 아무 곳이나 있어도 된다.
-intx; //일반 변수 x의 선언 -int *x; //포인터 (변수) x의 선언 -int* px; //포인터 px의 선언 -int *px, y; //px만 포인터, y는 일반 변수 -int*px,*py; //px, py 둘 다 포인터 |
*는 자료형과 변수병 사이 아무 곳이나 있어도 된다.
-int* px; //선언문에서 쓰는 *는 구두점으로 포인터를 선언 -int * px; -int *px; //이 책에서 주로 사용하는 방법 |
13. 참조 연산자*
포인터에 주소를 대입하는 방법
int x=10; //일반 변수 x의 선언과 초기화 int *px; //포인터 변수 px선언 int=&x; //포인터 px에 변수 x의 주소 대입 |
포인터는 일반적으로 일반 변수명 앞애 주소 연산자(&)를 사용하여 해당 변수의 주소를 저장한다.
px가 저장하고 있는 x의 즈소로 가서 그 값인 10을 변수 y에 대입하려면
y=*px;
(실행문에서 사용하는 *는 참조 연산자, 포인터의 주소로 가서 값을 가져온다.)
와 같이 하면 된다.
14. C언어에서 *(구두점 vs. 연산자)
선언문: 포인터를 선언(구두점)할 때
실행문: 주소로 가서 값을 가져올 때(연산자)
*이 선언문에서 사용되는지 실행문에서 사용되는지에 따라서 다르다.
실행문에서 *는 포인터 변수에 저장된 주소로 가서 실제 데이터 값을 가져오는데 사용하는 참조 연산자로 간접 값(indirect value) 연산자, dereferencing연산자라고도 한다.
px에 저장된 주소(&x)로 가서 값(x의 내용)을 가져오므로 y에는 10이 대입됨
*px=20; //x=20;
(포인터 px가 가리키는 주소에 20을 대입, px가 x의 주소를 가지고 있으므로 변수 x의 값도 바뀜, 주소로 가서 값을 바꾸는 간접적인 방법으로 변경)
'C언어' 카테고리의 다른 글
[C언어] 함수, 기억클래스 (0) | 2022.06.02 |
---|---|
[C언어] 제어문, 함수 (0) | 2022.05.27 |
[C언어] 제어문 (2) (0) | 2022.05.19 |
[C언어] 제어문 (1) (0) | 2022.05.15 |