프로그래밍 공부
작성일
2023. 4. 6. 15:51
작성자
WDmil
728x90

C++에서도 메크로 펑션을 사용할 수 있다. #define에서 매크로를 선언하여 사용하는것 을 이야기 한다.

매크로 함수로 선언하면  CODE영역에서 함수를 저장하여 연산하기에 더 빠른 연산 처리가 가능하다.

 

코드 영역은 프로그램이 실행되기 전 코드 데이터가 들어가는 영역이다.

코드 예시와 실행 결과를 보자.

다음과 같은 방식으로 define을 사용하여 연산을 하는 펑션을 구축 가능하다.


그러나, 매크로 펑션은 입력된 매크로의 입력을 다음에 입력된 함수대로 변경되는것 이기에

괄호가 없어서 사용상 주의가 필요하다. 주의사항은 다음과 같다.

결과

즉, 매크로로 변환하여 사용하는 것은 괄호가 들어가지 않아. 정상펑션 대로 사용하면, 1+2의 결과가 나온 3이 다음 1+2의 결과와 곱해져 9가 나와야하는것이, 1 + 2 * 1 + 2 가 되어, 의도와는 다른 결과가 나타나는 것을 확인할 수 있다.

 

이와같은 괄호문제로 인하여, 매크로 펑션을 사용할 때 에는 함수의 연산 간, 우선순위를 잘 살펴보는것 이 중요하다.

 

그리하여, 원하는대로 9라는 출력값을 나타내기 위해서는 다음과 같이 작성해야 한다.

즉, 연산 결과가 함수펑션에서 나타나는 것 이 아닌, 수학연산 자체를 코드에서 실행한다고 이해해도 무방하다.

 

이를 다른 방법으로 응용하면 다음과 같이 최대값 구하는 함수 또한 define으로 제작이 가능하다.

이는 다음 함수와 같은 효과를 보면서도, 연산을 펑션에서 하는것 이 아닌 코드 자체에서 끌어와서 연산하기에 더 빠른 연산을 보장한다.


만약, 펑션단위로 작성하면서 함수펑션과 같은 효과를 보고싶을 경우가 있을 것 이다.

이럴경우 코드자체에 펑션을 남기기 위해 다음과 같이 코드를 작성하면 된다.

위와 같이 작성하면, 작성한 펑션 또한 함수펑션과 같은 동작속도를 발휘할 수 있다.


C언어에서는 변수에 데이터를 입력받아오는 과정에서 int나 flaot 또는 double같은 변수형 선언을 한 뒤 받아와야한다.

그러나, C++에서는 그러한 번거로운 선언대신 auto라는 방법을 사용할 수 있다. 다음과 같은 예시를 살펴보자.

위와 같이 int형과 float형 double형을 선언하여 덧샘결과를 result에 넣어준다는 가정을 해보자,

그렇다면 auto result는 a와 b형을 더하면서, 형변환을 시도한다.

가장 우선순위가 높은 변수를 기준으로 형 변환을 하여 덧셈 결과를 출력하고 형변환을 한다.

 

이 우선순위 는 다음과 같이 int < float < double 처럼 쉽게 생각하면, 덧셈을 하였을 때 형변환을 하여도, 잘라 없어지는 수의 단위가 작은 순서대로 형변환을 하여 데이터를 절삭한다 라고 생각하면 된다.


펑션을 선언하고, 펑션에도  auto를 넣어줄 수 있다. 리턴값을 정해주지 않고, 나중에 return을 사용자 임의로 줄 수 있기 때문에 편리하게 코드를 작성할 수 있다.

또한 꼬리표를 달아줄 수 있는데, 앞에 auto를 넣어놓고 코드를 마무리 한 뒤, 코드의 리턴값이 int나 float로 정해진것을 프로그래머가 확인하였을 때, 꼬리표로 int를 붙여주면, auto가 형을 찾을 필요가 없이 int로 지정되어 더 빠르게 설정이 가능하다.

 

쉽게 생각하면, auto는 코드 작성 시작시에 작성하는 것 이고, return은 결국 나중에라도 결정될 수 있기에 프로그래머 의 편리함이 더 늘어나는것 이다. 마지막에 int나 float을 바꾸어주면되고, 수정도 편하게 할 수 있을것이다. 

[ int를 리턴시켜도 float으로 받아와야할 수도 있다! ]


그러나, 펑션의 매게변수는 auto로 지정해줄 수 없다. 이는 펑션의 설계자체에 문제가 되는데, C++에서는 펑션을 찾을 때 펑션의 이름이 아닌 펑션의 매개변수를 기준으로 찾게된다. 이때 auto로 펑션을 지정해놓으면, 이름이 겹치는 펑션을 여러개 작성해놓았을 때 모호 문제가 발생할 수 있음으로, auto는 허용하지 않는다.


C++은 C와 다르게 같은 이름의 함수를 여러개 사용할 수 있다.

그러나, 유의해야 하는 점 은 함수를 선언할 때 매개변수를 다르게 해야한다. 매개변수가 같다면, 호출시 두개의 함수를 동시에 호출하기 때문에 모호성 문제가 발생한다.

 

그럼으로 같은 이름의 함수를 사용할 때 에는 매개변수를 다르게 하는것 이 중요하다. 다음과 같은 예시를 보면 알 수 있다.

위와 같이 함수의 이름을 중복하여 사용할 수 있다. 그러나, 매개변수로 구분해야만 한다.

또는, 인자의 개수를 다르게 하여 구분할 수 도 있다.

사용예시는 다음과 같다.

 

사용시에 리턴값이 달라질 수 있음으로, auto를 사용하면 임의의 리턴값을 판단하여 자동으로 분류해줌으로 더 편하게 사용할 수 있다.


