컴퓨터 프로그래밍/C

C언어 1차원 배열 / 문자열 배열 / 배열(포인터 연산)

나노콛 2019. 7. 23. 11:16

배열 선언

 

int array[5] = {0};

array[0] = 1;
array[1] = 2;
array[2] = 3;
array[3] = 4;
array[4] = 5;

배열은 같은 형태의 데이터를 말합니다.
하나의 변수명으로 여러 개의 변수를 표현할 수 있습니다.

배열 선언 시 주의사항
배열 선언 시 배열의 크기는
상수만 입력 가능하며 변수는 불가능합니다.

 

int index=10;
int array[index];

위처럼 쓸 수 없습니다.
단 선언 이후에는 배열 크기에 변수를 사용할 수 있습니다.

선언 시 배열 크기는 5이지만
실제 배열에게 접근하려면 0부터 4까지 접근이 가능합니다.

배열 이름의 특징
1. 배열 이름은 저장공간이 아니다.
2. 배열 이름은 배열의 시작 주소이다.(array[0])

 

 


문자 배열(문자열 배열)

문자열을 표현하기 위해서는 char형을 이용합니다.
문자열 끝에는 null 값(\0)이 자동으로 추가되어있습니다.
그래서 배열의 크기는 필요한 문자 수에서 +1이 됩니다.(null 값이 들어갈 공간)

char array[5] = "Test";  //문자열은 ""를 이용해서
char array1[] = "test";  //배열 크기를 설정하지 않으면 초기화 값에따라 자동 설정
char array2[5] = { 'T','e','s','t' }; // 문자 하나하나를 이렇게 초기화 가능
char array3[] = { 'T','e','s','t','\0' }; // 널문자를 직접 넣을 수 있다.

이 변수들에게 접근하려면

array[0] //T
array1[0] //t
array2[0] //T
array3[0] //T

모두 똑같이 사용이 가능합니다.


#include <stdio.h>
int main()
{
	int array[4] = { 0, 1, 2, 3 };
	char carray[4] = { 'a','b','c' };

	printf("&array = 0x%X \n", array);
	printf("array[0] = %d &array[0] = 0x%X\n", array[0], &array[0]);
	printf("array[1] = %d &array[1] = 0x%X\n", array[1], &array[1]);
	printf("array[2] = %d &array[2] = 0x%X\n", array[2], &array[2]);
	printf("array[3] = %d &array[3] = 0x%X\n", array[3], &array[3]);

	printf("&carray = 0x%X \n", carray);
	printf("carray[0] = %d &carray[0] = 0x%X\n", carray[0], &carray[0]);
	printf("carray[1] = %d &carray[1] = 0x%X\n", carray[1], &carray[1]);
	printf("carray[2] = %d &carray[2] = 0x%X\n", carray[2], &carray[2]);
	printf("carray[3] = %d &carray[3] = 0x%X\n", carray[3], &carray[3]);

	printf("carray = %s\n", carray);
	return 0;
}

여기서 확인할 수 있는 것은
array의 주소와
array[0] 주소가 같다는 점

주소의 값 차이가 array는 4씩
carray는 1씩 차이 난다는 점

array는 int형 배열이라서 각각의 배열 인덱스마다 4바이트씩 할당되어 있다는 것을 알 수 있고
carray는 char형 배열이라서 1바이트씩 할당되어 있습니다.

또한 carray[3] 의 값은 정수 형태로 출력 시 0이 나온다는 건데요 이것은 널 문자를 뜻합니다.

마지막으로 서식 문자 %s는 문자열을 출력하는 서식 문자이지만
사실은 처음 주소부터 날 문자까지 출력한다는 의미를 갖고 있습니다.


배열(포인터)

배열은 주소를 갖고 있다는 것을 확인했습니다.

int array[5] = {1,2,3,4,5};
int* ptr = array; // array는 주소이기 때문에 &를 쓸필요 없다.

배열의 주소를 포인터 변수에 가리키게 하고
각각의 값에 접근하는 방법을 알아보겠습니다.

 

포인터 연산

 

array[0]   array[1]   array[2]   array[3]   array[4] 
*(ptr+0)   *(ptr+1)   *(ptr+2)   *(ptr+3)   *(ptr+4)
 ptr[0]     ptr[1]      ptr[2]     ptr[3]     ptr[4]
*(array+0) *(array+1) *(array+2) *(array+3) *(array+4)

배열을 포인터처럼 포인터를 배열처럼 이렇게 각각의 값에 접근이 가능합니다.
그러나 포인터 연산을 할 때 주의할 점은
array의 주소가 1000번지라고 할 때
ptr이 1000번지를 가리키는 상황입니다.
ptr+0은 1000번지 곧 처음 인덱스의 값에 접근을 할 수 있습니다.
ptr+1은 1001번지의 값에 접근을 하는 게 아닙니다.

해당 주소의 자료형에 따라 자료형 할당 데이터 값이 더해집니다.
ptr+1은 int형 포인터이기 때문에 4바이트씩 증가합니다. 
포인터 연산에서는 ptr+1 이 1004 번지를 가리키게 되는 것입니다.
double의 포인터였다면 1008번지가 되었을 것입니다.

728x90