인프런 커뮤니티 질문&답변

용개형멋져님의 프로필 이미지
용개형멋져

작성한 질문수

홍정모의 따라하며 배우는 C언어

11.8 문자열의 포인터를 정렬하기

3분 40초경 질문

해결된 질문

작성

·

131

·

수정됨

2

3분 40초경의 교수님 설명을 듣고

void swap(char** xp, char** yp)

{

char* temp = *xp;

xp = yp;

*yp = temp;

}

void selectionSort(char* arr[], int n)

{

int i, j, min_idx;

for (i = 0; i < n - 1; i++) // Note n - 1

{

min_idx = i;

for (j = i + 1; j < n; j++) // Note i + 1

{

if (strcmp(arr[min_idx], arr[j]) == 1) //if (arr[min_idx] > arr[j])

min_idx = j;

}

swap(&arr[i], &arr[min_idx]);

}

}

 

 

void swap(char* xp, char* yp)

{

char* temp = xp;

xp = yp;

yp = temp;

}

void selectionSort(char* arr[], int n)

{

int i, j, min_idx;

for (i = 0; i < n - 1; i++) // Note n - 1

{

min_idx = i;

for (j = i + 1; j < n; j++) // Note i + 1

{

if (strcmp(arr[min_idx], arr[j]) == 1) //if (arr[min_idx] > arr[j])

min_idx = j;

}

swap(arr[i], arr[min_idx]);

}

}

예제를 이렇게 바꿔봤습니다.

포인터 변수의 주소를 넘겨주는 대신에 포인터 자체를 넘겨주고

swap 함수 안의 xp나 yp에 *를 때주면 첫 번째 예제와 두 번째 예제가 같아지는 것 아닌가요?

뭐가 잘못된건지 이해가 가질 않습니다.

 

추가로 swap 함수에 대해서 설명을 해봤는데 제 설명이 맞는건지 알려주시면 감사하겠습니다.

 

swap의 매개변수를 char**로 적은 이유는 넘겨줄 게 포인터 변수의 주소라 char에 **를 붙여줬기 때문이다.

그리고 swap 함수 안에서 xp나 yp에 *를 붙인 이유는 매개변수로 넘겨준 건

arr[i], arr[min_idx]라는 포인터의 주소이고 스왑 해줘야 할 건 그 포인터의 메모리 공간에 있는 주소값이기 때문이다.

답변 1

2

안녕하세요, 질문&답변 도우미 Soobak 입니다.

 

예제 코드:

void swap(char** xp, char** yp)
{
  char* temp = *xp;
  xp = yp;
  *yp = temp;
}

void selectionSort(char* arr[], int n)
{
  int i, j, min_idx;
  for (i = 0; i < n - 1; i++) // Note n - 1
  {
    min_idx = i;
    for (j = i + 1; j < n; j++) // Note i + 1
    {
      if (strcmp(arr[min_idx], arr[j]) == 1) //if (arr[min_idx] > arr[j])
        min_idx = j;
    }
    swap(&arr[i], &arr[min_idx]);
  }
}

 

변경하신 코드:

void swap(char* xp, char* yp)
{
  char* temp = xp;
  xp = yp;
  yp = temp;
}

void selectionSort(char* arr[], int n)
{
  int i, j, min_idx;
  for (i = 0; i < n - 1; i++) // Note n - 1
  {
    min_idx = i;
    for (j = i + 1; j < n; j++) // Note i + 1
    {
      if (strcmp(arr[min_idx], arr[j]) == 1) //if (arr[min_idx] > arr[j])
        min_idx = j;
    }
    swap(arr[i], arr[min_idx]);
  }
}

 

'포인터의 값' (포인터가 가리키는 주소) 를 함수를 통해 변경하기 위해서는, '포인터의 주소' (포인터 변수의 주소) 를 전달해주어야 합니다.
(변수의 값을 변경하기 위해 변수의 주소를 포인터를 통해 전달해준 경우를 떠올려보시면 이해에 도움이 되실 것 같습니다.)

 

변경하신 예제에서 처럼 swap()char* 포인터를 받는 경우,
xpyp 의 '값' 을 교환한다고 하더라도, 해당 교환은 함수 내에서의 '복사본' 에서만 일어나며
호출한 곳의 배열 arr 에 있는 실제 포인터에는 아무런 영향을 미치지 않습니다.
따라서, 배열의 원소가 실제로 교환되지 않는 것입니다.

마지막에 말씀해주신 내용과 이해가 정확하십니다 👍

수박님 답변을 보고 생각을 정리해 봤는데

예제 코드는 *xp = *yp인데 이건 포인터 변수의 메모리 공간에 *yp를 대입한거라 스왑이 됐고

변경한 코드는 xp = yp 그러니까 포인터값에 포인터값을 대입한거라 스왑이 안됐다고 생각해도 될까요?

 

그리고 제가 질문을 잘못드린거 같아서 다시 질문 드리는건데

3분 37초경에 주석으로

 

char* temp = arr[min_idx];

arr[min_idx] = arr[i]

arr[i] = temp;

 

라고 써놓으셨는데 이렇게 구현을 해도 기능이 똑같이 작동한다는 게 이해가 안되서 질문을 드린거였거든요.

이걸 어떻게 이해해야할지 감도 안잡혔었는데 감이 아주 조금 잡힌 상태에서 질문을 드린게 맨 위의 내용입니다.

제가 봐도 질문을 이상하게 한거 같은데 주석 처리 해놓은 코드가 어떤 코드인지 설명해 주실 수 있나요?

 

항상 답변 감사합니다.

안녕하세요, 질문&답변 도우미 Soobak 입니다.

 

예제 코드는 xp = yp인데 이건 포인터 변수의 메모리 공간에 *yp를 대입한거라 스왑이 됐고

변경한 코드는 xp = yp 그러니까 포인터값에 포인터값을 대입한거라 스왑이 안됐다고 생각해도 될까요?

: *xp = *yp; 는 포인터 변수가 가리키는 메모리 공간에 저장된 값을, 다른 포인터 변수가 가리키는 값으로 대체합니다.
즉, 두 문자열 포인터가 실제로 가리키는 메모리 주소를 교환합니다.

변경 한 코드에서 xp = yp; 는 함수 내에서 지역 변수인 xpyp 의 값만 교환하며, 실제 배열의 원소가 가리키는 주소(함수 외부)는 변경되지 않습니다.


char* temp = arr[min_idx];

arr[min_idx] = arr[i]

arr[i] = temp;

: swap() 함수를 별도로 정의하고 포인터 변수의 주소를 전달하는 대신,
배열의 원소(포인터)를 직접 교환하기 때문에 동일한 결과를 얻게 됩니다.

 

핵심은, 변수가 함수의 인수로 전달될 때, 그 함수 안에서 새로운 지역 변수로 복사되어 작동하는 과정에 대한 이해입니다.

변경한 코드에서 xp = yp; 는 함수 내에서 복사된 지역 변수의 xpyp 의 값만 교환하며, 함수 외부의 변수 (주석으로 처리된 코드는 swap() 함수가 호출된 곳, 즉 swap() 함수의 외부인 곳에서 실행됨을 생각해보시면 이해에 도움이 되실 것 같습니다.) 에는 영향을 미치지 않습니다.

 

용개형멋져님의 프로필 이미지
용개형멋져

작성한 질문수

질문하기