[TIL] 2025-04-29 알고리즘 문제, MakeFromX 함수 분석, 코드 실행 순서 심화, 조건문 심화
2025-04-29 TIL
알고리즘 문제
오랜만에 풀어보는 DFS 문제입니다.
이번 문제는 특별한 알고리즘이 있을까 싶었는데, 문제의 배열 길이가 크지 않아 완전탐색으로 풀어보았습니다.
DFS의 탈출 조건이 딱 와닿지 않아서 로직을 구현하는게 가장 오래 걸렸고, 다른 부분은 빠르게 해낼 수 있었습니다.
프로그래머스의 2레밸 문제들이 처음에는 어렵게 느껴졌는데 지금은 어느정도 풀어낼 수 있게 된 것 같습니다.
[프로그래머스][C++] 이모티콘 할인행사
MakeFromX 함수 분석
언리얼 엔진의 MakeFromX
함수를 분석해보는 시간을 가져보았습니다.
MakeFromX
는 입력된 벡터를 앞방향으로 가정하고, 이것을 기준으로 직교 좌표계를 구성하여 회전 행렬을 만들고, 반환하는 함수입니다.
template<typename T>
TMatrix<T> TRotationMatrix<T>::MakeFromX(TVector<T> const& XAxis)
{
TVector<T> const NewX = XAxis.GetSafeNormal();
// try to use up if possible
TVector<T> const UpVector = (FMath::Abs(NewX.Z) < (1.f - UE_KINDA_SMALL_NUMBER)) ? TVector<T>(0, 0, 1.f) : TVector<T>(1.f, 0, 0);
const TVector<T> NewY = (UpVector ^ NewX).GetSafeNormal();
const TVector<T> NewZ = NewX ^ NewY;
return TMatrix<T>(NewX, NewY, NewZ, TVector<T>::ZeroVector);
}
- 입력 벡터를 앞 방향이라고 가정하고, 정규화하여
NewX
를 생성합니다.- 이 벡터가 최종 회전 행렬의 X축(앞 방향)이 됩니다.
- X축이 Z축과 거의 평행한 경우 크로스 곱 계산에서 Y축을 구할 수 없기 때문에 외적이 실패하지 않도록 보완합니다.
UpVector
와NewX
의 외적(^)으로 Y축 벡터(NewY
)를 계산합니다.- 언리얼 엔진은 오른손 좌표계를 사용하기 때문에 해당 좌표계 기준의 오른쪽 방향입니다.
NewX
와NewY
의 외적으로 Z축(NewZ
)을 계산합니다.- 3개의 축 벡터를 사용해 회전 행렬(
TMatrix
)을 생성해 반환합니다.- 네 번째 인자는 위치 벡터인데, 여기서는 원점입니다.
코드 실행 순서 심화
#include<iostream>
using namespace std;
int main()
{
int a=1,b=2,c=3;
int x=++a+b+++ ++b+c+++a+++ ++c+b+c;
cout<<"a="<<a<<",b="<<b<<",c="<<c<<",x="<<x<<endl;
}
위 코드에 대해 분석해보는 시간을 가져보았습니다.
일종의 처음 봤을 때 굉장히 당황스러운 코드였는데, 차근차근 살펴보니 아래와 같이 코드를 좀 더 보기좋게 정리할 수 있었습니다.
#include<iostream>
using namespace std;
int main()
{
int a = 1, b = 2, c = 3;
int x = ++a + b++ + ++b + c++ + a++ + ++c + b + c;
cout << "a=" << a << ",b=" << b << ",c=" << c << ",x=" << x << endl;
}
이 상태에서 코드의 실행 순서를 하나씩 파악해보았습니다.
우선 코드의 실행 순서는 왼쪽에서 오른쪽이므로, int x
가 선언되고, 오른쪽의 대입 연산자를 발견하게 됩니다.
대입 연산자는 현재 실행해야할 코드 중에 가장 마지막에 실행되는 순서를 가집니다.
그렇기 때문에 오른쪽에 있는 전위와 후위 및 더하기 연산이 다 끝나고 대입됩니다.
더하기 연산자를 기준으로 전위가 먼저 실행되고, 더하기가 실행된 다음 후위가 실행됩니다.
하지만 컴파일러마다 순서가 달라질 수 있는데, 모든 전위와 더하기가 실행된 다음 후위가 실행될 수있습니다.
비주얼 스튜디오 기준으로는 x의 값이 25가 나왔는데, 다른 컴파일러에서는 27이 나오기도 했습니다.
a=3,b=4,c=5,x=25
조건문 심화
조건문에서 조건식에 문자열이 들어가면 어떻게 될지 살펴보았습니다.
평소에 생각해보지 못한 주제인데, 이런 주제를 듣고 굉장히 궁금해져서 직접 코드를 작성해보면서 살펴보았습니다.
#include <iostream>
int main()
{
if ("false")
{
std::cout << "1" << std::endl;
}
}
위 코드는 문자열 리터럴 "false"
를 조건식으로 사용하고 있습니다.
결과적으로 조건식은 참이므로, 1이 출력됩니다.
그 이유는 다음과 같습니다.
문자열 리터럴은 내부적으로 배열로 저장하기 때문에 포인터로 관리됩니다.
이때 이 포인터는 메모리에 있는 문자열의 시작 주소를 가리키며, 포인터의 값이 NULL이 아니기 때문에 조건식은 참입니다.
만약, 문자열 리터럴에 "false"
가 아닌 아무 글자가 없는 ""
기본 값이라면 결과가 다를지 궁금해집니다.
이 경우 배열의 크기가 0이 아닌 1이고, 포인터의 값이 NULL이 아니기 때문에 위에서 설명한 것과 같은 이유로 조건식은 참입니다.
정리하면, C++에서 포인터를 조건식에 사용하면 포인터가 nullptr인지 아닌지에 따라 조건식의 결과가 결정됩니다.
이런 이유는 C언어 때부터 0은 거짓 0이 아닌 값은 참으로 간주되며, nullptr일 경우 0이 반환되도록 구현돼있기 때문입니다.
이 개념은 컴퓨터가 이진 논리를 사용하는 것에 기반하고, 값이 0이면 없음, 0이 아니면 값이 있음으로 판단하는 기본적인 원칙에서 비롯했습니다.
"false"
가 0이 아닌 값이 존재하는 무언가이므로, 실행될거라고 생각은 했었는데 구체적으로 알아보니 간단한 코드더라도 굉장히 많은 개념이 사용된다는 것을 알 수 있었습니다.
댓글남기기