[Golang] 연산자

이정훈·2023년 5월 19일
0

Golang

목록 보기
4/24
post-thumbnail

연산자 종류

  • 변수와 상수는 값을 저장하는 기능만을 가지고 있다. 따라서 저장한 값을 가지고 (저장하지 않은 값도) 연산을 하기 위해서는 '연산자'를 사용

수식 연산자

  • 두 개의 피연산자를 요구하는 이항 연산자(binary operator).
  • 다른 언어들과 마찬가지로 기본적인 사칙연산이 있고, 값을 나눈 나머지 값을 반환하는 연산자가 있다.

종류

  • + : 피연산자들를 더한 값
    값의 자료형은 정수, 실수, 복소수, 문자열
    문자열도 합해준다!
  • - : 왼쪽 피연산자에서 오른쪽 피연산자를 팬 값
    값의 자료형은 정수, 실수, 복소수
  • * : 피연산자들를 곱한 값
    값의 자료형은 정수, 실수, 복소수
  • / : 왼쪽 피연산자에서 오른쪽 피연산자를 나눈 값
    값의 자료형은 정수, 실수, 복소수
  • % : 왼쪽 피연산자에서 오른쪽 피연산자의 값을 나눈 나머지 값
    값의 자료형은 정수, 실수, 복소수

코드

package main

import "fmt"

func main() {
	num1, num2 := 17, 5
	str1, str2 := "Hello", "goorm!"
	
	fmt.Println("num1 + num2 =", num1+num2)
	fmt.Println("str1 + str2 =", str1+str2)
	fmt.Println("num1 - num2 =", num1-num2)
	fmt.Println("num1 * num2 =", num1*num2)
	fmt.Println("num1 / num2 =", num1/num2)
	fmt.Println("num1 % num2 =", num1%num2)
}

출력

num1 + num2 = 22
str1 + str2 = Hellogoorm!
num1 - num2 = 12
num1 * num2 = 85
num1 / num2 = 3
num1 % num2 = 2

증감 연산자

  • 값을 1만큼 증가시키거나 감소시키는 연산자
  • Go언어에서는 증감 연산자를 사용할 때 주의할 점이 2가지가 있다.
    • 증감연산자를 사용하고 동시에 대입할 수 없다
    • 전위 연산을 할 수 없다.
      • num := count++ (X)
      • ++count(X)

종류

  • ++ : 값을 1 증가
    값의 자료형은 정수, 실수, 복소수
  • -- : 값을 1 감소
    값의 자료형은 정수, 실수, 복소수

코드

package main

import "fmt"

func main() {
	count1, count2 := 1, 10.4
	
	count1++
	count2--
	
	fmt.Println("count1++ :", count1)
	fmt.Println("count2-- :", count2)
}

출력

count1++ : 2
count2-- : 9.4

할당 연산자

  • 값을 단순히 대입하는 대입 연산자와 연산 후 값을 바로 대입시키는 복합 대입 연산자가 있다.

종류

  • = : 변수나 상수에 값을 대입
    변수는 변수끼리 대입이 가능
  • := : 변수를 선언 및 대입
  • += : 값을 더한 후 대입
    문자열일 경우 현재 변수에 문자열을 이어 붙인 다음 변수에 대입
  • -= : 값을 뺀 후 대입
  • *= : 값을 곱한 후 대입
  • /+ : 값을 나눈 후 대입
  • %+ : 값을 나눈 후 나머지를 대입
  • &= : 값의 AND 비트 연산 후 대입
  • |= : 값의 OR 비트 연산 후 대입
  • ^= : 값의 XOR 비트 연산 후 대입
  • &^= : 값의 AND NOT 비트 연산 후 대입
  • <<+ : 비트를 왼쪽으로 이동 후 대입
  • >>= : 비트를 오른쪽으로 이동 후 대입

코드

package main

import "fmt"

func main() {
	a := 2 // a는 2 로 초기화
	var num int // 아직 num은 선언하지 않았음

	num = a // num = a 로 선언하고
	fmt.Println("num = a :", num) 
	num += 4 // 2+4
	fmt.Println("num += 4 :", num) // 6
	num -= 2 // 6-2
	fmt.Println("num -= 2 :", num) // 4
	num *= 5
	fmt.Println("num *= 5 :", num)
	num /= 2
	fmt.Println("num /= 2 :", num)
	num %= 3
	fmt.Println("num %= 3 :", num)

	num = 3  //00000011
	num &= 2 //00000010
	fmt.Printf("num &= 2 : %08b, %d\n", num, num)
	num |= 5 //00000101
	fmt.Printf("num |= 5 : %08b, %d\n", num, num)
	num ^= 4 //00000100
	fmt.Printf("num ^= 4 : %08b, %d\n", num, num)
	num &^= 2 //00000010
	fmt.Printf("num &^= 2 : %08b, %d\n", num, num)
	num <<= 9 //00001001
	fmt.Printf("num <<= 9 : %08b, %d\n", num, num)
	num >>= 8 //00001000
	fmt.Printf("num >>= 8 : %08b, %d\n", num, num)
}

