[이론]배열사용시의 장점

출처 블로그 > 방문환영!!Gracias
원본 http://blog.naver.com/qkekalth/120008621835


답변 (1)  배열의 장점
------------------------------

프로그램을 짜면서 변수를 다루다보면 몇 가지 불편한 점이 생깁니다. 첫 번째로 불편한 점은 변수 하나에 하나의 자료만 넣어야 한다는 점입니다. 즉 백 개의 다른 자료를 사용하기 위해서는 백 개의 변수를 선언해주고 백 개의 변수 이름을 지어준 다음에 하나씩  자료를 대입해주어야 한다. 이것은 매우 번거로울 뿐만 아니라 프로그램의 자동화에도 걸림돌이 됩니다.

여기에서 이런 생각을 가질 수 있습니다. 변수를 한 번만 선언해주고 변수 이름도 하나만 사용하면서 백 개의 자료를 따로따로 다룰 수 있는 방법은 없을까? 이런 생각을 토대로 해서 나온 개념이 배열이라는 개념입니다. 배열은 쉽게 말하면 여러 개의 자료를 다룰 수 있는 변수라고 보면 됩니다. 

배열은 0번부터 시작하므로 a[2]는 두 번째 방이 아니라 세 번째 방입니다.
한 가지 주의할 점은 컴퓨터의 특성상 배열은 0번부터 시작한다는 점입니다. 즉 a[2]라는 배열은 2번 방이지 두 번째 방이 아니라는 사실입니다. a[2]라는 배열은 a라는 배열의 세 번째 방이 되는 것입니다. 첫 번째 방은 a[0], 두 번째 방은 a[1]이라고 표시하기 때문입니다.

배열은 복잡하거나 많은 양의 자료를 다룰 때 거의 필수적입니다. 변수만 가지고 자료를 다루려면 매우 힘들 뿐만 아니라 사실상 불가능에 가깝습니다.

배열은 변수보다 훨씬 편하고 매우 유용한 개념이지만 변수보다 다루기가 까다롭습니다. 변수는 각기 독특한 이름이 있기 때문에 기억하기도 쉽고 다루기도 쉽습니다. 그러나 배열은 이름이 같기 때문에 몇 번째라는 숫자를 통해서 다른 배열과 구별해야 합니다. 이일은 생각보다 까다로운 일이지만 배열을 사용하지 않고 많은 용량의 자료를 다루기란 어려우므로 배열의 사용법을 잘 익혀두셔야 합니다.


------------------------------
답변 (2) 자동 변수와 정적 변수의 차이
------------------------------

기억 장소의 선언방법

변수는 기억 장소의 종류와 방법에 따라서 네 가지로 분류합니다.
이번에는 기억 장소의 종류와 기억방법에 따른 변수의 분류방법을 알아보겠습니다. auto변수를 제외하면 변수를 선언할 때 키워드를 써주어야 변수의 기억 장소를 선택할 수 있습니다. 즉 auto 키워드는 생략이 가능하지만 static과 register 키워드는 생략할 수 없습니다. extern 키워드는 함수의 바깥에서 사용할 경우에는 생략할 수도 있습니다. 단 extern 키워드는 변수의 선언에만 사용합니다.

일반적인 함수는 기억 장소로 따지자면 원래 외부형입니다. 때문에 함수를 정의할 때 함수형 앞에 static을 덧붙여서 그 함수를 정적 함수로 만들 수 있습니다.
함수는 외부함수와 정적 함수의 두 가지 부류밖에 없지만 변수는 다양한 종류가 있습니다. 변수는 여러 가지 기억 부류를 조합해서 사용할 수 있기 때문입니다. 그러니까 여러 가지 기억 부류 관련 키워드를 조합해서 사용할 수 있다는 뜻입니다. 다음 보기는 똑 같은 키워드를 사용하더라도 선언된 위치에 따라서 다른 종류의 변수로 선언되며, 각기 다른 기억 장소를 배정받음을 보여줍니다.

[보기]

#include

int n; /* main 함수 바깥에서 선언한 것이므로 외부 변수 n의 선언. */
extern int a; /* 외부 변수 a의 선언 */
static int i; /* 외부정적 변수 i의 선언 */

