언어 자료구조 알고리즘/C 언어 문법

11. 산술 연산자

언제나휴일 2009. 8. 19. 05:47
반응형
산술 연산자

 

 

다루는 내용

   - 산술 연산자의 피 연산자와 연산 결과

   - 포인터와 가감(+-) 연산

 

산술 연산자는 모두 이항 연산자로 -, *, /, % 연산자가 있다.

 

각 연산자에 따라 피연산자로 올 수 있는 것이 조금씩 다르다.

문자형과 정수형은 모든 산술 연산자에 피연산자로 올 수 있으며 실수형은%연산자를 제외한 다른 연산자로 올 수 있다.

또한 포인터의 경우 +, - 연산자에 올 수도 있다. 이들에 대해 하나 하나 알아보도록 하자. 

+연산자

문자 정수 연산 결과 정수
문자 실수 연산 결과 실수
문자 포인터 연산 결과 포인터
정수 실수 연산 결과 실수
정수 포인터 연산 결과 포인터
실수 포인터 연산 불가
 

검증

 프로그래밍에 관련된 학습을 할 때에는 언제나 배운 내용에 대해 검증을 할 줄 알아야 한다.

다음은 위의 표를 검증하기 위한 코드이다.   

 

 

라인 22: <정수형 = 문자형 + 실수형>은 경고

라인 23: <실수형 = 문자형 + 실수형>은 아무런 메시지 없음

경고 메시지는 <'=': 'double'에서 'int'로 변환하면서 데이터가 손실될 수 있습니다.>

이를 통해 <문자형 + 실수형>의 연산 결과는 실수형이라는 것을 알 수 있다.

 

라인 24:<정수형 = 문자형 + 포인터>는 경고

라인 25:<포인터 = 문자형 + 포인터>는 아무런 메시지도 없음

경고 메시지는 <'=': 'int'의 간접 참조 수준이 'Foo *'와 다릅니다.>

이를 통해 <문자형 + 포인터>의 연산 결과는 포인터라는 것을 알 수 있다. 

 

라인 27:<정수형 = 정수형 + 실수형>의 연산 결과는 경고

라인 28:<실수형 = 정수형 + 실수형>은 아무런 메시지 없음

경고 메시지는 <'=': 'double'에서 'int'로 변환하면서 데이터가 손실될 수 있습니다.>

이를 통해 <정수형 + 실수형>의 연산 결과는 실수형이라는 것을 알 수 있다. 

 

라인 29:<정수형 = 정수형 + 포인터>는 경고

라인 30:<포인터 = 정수형 + 포인터>는 아무런 메시지도 없음

경고 메시지는 <'=': 'int'의 간접 참조 수준이 'Foo *'와 다릅니다.>

이를 통해 <정수형 + 포인터>의 연산 결과는 포인터라는 것을 알 수 있다. 

 

라인 32: <실수형 = 실수형 + 포인터> 에러

에러 메시지는 <'+': 포인터 더하기에는 정수 계열 피연산자가 있어야 합니다.> 

이를 통해 + 연산에 피연산자로 포인터 하나가 오면 나머지는 정수형(문자형 포함)이 와야 된다는 것을 알 수가 있다.

또한, 문자형은 + 연산에서 정수형과 차이가 없음을 알 수 있다.  실제 문자형은 메모리 사이즈가 1바이트라는 것 말고는 정수형과 큰 차이가 없다. 

 

 

-연산자

문자 정수 연산 결과 정수
문자 실수 연산 결과 실수
문자 포인터 연산 불가
정수 실수 연산 결과 실수
정수 포인터 연산 불가
실수 포인터 연산 불가

<포인터 + 정수> 연산이 되며 연산 결과가 포인터 이다.  교환 법칙이 성립하므로

<포인터 = 포인터 + 정수> ☞  <정수 = 포인터 - 포인터>이 되는 것이다.

반면  <포인터 + 포인터>는 연산이 되지 않기 때문에 <포인터 - 정수형>이나 <정수형 - 포인터>는 안 된다.

 

 

*연산자

문자 정수 연산 결과 정수
문자 실수 연산 결과 실수
정수 실수 연산 결과 실수

 
/연산자
문자 정수 연산 결과 정수
문자 실수 연산 결과 실수
정수 실수 연산 결과 실수

 * , /연산자에는 피 연산자로 포인터가 올 수가 없다.

 

 

Look & Think & Feel 

%연산은 여러분의 몫으로 남긴다. 

 

 

 

 

포인터와 가감(+-)연산

포인터는 + 연산자의 피연산자로 왔을 때 다른 피 연산자는 정수형(문자형 포함)이어야 하며 연산 결과는 포인터이다.

포인터는 - 연산자의 피연산자로 왔을 때 다른 피 연산자도 또한 포인터여야 하면 연산 결과는 정수이다. 

또한 - 연산에 오는 두 개의 포인터는 원소 형식이 같아야 한다.

  

 

위의 코드와 실행 결과를 보면 무엇을 알 수 있겠는가?

포인터에 정수를 더하면 해당 메모리 주소에서 해당 원소가 정수개 지나고 난 뒤의 메모리 주소가 연산 결과가 된다는 것이다.

즉, 포인터의 원소형식의 사이즈가 언제나 연산에 영향을 미친다는 것이다.

또한, 포인터에 포인터를 뺀다는 것은 두 메모리 주소 사이에 해당 원소 형식이 몇 개 있는지가 연산 결과인 것이다.

 

이는 조금만 생각해 보면 당연할 수도 있다.  C언어 사용자 입장에서 메모리 주소값이 궁금한 것이 아니고 해당 메모리에 있는 값이 궁금하고 해당 메모리에 원하는 값을 보관하고 싶을 것이다.  포인터는 사용자에게 프로그래밍에 유연성을 높이기 위해서 제공을 하였는데 더하기 연산이 무슨 의미가 있을까?  의미가 있으려면 '해당 메모리 주소에서 몇 번째 원소'와 같이 C언어 사용자에게 의미가 있어야 될 것이다.  C언어에서는 '해당 메모리 주소에서 n개의 원소가 떨어진 주소'라는 의미로 제공하고 있다.  '-' 연산의 경우 그 역으로 생각하면 될 것이다.  그리고, 포인터 * 포인터는 메모리 주소를 벗어날 수 있고 어떤 의미도 C언어 사용자에게 주지 못하고 / 연산자도 마찬가지 이유에서 포인터를 피연산자로 두지 못하는 것이다.

 

여러분은 포인터를 만나면 제일 먼저 원소 형식이 무엇인지를 확인하는 습관을 가져라.  

 

반응형