출력

num = a : 2
num += 4 : 6
num -= 2 : 4
num *= 5 : 20
num /= 2 : 10
num %= 3 : 1
num &= 2 : 00000010, 2
num |= 5 : 00000111, 7
num ^= 4 : 00000011, 3
num &^= 2 : 00000001, 1
num <<= 9 : 1000000000, 512
num >>= 8 : 00000010, 2

논리 연산자

  • AND(논리곱), OR(논리합), NOT(논리부정)을 연산
  • Go언어에서 논리부정 연산시 bool 형의 선언 및 사용만이 가능
    즉, false와 true값만 사용할 수 있다.
    • var a int = 10, b += 1 일 때,
      fmt.Println(!a) (X)
      fmt.Println(!b) (X)

종류

  • && : 연산하는 A와 B모두 '참'이면 연산 결과로 '참'을 반환
    1&&0=0, 1&&1=1, 0&&0=0
  • || : 연산하는 A와 B둘 중 하나라도 '참'이면 연산 결과로 '참'을 반환
    1||0=1, 1||1=1, 0||0=0
  • ! : 연산하는 A가 '참'이면 '거짓', '거짓'이면 '참'을 반환
    !1=0, !0=1

코드

package main

import "fmt"

func main() {
	var a bool = true
	b := false

	fmt.Println("0 && 0 : ", b && b)
	fmt.Println("0 && 1 : ", b && a)
	fmt.Println("1 && 1 : ", a && a)
	fmt.Println("0 || 0 : ", b || b)
	fmt.Println("0 || 1 : ", b || a)
	fmt.Println("1 || 1 : ", a || a)

	fmt.Println("!1 ", !true)
	fmt.Println("!0 ", !false)
}

출력

0 && 0 :  false
0 && 1 :  false
1 && 1 :  true
0 || 0 :  false
0 || 1 :  true
1 || 1 :  true
!1  false
!0  true

관계 연산자

  • 두 값의 대소와 동등의 관계를 따지는 연산자
  • 조건을 만족하면 treu, 만족하지 않으면 false를 반환ㄴ

종류

  • == : 두 값이 같은지 비교
    같을경우 'true', 다를 경우 'false'를 반환
  • !- : 두 값이 다른지 비교
    다를경우 'true', 같을 경우 'false'를 반환
  • < : 오른쪽 같이 큰지 비교
    오른쪽 값이 큰 경우 'true, 그렇지 않을 경우 'false'를 반환
  • <= : 오른쪽 같이 크거나 같은지 비교
    오른쪽 같이 크거나 같은 경우 'true', 그렇지 않을 경우 'false'를 반환
  • > : 왼쪽 같이 큰지 비교
    왼쪽 값이 큰 경우 'true, 그렇지 않을 경우 'false'를 반환
  • >= : 왼쪽 같이 크거나 같은지 비교
    왼쪽 같이 크거나 같은 경우 'true', 그렇지 않을 경우 'false'를 반환

코드

package main

import "fmt"

func main() {
	fmt.Println("13 == 13 : ", 13 == 13)
	fmt.Println("13 == 23 : ", 13 == 23)
	fmt.Println("13 != 13 : ", 13 != 13)
	fmt.Println("3 != 5 : ", 3 != 5)
	fmt.Println("0 < 1 : ", 0 < 1)
	fmt.Println("0 > 1 : ", 0 > 1)
	fmt.Println("0 >= 1 : ", 0 >= 1)
	fmt.Println("0 <= 1 : ", 0 <= 1)
}

출력

13 == 13 :  true
13 == 23 :  false
13 != 13 :  false
3 != 5 :  true
0 < 1 :  true
0 > 1 :  false
0 >= 1 :  false
0 <= 1 :  true

비트 연산자

  • 비트 단위의 연산을 진행
  • 사실 기계에 좀 더 친화적인 연사자지만 다른 영역에서도 사용, 효율성을 높이고 연산의 수를 줄이는 요인!
  • 활용적 측면을 이해하기엔 큰 부담이 따르기 떄문에 연산자의 기능을 먼저 이해!!

종류

  • & : 두 값을 비트 단위로 AND 연산
  • | : 두 값을 비트 단위로 OR 연산
  • ^ : 두 값을 비트 단위로 XOR 연산
    사용가능 자료형은 정수
  • &% : 두 값 비트 단위로 AND NOT 연산
    사용가능 자료형은 정수
  • << : 값의 비트열을 왼쪽으로 이동
    사용가능 자료형은 정수
  • << : 갑의 비트열을 오른쪽으로 이동
    사용가능 자료형은 정수

