배열을 가리키는 포인터

문성원·2024년 1월 4일
0

1) 목표

  • 2차원 배열을 포인터 변수로 나타내어 표기해보자
  • 주소 지정 연산자, 차원 변환 공식을 사용하여 2->1차원 배열로 사용하는 것처럼 표현해보기
  • 배열과 포인터의 관계를 명확하게 이해해보기

2) 소스 코드

#include "pch.h"
#include <stdio.h>

// 2차 배열로 표기하고 싶을 경우
// 차원 변환 공식에 의해서 각 그룹에 들어가는 항목을 곱하고 
// 나머지를 더한 값이 일차원 배열 상의 인덱스 번호
// char(*p)[3] == char[][3](배열이 아니고 포인터를 약식으로 표현한 것)
void ShowResult(char p_array[][3])
{
	int group, member;
	for (group = 0; group < 2; ++group)
	{
		for (member = 0; member < 3; ++member)
		{
			printf("(%d, %d),", p_array[group][member], p_array[group][member]);
		}
	}
	printf("\n");
}


int main()
{
	char data[6] = { 1,2,3,4,5,6 };
	char *p = data; // &data[0] == &*(data + 0) == data
	for (int i = 0; i < 6; ++i)
	{
		printf("(%d, %d), ", *p++, data[i]);
	}
	printf("\n");

	// 2차원 배열 선언
	char temp[2][3] = { {3, 4, 5}, {6, 7, 8} };
	p = (char *)temp; // &*(temp + 0) == temp

	// 2차원 배열 횟수 변수 사용
	int group, member;
	// 원칙적으로 2차원 배열을 통해 값을 출력하고자 하는 경우
	/*for (group = 0; group < 2; ++group)
	{
		for (member = 0; member < 3; ++member)
		{
			printf("(%d, %d), ", *p++, temp[group][member]);
		}
	}
	printf("\n");*/

	// p[i] = *(p + i)
	for (group = 0; group < 2; ++group)
	{
		for (member = 0; member < 3; ++member)
		{
			printf("(%d, %d), ", *(p + group * 3 + member), temp[group][member]);
			// printf("(%d, %d), " *(p + i), temp[group][member]);
		}
	}
	printf("\n");

	// p[i] = *(p + i) 
	for (int i = 0; i < 6; ++i)
	{
		//printf("(%d, %d), ", *(p + i), temp[0][i]);
		printf("(%d, %d),", p[i], temp[0][i]);
	}
	printf("\n");

	// 2차원 배열 선언
	// 포인터 연산자의 우선순위를 고려하여 괄호를 친 것
	// *p_array -> char 배열(char[3]) -> 3byte
	
	// temp[0][0] = char 1개 -> 1byte
	// temp[0]	  = char 3개 -> 3byte (char[3])
	// temp		  = char[2][3]
	
	char(*p_array)[3] = temp; // &*(temp + 0) -> temp == &temp[0];
	// *(p + i) = p[i];
	for (group = 0; group < 2; ++group)
	{
		for (member = 0; member < 3; ++member)
		{
			printf("(%d, %d), ", (*(p_array + group))[member], temp[group][member]);
			 // printf("(%d, %d), ", (*(p_array + group))[member]++, temp[group][member]);
			 // printf("(%d, %d), ", *(p_array + group * 3 + member), temp[group][member]);
			 // printf("(%d, %d),", p_array[group][member], temp[group][member]);
		}
	}
	printf("\n");
	
	// 함수 호출
	ShowResult(temp);

	// 프로그램 종료
	return 0;
}

3) 이해한 내용 정리

  • 배열에서의 포인터 변수의 선언은 배열의 첫번째 주소를 지정하는 것이다.
char data[6] = {1,2,3,4,5,6};
char *p = &data[0];
// &data[0] == &*(data + 0) == data
char *p = data;
  • 2차원 배열을 포인터를 통해 나타내고 싶으면 "*(주소 + 인덱스)" 의 개념을 사용하여 나타낸다. 또한 "*(주소 + 인덱스)"는 "주소[인덱스]" 이렇게도 사용할 수 있다.
char temp[2][3] = {{1,2,3}, {4,5,6}};
char *p = temp;
int group, member;
for(group = 0; group < 2; ++group)
{
	for(member = 0; member < 3; ++member)
    {
    	// p -> 주소, group * 3 + member -> 인덱스(여기서는 차원 변환 공식 사용함)
    	// 차원 변환 공식: 숫자 진법 계산 처럼 배열의 차원을 임의로 바꿔주어 메모리에 값을 집어 넣는 의미
        // 이 차원 변환 공식이 가능한 경우에는 메모리의 길이, 크기가 같은 경우에 많이 쓰임
        // 1) 2->1 => [group1 * 그룹화한 항목의 개수 + group2]
        // 2) 1->2 => [index / 그룹화한 항목의 개수][index % 그룹화한 항목의 개수]
        printf("(%d, %d), ", *(p + group * 3 + member), temp[group][member]);
    	printf("(%d, %d), ", p[group * 3 + member], temp[group][member]);
    }
}
  • 포인터 변수는 배열이 가리키는 곳의 시작 주소의 범위에 따라 참조하는 메모리 개수도 달라진다.
char temp[2][3] = {{1, 2, 3}, {4, 5, 6}};
temp[0][0]; // char 1개
temp[0];  	// char 3개
temp		// char[2][3];

// char 자료형: byte 공간 3개를 할당 받음 -> char[3]
char(*p_array)[3] = temp;

4) 출처

본 게시글은 금배씨 영상 중 "배열은 가리키는 포인터"를 참조하여 작성되었습니다.

profile
EasyWin32를 통해 C언어를 공부하고 있습니다~

0개의 댓글

관련 채용 정보