for문에 해당하는 글 1

[아두이노] 아두이노 코딩 배열과 FOR문

IOT/아두이노기초문법|2019. 4. 12. 09:00

[아두이노] 아두이노 코딩 배열과 FOR문



오늘은 제어문 중에 FOR문에 대해 설명하고자 합니다. FOR문을 들어가기 전에 배열에 대해서 살펴보고 FOR문을 다룰 예정입니다. 배열를 먼저 다루는 이유는 FOR문 한쌍을 이루고 있으면 같이 배우면 이해하기 쉽기 때문입니다. 배열와 FOR문은 한쌍을 이룬다고 생각하시면 됩니다. 1차배열은 FOR문 한개, 2차배열은 FOR문 2개, 3차배열은 FOR문 3개로 표현이 되는데 이게 무슨 소리인지 아직 모를 수 있으나 대충 배열과 FOR문의 갯수는 같구나 정도만 생각하시고 이제 본격적으로 포스팅 하겠습니다.

1. 배열변수


지난 시간에 변수 선언은 어떻게 했나요.

int a = 10;

a라는 변수를 int형으로 선언했고 a변수에 10을 저장했습니다. 대충 이렇게 변수를 선언 했습니다. 이것을 단일변수라고 부릅니다.

그러면, 배열변수는 a라는 변수명을 갖는 것 까지는 단일변수와 같은데 차이점은 여러개의 저장공간을 하나의 변수명으로 갖을때 이 변수를 배열변수라고 부릅니다. 즉, a변수에 여러개의 값을 저장할 수 있다는 것이죠.

[ 표현식 ]


A[6]는 A라는 변수명을 가지고 6개의 저장공간을 가지고 있다는 의미가 됩니다. A[6] 배열변수에는 순서대로 "10, 20, 30, 40, 50, 60"이라는 값들이 저장하게 됩니다. 선언하면서 값이 저장될 경우 숫자인 경우는 중괄호({ })를 사용하여 위와 같이 표현 합니다. 참고로 C언에서는 첫번째 위치가 0부터 시작합니다. 그리고 A[6]으로 표현했다고 해서 0부터 시작하니깐 7개의 저장공간이 있겠구나 생각하실 수 있는데 공간은 있는게 맞지만 마지막 7번째 저장소는 사용되지 않습니다. 배열을 선언하시면 A[7]하면 7개의 저장소를 갖는데 "0~6"의 위치(index)에 값을 저장한다고만 머리속에 담아 두시면 됩니다.

여기서, 배열변수의 각 저장소 접근은 다음과 같은 방법으로 접근하게 됩니다. 배열변수에 위치(index) 값으로 배열의 위치를 지정하고 그 위치에 저장된 값을 가리키게 됩니다.

** A[index] => ?**

실제로 접근해보면,

A[0] => 10
A[1] => 20
A[2] => 30
A[3] => 40
A[4] => 50
A[5] => 60

어떻게 배열변수가 선언되고 접근되는지 아시겠지요. 시리얼모니터로 출력을 한번 해볼까요.

[ 소스 ]

void setup()
{
  Serial.begin(9600);
  
  int A[6] = {10,20,30,40,50,60};
  Serial.println(A[0]);
  Serial.println(A[1]);
  Serial.println(A[2]);
  Serial.println(A[3]);
  Serial.println(A[4]);
  Serial.println(A[5]);
}

[ 결과 ]


배열변수를 선언하고 그안에 값을 넣고 다시 그 배열변수에 저장된 값을 출력을 하였습니다. 여기까지 배열변수의 선언과 출력을 어떻게 하는지 이해 하셨죠.

그런데 자세히 살펴보세요. Serial.println()함수가 6번 반복됩니다. 만약에 배열변수에 100개 아니 1000개의 데이터가 있다면 1000개의 println()문을 코딩해야 겠죠. 정말 비효율적인 코딩이겠죠. 이 문제를 해결하기 위한 제어문이 있습니다. 배열변수가 표현되면 한쌍을 이룬다는 제어문이 있는데 그게 바로 FOR문입니다.

이제 FOR문에 대해서 본격적으로 다뤄보겠습니다.

2. FOR 문



위와 같은 형식으로 표현이 되는데 시작값은 i=0부터 조건식(i<6)이 참이 될때까지 반복 수행 한다고 생각하시면 됩니다. 좀 햇갈릴 수 있는데 다음 표현으로 이해해 주세요.


번호 순서대로 진행되는데 1번 i=0에서 시작해서 2번 조건식(i<6)이 참이면 아래 수행문 3번을 수행합니다. 그리고 나서 4번 i++ 증감연산으로 i=i+1의 표현인데 1씩 증가한다고 생각하시면 됩니다. i가 1이 증가된 값에서 다시 2번 조건식으로 참인지 거짓인지 비교하게 됩니다. 이렇게 "i<6"이 거짓이 될때까지 수행문은 반복한다고 생각하시면 됩니다.

