int stackPop(int *value)
{
if (stackIsEmpty())
{
printf("stack is empty!");
return 0;
}
top--;
*value = stack[top];
return 1;
}
왜 굳이 리턴값을 value라는 매개변수에 간접적으로 리턴하는가?
- 리턴값과 실제 데이터값을 분리하기 위함.
보통 pop이 불가능한 경우(stack이 비어있을 경우)에 -1같은 sentinel 값을 쓰긴 하지만, 실제로 -1이라는 값이 엄연히 사용되는 수일 수도 있다. 따라서 임의의 수로 표현하면서 생기는 애매함을 없애고, 실제로 pop의 성공 실패 여부만 리턴해주면서 실제값은 매개변수 주소로 직접 넣어주는 방식을 채택한 것.
- 다중 값 반환을 위한 전형적인 C 패턴.
C는 함수당 한개의 리턴값만 가질 수 있다. 그래서 여러 개의 결과(성공 여부 + 실제 데이터)를 전달할 때 포인터 인자를 사용한다.
이는 표준 라이브러리scanf("$d, &x);같은 함수와 비슷한 이유.
scanf는 성공적으로 입력받은 개수를 리턴값으로 돌려주고, 실제 입력받은 정수는 포인터&x를 통해 채워준다.
- 효율성과 일관성
스택이 int 뿐 아니라 구조체(struct)같은 큰 자료형을 저장한다고 해보자. 만약 리턴값으로 struct를 통째로 돌려주면 복사 비용이 생긴다. 반면, 포인터를 쓰면 스택에서 꺼낸 걸 호출자의 변수에 직접 대입할 수 있기 때문에 불필요한 복사가 줄어든다.
또한,push와pop을 대칭적으로 설계하면 API가 직관적이다.stackPush(value); stackPop(&value);pop의 경우, value라는 변수가 차지하고 있는 주소에 직접 pop된 값을 넣는 것.