함수를 선언 시 매개변수를 다르게 하였음에도 모호성 문제가 발생하는 경우가 있다. 이는 다음과 같다.

위와 같은 방식으로 output 함수를 생성하고, 각각 다른 int, unsinged int, float 으로 구성된 함수를 만들었다는 가정 하에

함수를 호출 시 int와 unsigned int를 구분하지 못해 모호성 문제가 발생한다.

30번째 줄 을 실행 시 output 1을 호출하나, int와 unsinged int 두개 전부 해당됨 으로 모호성 문재가 발생한다. 이를 유의하여 사용하여야 한다.


자신과 일치하는 변수를 찾지 못했을 경우, 가장 적합한 변수로 형변환하여 찾게된다.

예시는 다음과 같다.

output에는 char문이 없다.

output에는 char문이 없음으로, char를 받아올 수 없다. 그러나, 형변환 하여 손상이 가장 적은 변수로 형변환하여 데이터를 받아들이게 된다. 즉, int로 형변환하여 받아들인다.


함수를 선언할 때 매개변수 를 입력하지 않았다면, 매개변수 의 기본값을 입력해줄 수 있다.

이는 C++는 C와 다르게 함수명이 아닌 매개변수 를 기준으로 함수를 찾기 때문에 가능하다. 예시는 다음과 같다.

그러나, 같은 함수이름을 사용하는 중첩방식과 기본매개변수를 같이 사용하는것은 권장되는 방식이 아니다. 그 이유는 다음과 같다.

26번째 줄 과같이 2를 넣고 선언하였을 경우, 컴퓨터는 print(int x = 7) 의 x에 2를 넣은것 인지, print(int x, int y = 7)의 x에 2를 넣은것 인지 판단할 수 없음으로 모호성 문재를 발생시킨다. 그렇게 됨으로써 오류가 발생할 수 있으니, 이와같은 방법은 

 

권장되는 방법이 아니다. 그럼으로 유의해서 사용해야 한다.


또한, 앞의 값을 기본값으로 사용하고 뒤의값을 변경하고 싶어도 앞의값을 무시한 채로 사용할 수 없다.

앞의 값을 그대로 10으로 사용하고 z의 값만 3으로 바꾸고 싶다고 하더라도, test에 3만 넣는것으로 바꿀 수 없다.

다른 모든 값을 채워넣고 가장 마지막값을 변경해야 마지막값을 변경할 수 있다.


C++은 C와 다르게 문장을 출력하거나 수정할 때 배열참조방식을 사용하지 않아도 된다. 이는 다음과 같다.

14번째 줄은 const를 빼면 C++에서는 허용하지 않는다. 어차피 상수항이기 떄문에 수정이 불가능하여 const를 붙여야 하게 제한한다.

C는 위와 같은 방식을 사용하여 배열에 문자를 하나씩 넣는방식으로 데이터를 참조하여 출력할 수 있다.

 

C++에서는 다른방법인 string을 사용한다. 다음 예시를 살펴보자.

위와 같이. string을 사용하여 문장을 만들어서 넣어줄 수 있고, 각각의 문장을 하나로 결합하여 출력해줄 수 도 있다.

또한, += 연산을 사용하여 문장 끝에 다른 문장을 붙여넣어줄 수 도 있다.

 

그렇다고 C처럼 배열연산을 못하는것 도 아니라서, 배열처럼 사용또한 가능하다.


C++에서의 포인터연산은 C와 비슷한 방식으로 이루어지나, 변수초기화방법을 C++방식을 따르게 된다.

예시는 다음과 같다.

nullptr_t 를 사용하면 포인터를 nul로 초기화할 수 있다.


C++은 C와 다른방식의 랜덤함수 호출을 사용한다.

C에서의 랜덤함수 호출을 먼저 살펴보자.

위와 같은 방식으로 랜덤함수를 불러와서, srand로 초기화하고 시간상수를 받아다가 시드로 사용한 뒤 10개의 랜덤수를 0~ 9 까지 출력하는 코드 이다.

 

이를 C++로 다시 살펴보자.

다음과 같은 방법으로 함수를 호출하고 출력하게 된다. random_device 라는 함수를 호출하고 

rd 라는 변수에 0 ~ 2^32 수 사이의 범위 내에서의 시드를 생성하게 된다.

 

mt19937 는 메르센 트위스터 유사난수생성기 중 하나로, 1997년 마츠모토 마코토와 니시무라 다쿠지가 개발한 난수 생성기 이다. 기존 생성기를 개선하고, 질이 좋은 난수를 생성하며, 속도또한 빠르기 때문에 다양한 분야에서의 난수를 생성하기 위해 사용한다.

 

mt19937의 특징은, 2^19937-1의 주기를 623차원 내에 고르게 분포시켰다는것 에 있다.

쉽게 말하면, 2^19937 - 1 의 범위수를 생성해내는데 난수를 623개까지 생성한 뒤 하이퍼큐브 좌표에 입력하여 좌표점을 찍어도, 유사성을 발견할 수 없다는 의미이다.

 

또한 이를 비트연산 으로 알고리즘을 구현하였기 때문에, 속도도 매우 빠르다.

 

즉, 위 코드를 분리하면,

random_device 라이브러리 에서 rd라는 임의 하드웨어의 난수를 가져온 다음,

mt19937 클래스의 객체 messenne 를 생성하며, rd값을 시드로 받아와 사용한다.

그 후, uniform_int_destribution<>에서 reNUJm의 범위를 지정하여, 일정 수 내의 범위 의 수 가 생성되도록 재한한다.

그리고 26번째의 함수를 사용하여. 생성된 난수를 사용하여, 범위 내의 랜덤 수를 생성하게 된다.

 

 

 

 

728x90