잘 이해가 안 갈 수 있으니 예제로 들어 설명할께요. 위 소스에서 Serial.println()문이 6번 반복된다고 했잖아요. for문으로 표현을 하면 다음과 같습니다.

[ 소스 ]

void setup()
{
  Serial.begin(9600);
  
  int A[6] = {10,20,30,40,50,60};
  
  for(int i=0;i<6;i++){
    Serial.println(A[i]);    
  }
}

i는 0부터 조건식(i<6)이 참이 될 때 까지 Serial.println()함수를 반복 수행하는 코딩입니다. 여기서 A[i]라는 표현을 잘 기억해 주세요. for문은 i가 0부터 1,2,3,4,5까지 반복 수행 합니다. 그럴 때 A[i]로 표현하면은 i의 값은 0부터 1,2,3,4,5가 되겠죠.

A[i] => A[0], A[1], A[2], A[3], A[4], A[5]

A[i]은 위에서 표현한 것처럼 순서대로 가리키게 됩니다. 이 표현이 가장 중요합니다. for문을 돌리는 핵심이고요.

배열 변수 A[10]이면,

for(int i=0;i<10;i++){
    A[i]
}

이렇게 기계적으로 나와야 합니다.

2차배열변수 A[5][5]이면

for(int j=0;j<5;j++){
    for(int i=0;i<5;i++){
        A[j][i]
    }
}

이렇게 기계적으로 나와야 합니다. 배열변수이면 for문은 저렇게 기본적으로 표현한다고 생각하시면 됩니다.

위 소스에서

  for(int i=0;i<6;i++){
    Serial.println(A[i]);    
  }

이 표현을 아시겠지요. 혹시 모르시겠다면 다음 순서도를 보시기 바랍니다.


시작 하면 i=0으로 초기값이 정해지고 조건식 i<6보다 작으면 참(True)일때 아래 Serial.println()문이 수행되고 i++로 i가 1이 증가합니다. 파란색 화살표 방향으로 참일때 계속 반복 수행 됩니다. 그러다가 i가 6일 때 거짓(False)이 되면 for문을 빠져나와 종료가 됩니다.

순서도의 진행 과정을 머리속에서 그려 보세요. For문의 진행과정이니깐 꼭 숙지해 주세요.

[ 결과 ]


이제 for문이 어떻게 돌아가는지 이해가 되셨겠죠.

3. FOR문을 언제 사용할까요.


기본적으로 배열변수가 있을 때 배열변수의 위치(index)를 순서대로 접근을 할 때 사용합니다. 그리고 순서가 있는 중복되는 코딩이 있을때 for문을 사용하여 중복된 코드 부분을 줄이고자 사용합니다.

예를 들어 아두이노에서 단일변수에 저장된 값을 bit단위로 추출하고자 할때를 생각해 봅시다. p라는 단일 변수에 저장된 8bit로 구성된 1byte 값을 bitRead(입력값, 추출위치)로 1bit씩 추출이 가능한 함수입니다. 이 함수를 이용해서 총 8bit로 이루어진 1byte 데이터를 1bit씩 추출하기 위해서는 bitRead()함수가 8번 중복이 되겠죠. 이 중복된 명령을 for문으로 표현하면 다음과 같이 간단히 표현 됩니다.

const byte p=0B01110000;
for(int i=0;i<8;i++){
     bitRead(p, i);
}

[ 결과 ]


추출한 결과를 println()함수로 순서대로 출력되었네요.

간단히 정리하자면 for문은 일정한 순서가 있고 반복되는 코딩이 있을 때 사용하는 제어문이라고 생각하시면 됩니다. 명령이 일정한 순서가 있다면 "아! for문으로 표현해야지!"라고 생각을 하시면 됩니다. "배열변수가 있네! for문을 써야지!" 이렇게 바로 생각을 떠올리셔야 합니다.

4. 추가 공부


1) 문자열변수


문자배열변수는 char형으로 선언되고 "abcde"라고 단어를 그냥 표현하시면 됩니다. 참고로 5글자라고 해서 A[5]로 하시면 안됩니다. 문자의 경우는 마지막 끝나는 기호 '\0'이 저장되어야 합니다.

문자열 => 단어+'\0'

이 표현을 주의하셔야 합니다. 문장의 끝을 나타내는 기호를 저장하는 공간이 필요하니깐 문자배열변수를 선언할때 문자의 갯수와 마지막 문자의 끝 '\0' 기호를 포함된다는 것을 기억 해주세요. 그리고 각 알파벳을 접근하는 방식은 배열의 위치(index)로 접근하시면 해당 알파벳을 접근 할 수 있습니다.



위 그림에서 처럼 A[i]의 위치의 알파벳을 순서대로 출력했네요. 저장하는 것과 접근하는 것과 출력하는 것의 느낌을 잘 기억해 주세요.

2) 2차원배열


