-
[문제해설] 다음의 프로그램을 실행한 결과로 옳은 것은?전자계산기조직응용기사/필기 기출문제 해설 2021. 10. 25. 12:18반응형
전자계산기조직응용기사 필기 기출문제 (1과목 전자계산기프로그래밍-C언어) - 2017년3회
다음의 프로그램을 실행한 결과로 옳은 것은?
#include<stdio.h>
void main( )
{
int a[ ] = {1,2,3,4};
int b[ ] = {5,6,7,8};
int *pa[ ] = {a,b};
printf("%d", *(pa[1]+1));
}① 2 ② 3
③ 6 ④ 8
- 문제 해설 -
C언어 코드를 제시하고 결과를 묻는 문제입니다.본 문제는 알고리즘은 단순하지만, 배열에서 포인터 문법을 알고 있는지를 측정하는 문제입니다.
먼저 포인터에 대해서 간략하게 알아보겠습니다.
대학에서 교수님 등이 수업을 하실 때, 포인터를 들고 프레젠테이션을 가르키면, 붉은 점이 교수님이 원하는 곳을 가르키게 됩니다. 그럼 학습자들은 교수님이 봐주기를 의도하는 곳을 넓은 프리젠테이션 화면 중에서 정확하게 찾아볼 수가 있습니다.
C언어에서 포인터(pointer)도 마찬가지입니다. 포인터는 프로그램이 처리해야 할 데이터(혹은 값) 자체가 아니라, 데이터를 가리키고 있는 개념입니다. 컴퓨터 시스템에서 데이터들은 저장장치(실행 중인 프로그램의 경우 주기억장치)에 저장이 되어 있습니다. 저장장치에는 굉장히 많은 데이터들이 존재하고 있겠지만, 컴퓨터는 필요한 데이터에 정확히 액세스를 합니다. 이때 메모리 주소(address)로 필요한 데이터의 정확한 위치에 접근합니다.
C언어에서 선언된 변수는 다음과 같이 구성이 됩니다.
위 도식처럼 변수가 선언되면, 그 변수는 이름, 속성, 값이라는 구성요소를 가집니다. 이때 C언어 같은 포인터 개념이 있는 언어에서는 값의 위치를 나타내는 주소도 가집니다.
그럼 예를 들어, int fishbone = 3;이라는 코드로 변수를 선언을 하면, 그 변수를 다음과 같이 직육면체로 나타낼 수 있습니다.
위 직육면체의 오른쪽 면의 fishbone은 변수의 이름, 앞면의 3은 변수의 값, 윗면의 &fishbone은 값이 있는 주소입니다.
사실 주소는 복잡한 숫자로 이루어져 있지만, C언어에서는 변수명 앞에 &를 붙이면, 그 변수 값의 주소를 나타냅니다.
포인터 변수는 데이터에 접근할 수 있는 주소 값만을 저장할 수 있는 특별한 변수입니다. 포인터 변수를 선언하는 방법은 변수 앞에 *을 붙입니다.
그럼 예를 들어, int *ptr = &fishbone;이라는 코드로 포인터 변수를 선언하면,
이처럼 일반 변수처럼 나타낼 수 있습니다. 자세히 보면, 이 포인터 변수는 ptr이라는 이름을 가지며, &ptr이라는 자신의 주소도 가지고 있습니다. 한 가지 다른 점은 포인터 변수의 값인 &fishbone은 일반적인 자료가 아닌, 주소 값입니다. 여기서는 fishbone이라는 변수의 값을 가리키는 주소 값을 ptr이라는 변수의 값입니다.
#include <stdio.h> void main(void) { int a = 3; int *ptr = &a; printf("a의 값 : %d \n", a); printf("a의 주소 : %d \n", &a); printf("ptr의 값 : %d \n", ptr); printf("ptr의 주소 : %d \n", &ptr); printf("ptr의 값이 가르키는 값 : %d \n", *ptr); }
위 코드의 결과 화면은 다음과 같습니다.
포인터 변수의 가장 기본적인 문법을 알 수 있는 코드입니다.
그럼 배열에 대해서 알아보겠습니다.
배열은 동일한 자료 유형이 여러 개 필요한 경우에 이용할 수 있는 자료구조입니다.
C언어에서 int fishbone [5];라는 코드를 실행하면 다음과 같이 배열이 선언됩니다.
여러 개라는 것만 제외하고는 일반 변수와 구성이 똑같습니다. 한 가지 특징은 배열의 원소들은 주소가 연속적입니다.
일반적으로 배열은 fishbone [2]와 같이 인자와 같이 사용을 하지만 배열의 이름, 즉 fishbone만 쓰면 이 배열의 시작 주소를 나타냅니다. 이 특징을 이용하여, 다음과 같이 사용됩니다.
포인터에서 *(주소 값)은 주소 값이 가리키는 값을 나타낸다고 하였습니다. 배열에서 배열의 이름은 시작 주소를 나타내므로 위와 같이 활용을 할 수가 있습니다.
그럼 포인터와 배열에 대한 설명을 마치고 문제에서 주어진 코드를 살펴보겠습니다.
01 #include<stdio.h> 02 void main( ) 03 { 04 int a[ ] = {1,2,3,4}; 05 int b[ ] = {5,6,7,8}; 06 int *pa[ ] = {a,b}; 07 printf("%d", *(pa[1]+1)); 08 }
4~5번 라인 : 평범한 1차원 배열 a와 b가 선언하면서, 각각 초기값을 입력합니다.
6번 라인 : 포인터 변수 pa 배열을 선언하면서 초기값을 입력합니다. 그런데 pa 배열의 초기값들은 a, b입니다. a와 b는 4~5번 라인에서 선언한 배열들의 이름입니다. 배열들의 이름은 배열의 시작 주소를 나타냅니다.
7번 라인 : *(pa[1]+1)을 출력합니다. 이것을 하나씩 뜯어보면, 'pa[1]'은 배열 pa의 두 번째 원소인 b입니다. b는 배열 b의 시작 주소를 나타냅니다. 그럼 이것은 '*(b+1)'과 같습니다. *(b+1) = b[1] 입니다.
그래서 출력되는 값은 6이므로 정답은 3번입니다.
배열에서 포인터를 사용하는 문법은 꼭 기억해두셔야 합니다.
정리를 하자면,
배열의 이름이 a라고 할 때, '*(a + n)'은 'a[n]'을 나타냅니다.
2차원 배열의 경우, 배열의 이름이 a라고 할 때, '*((*a + n)+m)'은 'a[n][m]'과 같습니다. 이때 다중포인터가 아닌, 배열에서의 포인터 문법이라는 것에 유의하셔야 합니다.
https://youtube.com/playlist?list=PLboXycXmAIDuukQ2A6EvMZI-x1IMy3Xc-
반응형'전자계산기조직응용기사 > 필기 기출문제 해설' 카테고리의 다른 글
[문제해설] Infix 표기의 식 (A/(B^C))*D+E를 Postfix 방법으로 바르게 표현한 것은? (0) 2021.10.28 [문제해설] 2진수 덧셈으로 8비트(bit) 레지스터 250과 10을 더하는 ADC 명령어를 사용하여 덧셈한 결과는? (0) 2021.10.26 [문제해설] 시프트 레지스터(shift register)의 내용을 오른쪽으로 한 번 시프트하면 데이터는 어떻게 변하는가? (0) 2021.10.24 [문제해설] 스택 S에서 B, A, D, C를 순서대로 입력시킬 때, 출력을 A, B, C, D 순으로 하기 위한 push와 pop의 횟수는? (0) 2021.10.23 [문제해설] 객체 지향언어인 자바(java) 프로그램이다. 출력되는 값은? (0) 2021.09.24