[C언어-막코딩] 17장 배열
kr-dev·@codingman·
0.000 HBD[C언어-막코딩] 17장 배열
# [C언어-막코딩] 17장 배열 ----- - 다운 사이트 : https://sourceforge.net/projects/orwelldevcpp/ - 웹컴파일러 : https://www.tutorialspoint.com/compile_c_online.php ----- 오늘의 주제는 배열에 대해 이야기를 하도록 하겠습니다. 지난 시간에 배운 자료형 변수는 단일 변수에 대해서 이야기 했는데 오늘은 좀 더 확장된 개념으로 보시면 됩니다. 자료형 변수에서 단일 변수로 하나의 값을 담는 변수라면 배열변수는 여러개의 값을 저장 할 수 있는 변수입니다. 그러면 이 배열 변수에 대해 알아보도록 하죠. ## 1. 배열 변수 ----- <center>  </center> 위 그림은 단일 변수와 배열 변수를 표현한 것입니다. 단일 변수는 하나의 값만 담을 수 있는 변수를 말하고 배열 변수는 여러개의 값을 담을 수 있는 변수를 말합니다. 배열 변수의 표현은 다음과 같습니다. ``` int a[6]; int a[6] = {1,2,3,4,5,6}; int a[]; = {1,2,3,4,5,6}; ``` a라는 배열 변수를 선언하고 저장공간을 마련하거나 선언과 동시에 값을 넣은 방법으로 나뉩니다. 참고로 a[6]으로 해서 6개의 데이터를 넣는 다고 직접적으로 표현하는 방법도 있지만 a[]의 표현하고 6개의 데이터를 선언 때 집어 넣으면 배열 6이라는 숫자를 생략 가능합니다. 2차 배열에서는 ``` int a[2][3]; = {{1,2,3},{4,5,6}}; int a[][3]; = {{1,2,3},{4,5,6}}; ``` 위와 같이 표현 할 수 있습니다. 단, 이경우는 에러가 발생합니다. ``` int a[2][]; = {{1,2,3},{4,5,6}}; int a[][]; = {{1,2,3},{4,5,6}}; ``` 쪼개는 위치가 명확하지 않기 때문에 나눌 수 없어 잘못된 표현입니다. a[][3]이라고 하면 쪼개는 위치는 3개씩 쪼개기 때문에 6개의 데이터에서 3개씩 쪼개지고 a[2][3]의 배열 공간에 저장되기 때문에 정상적인 표현입니다. 정말 안되는지 확인하고 싶은 분들은 잘못된 표현을 코딩해서 실행 시켜보세요. 말보다는 눈으로 확인하시는게 가장 빠르죠. ### 배열의 표현 ----- 배열의 표현은 다음과 같습니다. <center>  </center> a[6]이라는 6개의 저장공간을 갖는 배열 변수가 선언되면 위와 같이 6개의 데이터가 저장 할 수 있게 됩니다. 참고로 배열의 index(위치)은 0번째 위치에서 부터 데이터를 저장합니다. 저장 공간은 0~6까지 총 7개의 저장공간이 있지만 마지막 6번째의 위치에는 저장을 하지 않습니다. 참고로 비주얼베이직의 경우는 a[6]으로 선언하면 0~6번째까지 해서 총 7개의 데이터를 저장 할 수 있는데 통상 a[6]하면 6개의 데이터만 저장하지 7개의 데이터를 저장하지 않습니다. ### 재밌는 혼동 ----- 과거 공무원 시험이나 컴퓨터 관련 자격증 시험에서 단골 문제로 출제되는 배열문제가 떠오르네요. 배열 변수에서 2번째의 값이 무엇입니까?일때 우리는 2번째란 글자의 의미를 햇갈려 합니다. 지문의 2번째가 a[2]인지 아니면 a[1]인지 명확하게 정의 할 수 없습니다. 출제 위원의 마음에 따라 a[2]가 될 수 있고 a[1]이 될 수 있습니다. ``` int a[6] ={1,2,3,4,5,6} ``` 여기서, 두번째 값은 무엇일까요? 두번째이니 2가 답이겠죠. 하시는 분이 있습니다. 지문이 애매하게 써있다면 해당 두번째가 순수하게 a[2]를 가르킬 수 있습니다. 0번째부터 시작하기 때문에 2번째란 a[2]가 되고 값이 3이 될 수 있습니다. 위치를 가리키는 경우 배열에서 출제자가 위치에 대한 정의를 명확하게 내려놓지 않으면 두번째란 위치가 a[1] or a[2]가 될 수 있어 선택 답이 2 or 3이 있으면 2도 답이 되고 3도 답이 되어 종종 논란거리가 되는 문제였습니다. 즉, 첫번째가 0번째인가에 따라 답이 달라지기기 때문이죠. 삼천포로 이야기가 빠졌지만 다시 본론으로 이야기 하겠습니다. <center>  </center> 1차 선형 배열과 2차 평면 배열과 3차 공간 배열로 표현 할 수 있습니다. 위 그림과 같이 저장 공간의 이미지화 모습으로 느낌을 잘 이해하시기 바랍니다. 이 느낌을 일상에서 모습으로 생각 해 볼까요. 이름을 저장한다. 이름은 한글자인 경우는 없죠. 제 아디를 보면 codingman이라는 9개의 문자열로 구성된 이름입니다. ``` char name[10] = "codingman"; ``` 9개의 문자를 하나의 변수이름으로 저장할 수 있게 됩니다. 어느 때 사용하는지 느낌 아시겠지요. 여기서, 여러명의 아디를 등록한다면 어떻게 될까요. ``` char name[3][10]= {"codingman","aaa","bbb"}; ``` 아디의 최대 글자는 10개로 제한을 두고 3명의 아디를 저장 하였습니다. 배열의 느낌을 아셨는지요. 다른예로 살펴 볼까요. raw255*255 영상 이미지를 예로 들어 봅시다. ``` unsigned char val[255][255]; ``` 이미지는 각 픽셀로 구성 된 평면입니다. 위에서 2차 배열로 위와 같이 배열 변수를 선언하고 raw 영상 이미지를 읽어와서 val에 저장하여 이미지 처리를 하게 됩니다. 우리가 컴퓨터 화면에서 출력되는 평면 이미지는 바로 이렇게 영상데이터를 읽어와서 배열 변수에 넣고 다시 모니터 화면에 시각화하여 보여지게 됩니다. 해상도 수치가 배열 변수의 저장공간이라 생각하고 머리속으로 평면 2차 배열을 그려 보세요. 배열의 느낌을 아셨다면 다음으로 넘어 갑시다. ### 배열과 for문는 한쌍이다. ----- 배열 변수가 선언되면 무조건 for문이 그 다음에 나온다고 생각 하시면 됩니다. 배열은 어떤 값들을 일정한 규칙으로 저장됩니다. 그렇기 때문에 일정한 순서대로 저장된 값을을 처리하게 됩니다. 일정한 값들은 일전한 반복 처리가 이루어지기 때문에 일정한 반복은 바로 for문이다라고 생각하시면 됩니다. ``` int a[6]; int i; for(i=0;i<6;i++){ a[i]=i+1; } ``` 위 코딩을 자세히 보시면 a[6]이라는 배열 변수가 선언 되었고 배열 변수에는 아직 값이 정해져 있지 않습니다. for문을 통해 1~6이라는 값이 순차적으로 a[i] 배열 위치에 값이 저장되는 코딩입니다. 이처럼 배열변수는 어떤 값을 집어 넣을 때 for문을 통해 순차적으로 지정하고 값을 저장하게 됩니다. 위의 코딩은 처리 값을 배열 공간에 입력하는 코딩이지만 출력할 때도 사용합니다. ``` int a[6]={1,2,3,4,5,6}; int i; for(i=0;i<6;i++){ printf("i=%d \n",a[i]); } ``` 이처럼 배열의 값을 출력 할 때도 for문을 사용합니다. 처리 할 때도 for문을 사용합니다. ``` int a[6]={1,2,3,4,5,6}; int b[6]; int i; for(i=0;i<6;i++){ b[i]=i+a[i]; } ``` 이렇게 a[i] 배열을 읽어와서 b[i]에 저장하는 처리문에도 for문이 사용 됩니다. 이처럼 배열이 나오면 무조건 for문을 사용한다고 생각하시면 됩니다. 1차 배열만 설명했는데 2차 배열은 어떻게 접근 할까요. ``` int a[3][3]; for(i=0;i<3;i++){ for(j=0;j<3;j++){ a[i][j]=i+j; } } ``` 이렇게 2중 for문을 사용합니다. 3차 배열은 3중 for문을 사용하겠죠. 이제 for문을 코딩하여 실행 시켜봐야 배열을 쉽게 이해할 수 있겠죠. ## 2. 코딩 ----- 아래 소스는 배열의 표현을 하나로 묶어서 만들었습니다. 코딩의 의미는 없지만 배열의 표현만 담아낸 것으로 코딩의 각 라인의 처리하는 과정을 잘 이해하시기 바랍니다. **[소스]** ``` #include <stdio.h> int main(int argc, char *argv[]) { int a[6]={1,2,3,4,5,6}; int b[6]; int i; char name[3][10]= {"codingman","aaa","abc"}; for(i=0;i<6;i++){ b[i]=a[i]+i; } for(i=0;i<6;i++){ printf("a[%d]=%d, b[%d]=%d \n",i, a[i],i,b[i]); } printf("%s \n",name[0]); printf("%s \n",name[1]); printf("%c \n",name[2][1]); return 0; } ``` 우선 int형의 a[6], b[6]배열 변수의 표현은 어렵지 않을 거에요. 각 i라는 위치의 공간에 하나의 값이 저장되기 때문에 각 위치별 저장된 값을 불러오과 저장하는 과정은 복잡하지 않을거에요. 하지만 문자의 경우에서는 위 표현이 이해가 잘 안될 수 있을 거에요. 2차 배열인데 출력 할 때 보면 1차배열로 표현하거나 2차 배열로 문자 배열 변수를 표현하여 출력하고 또 문자열 서식문자도 %s or %c로 표현하기 때문에 햇갈리 실 수 있을 거에요. 가단히 설명하자면 name[3][10]이라는 2차 문자열 배열이 있습니다. 최대 10글자씩 해서 3개의 문자열을 저장하는 배열 변수입니다. 여기까지는 이해 하셨죠. name[0] name[1] name[2] 위 표현은 뒤에 [10]이라는 값이 생략되에 있습니다. 위 표현은 name[0]는 저장 된 주소의 위치를 가리킵니다. 문자열의 범위는 NULL문자가 나올때까지 인데 그러면 name[0]은 "codingman"이라는 범위를 가리킬 수 있습니다. ``` printf("%s \n",name[0]); ``` 그래서, 위와 같이 name[0]은 첫번째 문자의 주소를 가리키고 %s로 문자열 서석문자로 name[0]의 주소에서 부터 NULL문자까지이니 "codingman"이 출력 됩니다. 또, name[1]은 두번째 문자열의 첫번째 주소 위치를 가리키고 name[1]의 문자열을 출력하면 "aaa"가 출력 되겠죠. 위의 경우는 문자열을 통채로 출력 할 때의 표현이고 문자열이 아닌 각 알파벳으로 출력 할 때는 아래와 같이 표현합니다. ``` printf("%c \n",name[2][1]); ``` name[2]은 3번째 문자열이고 뒤에 [1]은 두번째 위치의 알파벳을 가리키게 됩니다. [2][1]의 위치의 알파벳을 %c라는 단일 서식문자로 출력하여 해당 알파벳인 'b'가 출력 됩니다. **[결과]**  ## 마무리 ----- 배열에 대해 간단히 살펴 보았는데 코딩 부분에서 실행 했을 때 출력 결과를 잘 보시고 왜 이렇게 결과가 나왔는지에 대해 의미를 잘 이해하셔야 합니다. 무척 중요합니다. 그리고 for문을 이용한 입력, 처리, 출력을 위 코딩을 기준으로 변형시켜서 다양한 실험을 하시기 바랍니다. 그리고 문자열 출력에서도 수정을 해보시면서 다향한 형태로 출력을 해보세요. --- ##### <sub> **Sponsored ( Powered by [dclick](https://www.dclick.io) )** </sub> [](https://api.dclick.io/v1/c?x=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjIjoiY29kaW5nbWFuIiwicyI6ImMtMTctLTE1NTUwMjc5MjI1NDIiLCJhIjpbImktMTk1Il0sInVybCI6Imh0dHBzOi8vd3d3LmRjbGljay5pby9tb25ldGl6ZSIsImlhdCI6MTU1NTAyNzkyMiwiZXhwIjoxODcwMzg3OTIyfQ.QpGPMWhw29MK4RkQfcOCEjU3zsvIZSB0uDUXmosGBjQ)