위 그림은 2차원 배열입니다. 표에 있는 것은 위치(index)라고 생각하시면 됩니다. 3차배열은 3x3x3인데 위 그림의 2차배열을 x,y 평면으로 생각한다면 3차는 여기서 z축으로 깊이 만큼 x,y 평면인 2차 배열이 3개 있는 거라고 생각하시면 됩니다. 2차 배열은 예를 들면은 이미지같은 평면적 데이터를 제어할 때 사용하고요. 3차 배열은 3차원 형태의 3D 데이터를 제어할 때 사용한다고 생각하시면 됩니다.

3차배열은 이런 느낌입니다.


2차 배열을 For 문으로 접근한다면

for(int j=0;j<3;j++){
    for(int i=0;i<3;i++){
        A[j][i]
    }
}

이렇게 접근을 하겠죠.

For문을 편하게 사용하실려면 다양한 예제들을 구글 검색을 통해 찾으시고 직접 코딩을 해보셔야 합니다. 왜냐면 문법을 알아도 정확히 어떤 느낌의 제어문인지 그 의미를 잘 모르시는 분들이 많아요. 그러다보니 For를 활용을 잘 못하더군요. For문은 계속 다양한 예제를 검색하셔서 직접 코딩하고 그 코딩의 의미 해석을 여러번 하셔야 For문을 자유자재로 쓰실 수 있을거에요.

3) 증감연산자

[ 증감연산자 ]
i++ => i=i+1 => i가 1씩 증가
i-- => i=i-1 => i가 1씩 감소

대충 '++'과 '--'의 의미를 아시겠지요. 그런데 이게 좀 햇갈려 하시는 분들이 많아요. 혼동하는데 과거 전산직 공무원 시험문제로 자주 출제되는 문제인데 지금은 바뀌어서 나온지는 모르겠네요. 아무튼 혼동하시는 분들이 은근 많습니다.

증감연산자는 원래는 다음과 같은 4가지로 표현됩니다.
++i => i를 먼저 1증가 시키고 나서 대입
i++ => i를 먼저 대입하고 나서 1증가
--i => i를 먼저 1감소 시키고 나서 대입
i-- => i를 먼저 대입하고 나서 1감소

int a =10;
int i = 2;
s1 = a + (++i);
int a =10;
int i = 2;
s2= a + (i++);

이 둘의 s1과 s2 값은 다릅니다.

그리고,

int a =10;
int i = 2;
s1 = a + (++i);
s2 = a + (i++);

이렇게 연달아 있으면 s1과 s2에 저장된 값은 같습니다. 그 차이점을 아시면 증감연산자를 혼동하지 않습니다. 위의 증감연산자 4가지 표현 부분의 해답이 있습니다.

s1 = a + (++i);

a+i가 i=2일때 i를 먼저 1을 증가시킨후 a에 더해집니다. 그래서 i은 3이 되고 s1은 13이 됩니다.
그다음 문장에서는

s2 = a + (i++);

a+i가 i=3이 된 상태에서 먼저 a에 더한 후에 i가 1이 증가되기 때문에 a+i은 s2에 13이 저장됩니다.

혹시 햇갈릴 수 있으니간 위 코딩을 setup()함수 안에다가 넣고 println()문으로 그 값을 출력를 해보세요.

마무리


For문에 대해서 살펴보았습니다. For문은 일정한 규칙으로 반복수행 할 때 배열변수가 있을 때 중복되는 코드들이 있을 때 그 부분을 간소화 된 코딩으로 표현을 할 때 사용합니다. 꼭 숙지해 주세요.

For문이 처음에는 잘 이해가 안될 수 있는데 계속 For문 예제를 찾아서 몇번 코딩하게 되면 이해가 되실 거라 생각합니다. 대개 C언어 For문에 대해 배울때 숙제로 많이 내주는게 구구단 프로그램 입니다. 한번 C언어로 된 구구단 프로그램을 찾아보시거나 상상력을 동원해서 표현을 직접 코딩을 해보세요. 2차 배열의 대표적인 예제이니깐요.

제 포스트 중에 종종 For문을 써왔는데 한번 잘 살펴보세요. 여러게 아두이노 핀을 제어할 때 주로 For문을 사용했고요. 패턴을 만들때 배열변수에 저장하고 그것을 출력 할 때 For문을 사용하였습니다. for문을 얼마나 자유자재로 잘 사용하느냐에 따라서 아두이노의 코딩량을 대폭 줄일 수 있으니깐 꼭 For의 의미를 이해해 주세요.

계속 머리속에서 "중복되는데 순서를 가지고 있다 For문을 써야지", "배열변수네 For문 써야지" 생각하시고 어떻게 접근하는지만 숙지하시면 For문을 사용하는데 어려움이 없을꺼에요.

마지막으로, For문으로 1부터 100까지 더한 합을 구해 보세요. '*'기호로 삼각형, 마름모 등 다양한 도형으로 출력시켜 보세요.

댓글()