코드

package main

import "fmt"

func main() {
	num1 := 15 //00001111
	num2 := 20 //00010100

	fmt.Printf("num1 & num2 : %08b, %d\n", num1&num2, num1&num2)
    // AND 연산으로 b는 이진수로 8자리로 표현해달라! 하는 거니깐, num1과 num2를 2진수로 변경하고 AND연산을 해준 값을 표현달라! 그리고 %d는 정수 4를 출력!
	fmt.Printf("num1 | num2 : %08b, %d\n", num1|num2, num1|num2)
	fmt.Printf("num1 ^ num2 : %08b, %d\n", num1^num2, num1^num2)
	fmt.Printf("num1 &^ num2 : %08b, %d\n", num1&^num2, num1&^num2)

	fmt.Printf("num1 << 4 : %08b, %d\n", num1<<4, num1<<4)
	fmt.Printf("num2 >> 2 : %08b, %d\n", num2>>2, num2>>2)
}

출력

num1 & num2 : 00000100, 4
num1 | num2 : 00011111, 31
num1 ^ num2 : 00011011, 27
num1 &^ num2 : 00001011, 11
num1 << 4 : 11110000, 240
num2 >> 2 : 00000101, 5

채널 연산자

  • Go언어는 채널의 개념을 가지고 있다.
  • 채널이랑 고루틴(goroutine)끼리 데이터를 주고 받고 실행 흐름을 제어하는 기능
  • 자세한건 채널에서 배우고 채널 연산자가 있다 라고 생각하자

종류

  • <- : 채널의 수신을 연산
    채널에 값을 보내거나 가져옴

코드

package main

import "fmt"

func main() {
	ch := make(chan int) //정수형 채널 생성

	go func() {
		ch <- 10
	}() //채널에 10을 보냄

	result := <-ch //채널로부터 10을 전달받음
	fmt.Println(result)
}

출력

10
  • 자세한 것은 채널에서 다시 하는 것으로!

포인터 연산자

  • C++언어와 같이 &와 * 연산자를 이용해 메모리에 접근할 수 있도록 해준다.
  • 주의! 포인터 연산자를 제공하지만 포인터 산술 즉, 포인터에 더하고 뺴는 기능은 없다

종류

  • & : 변수의 메모리 주소 참조
  • * : 포인터 변수에 저장된 메모리에 접근하여 갑을 참조

코드

package main

import "fmt"

func main() {
	var num int = 5 // 정수 변수 num을 선언하고 5로 초기화합니다.
	var pnum = &num // 포인터 변수 pnum을 선언하고 num 변수의 주소를 저장합니다.

	fmt.Println("num : ", num)   // num 변수의 값을 출력합니다.
	fmt.Println("pnum :", pnum)  // pnum 변수의 값을 출력합니다.
	fmt.Println("pnum :", *pnum) // pnum 변수의 값을 통해 num 변수의 값을 출력합니다.

	*pnum++ // 포인터 변수를 통해 num 변수의 값을 1 증가시킵니다.

	fmt.Println("num : ", num)   // num 변수의 값을 출력합니다.
	fmt.Println("pnum :", pnum)  // pnum 변수의 값을 출력합니다.
	fmt.Println("pnum :", *pnum) // pnum 변수의 값을 통해 num 변수의 값을 출력합니다.
}

출력

num :  5
pnum : 0xc000018088
pnum : 5
num :  6
pnum : 0xc000018088
pnum : 6

포맷형식

  • 출력하는데 사용된 포맷형식을 이해하지 못해 왜 이런값이 나왔는지?? 찾아봤다.

종류

  • %s : 문자열을 출력
  • %d : 정수를 출력
  • %f : 실수를 출력
  • %b : 이진수를 출력
  • %o : 8진수를 출력
  • %x : 16진수를 출력
  • %c : 문자를 출력
  • %% : 문자 %를 출력
  • %()b : 이안에 숫자가 들어가면 자릿수를 표현한다.

코드

package main

import "fmt"

func main() {
	fmt.Printf("%s\n", "Hello, world!")
	fmt.Printf("%d\n", 123)
	fmt.Printf("%f\n", 3.14159)
	fmt.Printf("%b\n", 1010)
	fmt.Printf("%o\n", 12345)
	fmt.Printf("%c\n", 'a')
	fmt.Printf("%x\n", 12345)
	fmt.Printf("%%\n")
	fmt.Printf("%10d\n", 123)
	fmt.Printf("%.2f\n", 3.14159)
	fmt.Printf("%8x\n", 123)
}

출력

Hello, world!
123
3.141590
1111110010
30071
a
3039
%
       123
3.14
      7b

한 눈에 끝내는 고랭 기초 !!

profile
싱숭생숭늉

0개의 댓글