void main(void)
{
int m; /* 자동 변수 m의 선언 */
auto int b; /* 자동 변수 b의 선언 */
static int j; /* 정적 변수 j의 선언 */
register int r; /* 레지스터 변수 r의 선언 */

......
}

**표: 네 가지 기억 부류와 해당 기억 부류 지정자


변수는 가능한 자동 변수를 사용하는 것이 좋습니다.
기억 부류의 종류가 많기 때문에 아마 어떤 기억 부류를 선택해야 할 지 고민이 될 겁니다. 어렵게 생각하실 필요가 없습니다. 변수나 함수를 사용하다보면 자동적으로 기억 부류의 선택기준을 스스로 판단할 수 있기 때문입니다. 일단은 모든 변수는 자동 변수를 이용하는 것이 좋다고 생각하고 있으면 됩니다. 즉 가능하면 늘 자동 변수를 이용하는 것이 좋습니다. 만약 자동 변수의 값을 함수의 실행이 끝난 뒤에도 계속해서 보존할 필요가 있을 경우에는 내부정적 변수로 정의해서 사용하면 됩니다.

외부 변수를 사용할 때는 꼭 초기화를 해두어야 합니다.
외부 변수는 가능하면 사용하지 않는 것이 좋습니다. 그러나 모든 함수에서 사용해야 할 변수가 생기는데 이때는 외부 변수를 사용해야겠죠. 그리고 모든 외부 변수는 가능하면 초기화를 해두어야 합니다. 안그러면 쓰레기값을 가질 수 있기 때문입니다.
배열도 가능하면 자동배열로 사용해야 합니다. 단 초기화가 꼭 필요하거나 공용성을 가지는 배열을 사용해야 할 때는 주로 외부형으로 사용합니다.
그리고 함수의 형식매개변수(즉 인수)는 기억 부류로 따지자면 자동 변수에 해당되며, 상수 중에서 문자열 상수는 정적상수에 해당하는 것으로 알고 있으면 됩니다.
물론 이런 기억 부류를 사용할 때도 일정한 규칙을 따라야 합니다.

**표: 기억 부류의 사용규칙
1. 자동 변수 이름은 선언 또는 정의된 블록이나 함수 안에 하나 뿐이어야 합니다.
2. 외부 변수 이름은 프로그램 전체에 걸쳐서 하나 뿐이어야 합니다.
3. 내부정적 변수 이름은 선언 정의된 블록이나 함수 안에 하나 뿐이어야 합니다.
3. 함수 이름은 프로그램 전체에 걸쳐 하나 뿐이어야 합니다.
4. 정적 함수 이름은 정의된 모듈 안에서 하나 뿐이어야 합니다.

자동 변수

자동 변수는 함수 내부에서만 사용되며 자동으로 생성 소멸됩니다.
자동 변수는 말할 것도 없이 가장 많이 사용하는 변수입니다. 그리고 가능하면 자동 변수를 가장 많이 사용해야 합니다. 자동 변수는 함수 내부의 선언을 하고, 선언된 함수 내부에서만 사용이 가능합니다. 따라서 함수가 실행됨과 동시에 생성되며, 함수의 종료와 동시에 자동으로 사라지는 변수입니다. 함수가 종료되면서 자동으로 소멸되므로 메모리를 차지하지 않습니다. 그래서 메모리의 효과적인 관리를 위해서도 자동 변수는 매우 유용합니다.

만약 변수의 선언 때 기억 부류 지정자를 생략할 경우에는 자동 변수가 자동으로 생성되며 함수의 실행이 끝나면서 자동 변수도 소멸됩니다.

자동 변수는 함수 실행 때마다 쓰레기값을 가지며 생성되므로 매번 초기화해주어야 합니다.
자동 변수는 함수가 실행될 때마다 매번 새롭게 초기화되는데 생성될 때 불확실한 쓰레기값을 가지고 만들어집니다. 때문에 한 번은 초기화를 시켜주어서 쓰레기값을 제거해야 합니다. 이때 말하는 쓰레기값이란 아무나 버리는 쓰레기처럼 어떤 값이 들어있는지 모른다는 소리입니다.

따라서 어떤 값이 들어있는지도 모른 상태에서 이 변수를 사용해서는 안됩니다. 자동 변수를 초기화하지 않은 상태에서 자동 변수를 어떤 수와 비교하는 행위는 하면 안됩니다. 초기화되지 않은 변수를 사용하는 것은 뜻하지 않은 결과를 초래합니다.

