[인터돌™] 공부 해보자!! 열심히~~~

반응형
출처 블로그>구차니의 잡동사니 모음 | 구차니

원문 http://blog.naver.com/morpheuz82/130028829555

C언어의 난관으로 꼽는 것 중에 배열(+반복문) / 구조체 / 포인터 / 함수 가 포함되는건 누가 꼽더라도 빠지지 않을듯 하다.

최대한 쉽게쉽게 책에 적혀 있어도 몇번을 봐도 이해 못하는 외계 언어인 C언어 대해서 하나씩 알아가 보도록 하자.




배열 [Array]

'배열은 같은 변수형의 연속된 변수들의 모임이다' 라고 정의 하면 조금 이해하기 쉬웠을까..


간단한 예를 들자면, 100명의 키에 대해서 저장을 해야 하는데 배열이 없다면 변수를 100개를 선언해야 한다.

100개의 변수를 만들어 내는 것도 머리 아프지만, 그걸 일일이 입력하는것도 상당히 귀찮은 문제이다.

 unsigned char height_1, height_2, height_3, ...  , height_98,  height_99, height_100;

 unsigned int average = (height_1 + height_2 + height_3 + ...  + height_98 +  height_99 + height_100) / 100

귀차니즘에 의해서 ... 으로 생략을 했지만 저렇게 구성을 할경우 for문으로 일괄적으로 합을 구할수도 없기에

저 변수들의 평균을 내려면 일일이 모든 변수를 직접 입력해서 더해야 하는 문제가(!) 발생을 하게 된다.

귀차니즘을 중시하는 나로서는 절대! 용납할수 없는 저주스러운 작업이다.


그런 이유로 배열이란것을 사용하게 된다.

물론 이름이 같기 때문에 for문이나 while으로 반복 시키기에도 간편한 장점이 있다.

 unsigned char height[100];

 unsigned char idx;

 unsigned int average = 0;


 for(idx = 0; idx < 100; idx++)

 {

    average = average + height[idx]

 }

위의 엄청난 코드의 길이와 비교 하면 엄청나게 간단하게 끝이 난다.(... 으로 생략된 부분이 실제 있다고 상상을 해보면... OTL)



구조체 [Structure]

'구조체는 사용자 정의 변수형이며, 전혀 다른 변수형들을 묶어서 선언한다.'

위의 배열의 예에서는 100명의 키에 대해서만 생각을 했지만, 만약에 주소록을 만든다고 하면 저런 배열을 여러개 선언하고

같은 인덱스로 동시에 읽어 와야 한다. 어쩌면 간단한 일일수도 있지만, 나중에는 그 인덱스로 인해서 머리가 지끈 거리게 된다.


인적사항으로 몇가지 예를 들어 보면

 unsigned char age[100];

 unsigned char height[100];

 unsigned char weight[100];

 unsigned char IQ[100];

이런 식으로 여러개의 변수들에 대해서 독립적으로 값들이 선언된다. 그런 이유로 이러한 데이터 구조에서

한사람의 정보를 다른 곳으로 이동하거나 삭제하려면, 각각의 배열의 인덱스를 지워주어야 한다.


 idx = 10; // 10번째 사람

 age[idx] = 0;

 height[idx] = 0;

 weight[[idx] = 0;

 IQ[idx] = 0;

현재는 항목이 4가지이지만 개인인적 사항의 항목들이 늘어 갈수록 코드도 복잡하고 지저분해지며, 유지가 힘들어 진다.

하지만 구조체를 사용하면 순서대로 메모리에 할당이 되므로 memcpy,memset등의 명령어로 한번에 삭제,복사가 가능해진다.


 typedef struct _person_

 {

    unsigned char age;

    unsigned char height;

    unsigned char weight;

    unsigned char IQ;

 } PERSON;


 PERSON database[100];


#ifdef MEM_FUNC

 memset(database[10],0x00,sizeof(PERSON));

#else

 database[10].age = 0;

 database[10].height= 0;

 database[10].weight= 0;

 database[10].IQ= 0;

#endif

현재에는 쓸데없이 더욱 길어져 보이지만, 항목들이 기하급수적으로 늘어 났을 경우에는 구조체를 사용하면 더욱 간단하게 조작이

가능하며, memset / memcpy 등의 명령어는 수행속도도 빠르므로 성능향상을 기대할수 있다.


공용체 [Union]

'공용체와 구조체의 차이점은, 메모리의 사용양이며 공용체의 경우 변수가 상호배타적으로 사용이 되어져야 하는 제약이 있다'



포인터 [Pointer]

'포인터는 하드웨어를 직접 제어하는 C언의 특징으로, 변수명이 아닌 변수로 부터의 변위등으로 값을 읽어 오는 방식이다'

포인터는 포인터이다! 라고 하는게 가장 편하고 확실한 의미를 지니지만,

포인터의 개념이 잡히지 않은 상태에서는 이러한 두리뭉실한 용어로는 딱히 와닫지가 않는다.


예를 들자면 철수네 집에서 오른족 두번째 집 이라고 표시 하는 방법이 있고

다른 방법으로는 00시 00동 00아파트 00동 000호 라고 직접 표시 하는 방법이 있다.

이러한 상대적인 방법으로 표기를 하기에 배열을 사용할수 있는 것이고, 이러한 이유로 배열은 포인터 방식으로 표기 될 수 있다.

 unsigned char age[100];

 unsigned char *age_ptr = NULL;

 age_ptr = age;

 *(age_ptr + 10) == age[10]

처음 보기에는 난해한 문장이지만, 천천히 보면 age[100] 이라고 unsigned char 형의 변수 100개를 배열로 선언을 하고

c언어에서는 age는 age[100]의 시작 주소를 의미하게 된다.

그리고 *agr_ptr 은 주소만 저장하는 변수이고 age 라고 하면 age의 처음 내용이 복사 되는게 아닌, age의 시작주소가 복사가 된다.

가장 마지막 줄은 같은 의미를 지니며 *는 곱셈이 아닌 그 주소의 값을 읽어 오라는 의미이다.

이 글을 공유합시다

facebook twitter googleplus kakaoTalk kakaostory naver band