자동 변수는 자동으로 생성되고 소멸되기 때문에 동적 스택에 만들어지고 저장됩니다.

**요약: 기억 부류 지정자를 생략하면 자동 변수가 만들어집니다. 자동 변수는 함수 내부에서만 사용가능하며 자동으로 생성 소멸됩니다. 생성 시에는 쓰레기값이 대입되므로 자동 변수는 사용 전에 반드시 한 번은 초기화해주어야 합니다. 자동 변수는 동적인 스택에 저장됩니다.

내부정적 변수

내부정적 변수는 함수 내부에서 선언되지만 함수 종료 후에도 소멸되지 않습니다.
내부정적 변수는 함수 내부에서 선언되는 정적 변수라는 특성을 가지고 있습니다. static 이라는 키워드에 의해 선언되는데 함수 내부에서 선언되었지만 함수 종료 후에도 소멸되지 않고 그 값이 남아있다는 점이 다릅니다. 따라서 내부정적 변수는 변수가 소멸되지 않고 계속 남아있어야 할 때 사용합니다.

내부정적 변수는 함수 내부에서만 사용 가능하며, 0으로 초기화됩니다.
내부정적 변수는 함수 내부에서 선언하므로 선언된 함수 내부에서만 사용 가능합니다. 그러나 프로그램이 실행되는 동안 존재합니다. 내부정적 변수는 프로그램이 실행됨과 동시에 단 한 번만 초기화되는데 초기값을 주지 않으면, 모두 0 으로 초기화됩니다. 변수는 정적 데이터 영역에 저장됩니다.

내부정적 변수는 static 키워드로 선언합니다.
내부정적 변수를 사용할 때는 함수 안에서 static라는 키워드를 붙여서 변수를 선언해주면 됩니다. 사용 형식은 다음과 같습니다.

[사용 형식]
static 자료형 변수 이름1, 변수 이름2, ......;

[보기]
static int n=1;
static double a[3];

**요약:
내부정적 변수는 함수 내부에서 선언하며, 선언된 함수 내부에서만 사용 가능합니다. 그러나 프로그램이 실행되는 동안 존재하며, 프로그램이 종료되면서 소멸됩니다. 프로그램이 실행됨과 동시에 단 한 번만 초기화되는데 초기값을 주지 않으면, 모두 0 으로 초기화됩니다. 정적 데이터 영역에 저장됩니다.

외부정적 변수

외부정적 변수는 다른 소스 파일에서는 참고할 수 없는 외부 변수입니다.
외부정적 변수는 외부 변수와 같으나 자신이 속한 모듈에서만 사용할 수 있다는 점이 다릅니다. 즉 다른 소스 파일에서는 참고할 수 없다는 점이 다릅니다. 따라서 외부정적 함수는 특정 모듈에서만 사용 가능한 외부 변수인 셈입니다. 외부정적 변수는 함수 외부에서 선언되며, static 키워드를 사용합니다.

[사용 형식]
static 자료형 변수명1, 변수명2, ......;

[보기]
static int n = 1;
static int x[3];

main() {
...
}

보기를 통해 알 수 있는 것처럼 내부정적 변수와 선언방법은 내부정적 변수와 같으나 다만 선언하는 위치가 다릅니다. 따라서 정적 변수가 함수 내부에서 선언되면 내부정적 변수이고 함수 외부에서 선언되면 외부정적 변수입니다.

**요약: 정적 변수가 함수 외부에서 선언된 것이 외부정적 변수인데 다른 소스 파일에서는 참고할 수 없는 외부 변수입니다. 즉 선언된 모듈에서만 사용이 가능한 외부 변수입니다.

** 출처: [C언어 이야기(김중태 지음. 2003년. 혜지원)]

------------------------------
답변 (3) 라이브러리 함수와 일반 함수의 차이
------------------------------

질문이 명확하지 않습니다. 기본적으로 일반 함수라고 하는 것도 라이브러리 함수입니다. 아마, 컴파일러에서 제공하는 기본 함수(컴파일러 내장 함수)와 사용자가 만들어 라이브러리 파일로 저장한 사용자 정의 함수의 차이를 물어본 것 같습니다.

일반 함수(내장함수)는 C언어 자체에서 초기부터 제공하는 함수를 말합니다. printf() 함수 등이 일반 함수입니다. 따라서 모든 C언어 프로그램에서 공통적으로 지원하는 함수이므로 어떤 컴파일러에서도 사용 가능한 함수입니다.

반면 라이브러리 함수는 사용자가 함수를 만든 후에 이를 라이브러리 파일에 포함시킨 함수입니다. 따라서 라이브러리 함수를 사용하려면 라이브러리 파일이 있어야 합니다. 만약 라이브러리 파일이 없는 상태에서 이 함수를 사용하게 되면 함수를 찾을 수 없다는 오류 안내문이 뜰 겁니다.

즉 일반 함수는 어떤 컴파일러에서도 사용 가능한 함수인 반면, 라이브러리 함수는 라이브러리 파일이 함께 제공되어야만 사용할 수 있는 함수입니다.

------------------------------
답변 (4) 인수와 매개변수의 차이
------------------------------

이 질문 역시 명확하지 않습니다. 기본적으로 인수와 매개변수는 같은 낱말입니다. 제 생각에는 인수는 실인자, 매개변수는 가인자를 뜻하는 것 같습니다.
아래 내용을 참고하기 바랍니다. 아래 내용 중에서 swap(x,y)의 x, y를 매개변수, int swap(int a, int b) 의 a, b를 인수라고 생각하고 질문한 것이 아닌가 생각이 드네요.


/* c220301.c - 번지 참조를 이용하지 않은 swap 함수의 사용 예제 */

#include
int swap(int a, int b);
void main(void)
{
int x=3,y=5;
printf("x=%d y=%d \n",x,y);
swap(x,y); /* swap라는 함수를 실행시켜 x와 y를 바꿈 */
printf("main: x=%d y=%d \n",x,y); /* 다시 x와 y의 값을 출력했음. */
}

int swap(int a, int b)
{
int imsi;
imsi=a;
a=b;
b=imsi;
printf("swap: a=%d b=%d \n",a,b); /* a와 b의 값을 출력해봅니다. */
return 0;
}

함수에 넣어주는 매개변수를 실매개변수, 함수 본체의 변수는 형식매개변수라 합니다.
즉 swap함수를 실행시키면 swap() 함수 안에서는 a와 b가 바뀝니다. 그러나 이것은 swap() 함수 안에서만 일어나는 변화입니다. 이 변화가 바깥의 변수 x와 y에는 영향을 주지 않습니다.

이처럼 어떤 함수를 실행시킬 때 swap(x, y)라는 문장에 넣어주는 매개변수를 실매개변수 또는 실인자라고 합니다. 그리고 swap() 함수 본체에서 동작하는 변수 a와 b는 형식매개변수, 형식인자라고 말합니다. 즉 실매개변수를 매개변수(또는 매개변수)로 받았다 하더라도 같은 블록 안의 형식매개변수에만 영향을 미칠 뿐 함수나 블록 바깥 쪽에는 영향을 미치지 않습니다.

변수에 직접 값을 대입해 참조하는 형식을 '값에 의한 참조'라고 합니다.
이와 같이 변수에 직접 값을 대입해서 참조하는 형식을 '값에 의한 참조'라고 말합니다. 즉 swap() 함수는 x의 값과 y의 값인 3과 5를 대입한 함수입니다. 그리고 대입된 값인 3과 5를 서로 교환하기는 했습니다. 그러나 값에 의한 참조이기 때문에 변수 x와 y의 값을 실제로 교환하지는 못합니다.

그러나 실질적으로 우리가 바꾸고자 하는 것은 x와 y의 내용입니다. 즉 실매개변수인 것입니다. 실매개변수의 내용을 손쉽게 바꾸는 방법은 '값에 의한 참조'가 아니라 '번지(또는 주소)에 의한 참조'를 하는 것입니다. 번지에 의한 참조란 변수의 값을 직접 대입하지 않고, 변수의 번지를 대입한 다음에 간접 연산자를 이용하여 내용을 바꾸는 것입니다.

by 성우 | 2007/12/07 16:49 | 트랙백 | 덧글(0)

트랙백 주소 : http://downpour.egloos.com/tb/1101818
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]

:         :

:

비공개 덧글

<< 이전 페이지     다음 페이지 >>