[JAVA] 비트 연산자, 반복문과 배열

지수·2021년 6월 29일
0

플레이데이터

목록 보기
2/50
post-thumbnail

1. 비트 연산자

💡 비트 연산자
: 비트(bit) 단위로 연산이 이루어지는 연산자

  • 암호화, 마스킹(masking: 특정 비트를 꺼내보는 경우) 시 사용
  • IoT(Internet of Things) 신호 관련 연산 시 사용
  • 메모리 용량이 부족하거나 계산이 복잡해 속도가 느릴 때 곱셈, 나눗셈에 사용

비트 논리 연산자

: 비트 단위로 &, |, ^, ~ 연산 진행

1) &(and) 연산자
: 두 개의 비트 값이 모두 1인 경우에만 연산 결과 값이 1

int num1 = 5;			// num1: 0000 0101
int num2 = 10;			// num2: 0000 1010
int num3 = num1 & num2;		// num3: 0000 0000

2) |(or) 연산자
: 두 개의 비트 값 중 하나라도 1이면 연산 결과 값이 1

int num1 = 5;			// num1: 0000 0101
int num2 = 10;			// num2: 0000 1010
int num3 = num1 | num2;		// num3: 0000 1111

3) ^(xor) 연산자
: 두 개의 비트 값이 같은 값이면 0, 다른 값이면 1

int num1 = 5;			// num1: 0000 0101
int num2 = 10;			// num2: 0000 1010
int num3 = num1 ^ num2;		// num3: 0000 1111

4) ~(반전) 연산자
: 비트 값 0은 1로, 1은 0으로 바꿈

int num = 10;			// num1: 0000 1010
int result = ~num;	      // result: 1111 0101

+) 위의 result값 1111 0101은 부호 비트가 0에서 1로 바뀌어 음수가 됨


비트 이동 연산자(shift)

: 비트 단위로 이동(shift) <<,>>,>>> 세 종류

1) << 연산자
: 왼쪽으로 비트 이동 = 기존 값에 2^n만큼 곱함

int num = 5;		// num: 0000 0101 = 5
num << 2;	   // num << 2: 0001 0100 = 5 * 2^2 = 20

2) >> 연산자
: 오른쪽으로 비트 이동 = 기존 값이 2^n만큼 나눔
왼쪽에 채워지는 값은 기존 값의 부호 비트와 동일

int num = 10;		// num: 0000 1010 = 10
num >> 2;	   // num << 2: 0000 0010 = 10 / 2^2 = 2

3) >>> 연산자
: >> 연산자와 동일하게 오른쪽으로 비트 이동
왼쪽에 채워지는 값이 기존 값과 상관없이 무조건 0

🧨 컴퓨터는 실제로 가산연산(+) 밖에 하지 못하기 때문에 곱하기를 다 더하기로 변환하여 처리 => 큰 수를 곱할 때 느려짐
🧨 2의 제곱수만큼 곱하거나 나누는 연산을 할 때 비트 연산을 활용하면 빠르게 연산할 수 있음
(2진수 자리를 이동하는 방법으로 연산하면 훨씬 빠름, 컴퓨터는 2진수가 더 편함)



2. 반복문

💡 반복문
: 제어문 중 하나로(제어문: 반복문, 조건문), 프로그램 소스 코드 내에서 특정한 부분의 코드가 반복적으로 수행되도록 하는 구문
▶ 유사한 코드가 3번 이상 반복되면 반복문을 생각하자!

for문

: 몇 번 반복 하는지 아는 경우

for(**초기화식; 조건식; 증감식**) {
	수행문;
}
-------------------------------------------------------
for(int i = 0; i < 10; i++) {
	System.out.println(i);
}  // 10회 반복하여 i값(0,1,2,...,9) 출력

while

: 몇 번 반복 하는지는 모르고, 조건이 만족하는 동안 실행할 경우

**변수 선언**
while(**조건식**) {
      **수행문1;**
      **증감식**
}
수행문2;
-------------------------------------------------------
int num = 0
while(num < 10) {
	System.out.println(num);
    	num++;
}  // 10회 반복하여 num값(0,1,2,...,9) 출력
System.out.println("loop end");  // 반복문이 끝나면 출력

do-while(자주 사용 X)

: while과 동일 + 최소한 한 번 이상 실행되어야 할 경우

**변수 선언**
do {
      **수행문1;**
      **증감식**
}
while(**조건식**) {
      **수행문2;**
}
수행문3;
-------------------------------------------------------
int num = 1;
int sum = 0;
do {  // 조건과 관계없이 1번 실행
      sum += num;
      num++;
}
while(num <= 10) {  // 조건 확인 후 참이면 계속 진행
      System.out.println("1부터 10까지의 합은 "+sum+"입니다.");
}
System.out.println("loop end");  // 반복문이 끝나면 출력

반복문 관련 주의사항

🧨 for문과 while문은 선 비교, 후 실행 구문(=조건이 참이면 실행)

🧨 조건문 판단 시, <과 <= 중 <=가 시간을 더 많이 차지, 때문에 >,<만 쓰기를 권장

🧨 반복문 안에서 몇 번 반복되는지 세는 변수 = 제어 변수
(for문에서는 i, j, k, l, m, n을 주로 사용, while에서는 의미있는 변수명 지정하여 사용)

🧨 반복문 안에서 선언된 변수는 반복문 바깥에서 사용 불가
(for 반복문 안에서 선언된 i를 반복문 바깥에서 출력할 수 없음)
반복문 바깥에서도 변수를 사용해야할 경우, 반복문 안에서 변수 선언하지 않고, (for문 변수 초기화 생략) 이전에 변수 별도로 선언

  • while문 안에서 for문 사용 가능
  • for문 안에서 for문 이중으로 사용 가능
  • while문이나 for문 안에서 if문 사용 가능
    ...

🧨 조건만 충돌하지 않는다면 제어문 이중 사용 가능


break와 continue

breakcontinue를 사용하면 반복문 중에 블럭에서 벗어날 수 있음

💡 break문
: 반복문에서 break문을 사용하면 그 지점에서 더 이상 수행문을 반복하지 않고 반복문을 빠져나옴
🔽 1부터 10까지 반복하여 출력할 때, 5 이상은 출력하지 않는 구문(break 활용 예제)

for(int i = 0; i < 10; i++) {
	if(i+1 > 4) {
		break;  // i+1이 5가 되면 더 이상 수행문 반복하지 않고
        		// 반복문을 빠져나옴
	}
	System.out.println(i + 1);
}

💡 continue문
: 반복문에서 continue문을 사용하면 이후의 문장은 수행하지 않고 반복문의 처음으로 돌아가 증감식을 수행
🔽 1부터 10까지 반복하여 출력할 때, 5만 출력하지 않는 구문(continue 활용 예제)

for(int i = 0; i < 10; i++) { 
	if(i+1 == 5) {
		continue;  // i+1이 5일 때 이후 출력을 수행하지 않고
        		   // for문 상단으로 돌아가 증감식 수행
	}		   // 6부터 다시 출력
	System.out.println(i + 1);  // 0~9니까 +1 해서 출력
}

label break/continue

: 원래 break/continue문은 자신이 속한 블럭에서만 작용
break => 자신이 속한 반복문만 빠져나옴
continue => 자신이 속한 반복문 이하만 수행하지 않고 앞으로 돌아감

🧨 반복문에 label을 주고, break label명 을 하면 break문이 해당 반복문에 바로 속해있지 않더라도 빠져나올 수 있음
🧨 continue도 마찬가지

// 구구단에서 5단 이후는 출력하지 않는 구문
loop: for(int i = 1; i < 10; i++) {
	for(int j = 1; j < 10; j++) {
    	   if(i > 4) {
           	break loop;  // loop라는 이름의 반복문 전체 탈출
    	   }
            System.out.println(i+" * "+j+" = "+(i * j));
        }
        System.out.println();
}

값을 입력받은 후 연산하는 반복문 예제

🔽 "숫자를 입력받아서" 각 자리수의 합을 구하여 출력하라

Scanner sc = new Scanner(System.in);
System.out.println("숫자를 입럭하세요.");
int num = sc.nextInt();
// 숫자 입력 받아 num에 할당

int tot = 0;    // 전체 합 선언, 초기화
int quot, rem;  // 몫과 나머지 선언
quot = num;     // 입력받은 값을 초기 몫에 할당

// 10으로 나눈 나머지로 자리 수 하나씩 분리
while(quot != 0) {	   // 몫의 값이 0이 될 때까지 반복
    rem = quot % 10;      // 10으로 나눈 나머지 계산, 자리 수 분리
    tot += rem;		 // 전체 합산에 분리된 자리 수 더하기 
    quot /= 10;		// 몫의 값도 10으로 나눠주고 다시 반복
}
System.out.println("입력 받은 수의 모든 자리 수를 합한 값은 "+tot+"입니다.");


3. 배열

배열 선언과 초기화(자동 초기화)

💡 배열(array)
: 같은 타입의 변수들로 이루어진 유한 집합
배열을 구성하는 각각의 값: 배열 요소(element)
배열에서의 위치를 가리키는 숫자: 인덱스(index)

자료형[] 배열이름 = new 자료형[개수];
int[] arr = new int[5];
// 5개의 요소로 이루어진 수치형 배열 arr 선언
  • 배열은 선언과 동시에 자료값이 초기화 됨(자동 초기화)
    = 값을 일일히 넣어주지 않아도 기본값이 들어가 있음(ex. 0, 0.0, null, false)
  • 한 번 선언한 배열 크기는 바꿀 수 없음
  • 처음 선언한 전체 배열의 길이를 다 채울 필요는 없음(안 채워도 초기화 값이 들어가 있음)

🧨 배열 선언과 동시에 (기본값 아닌)값을 넣어 초기화 할 수도 있음

int[] arr = {1, 2, 3, 4, 5};
// 1,2,3,4,5 총 5개 요소를 갖는 배열 선언 및 초기화

배열의 길이.length

배열의 길이를 배열이름.length해서 알 수 있음

int[] arr = new int[5];
System.out.println(arr.length);  // = 5

🧨 length속성은 배열에서만 사용 가능

🧨 전체 배열 길이 != 유효한 요소의 수
처음에 선언한 배열 길이(length)가
언제나 기본값 외의 유효한 요소의 수와 같지는 않음
(유효한 값이 없는 부분에는 기본값이 채워져있음)

🧨 유효한 요소의 수를 세고 싶다면,
별도의 변수를 선언하여 배열 요소 초기화 시마다 카운트해줘야 함


다차원 배열 中 2차원 배열

💡 다차원 배열
: 2차원 이상의 배열, 배열 요소로 또 다른 배열을 가지는 배열

💡 2차원 배열
: 행과 열로 구성된 배열, 대괄호를 두 번 사용하여 선언

자료형[][] 배열이름 = new 자료형[행 개수][열 개수];
int[][] arr = new int[2][3];
// 2행 3열로 이루어진 수치형 이차원 배열 arr 선언
-------------------------------------------------------
int[][] arr = {{1,2,3}, {4,5,6}};
// 이차원 배열도 선언과 동시에 값을 넣어 초기화 가능

🧨 이차원 배열에서 배열이름.length를 하면 행 개수 반환
🧨 배열이름[행 인덱스].length를 하면 각 행의 열 개수 반환
배열은 참조형 변수이기 때문에 이차원 배열은 다른 배열을 요소로 갖는(참조하는) 배열, 하나씩 타고 들어가는 것


🧨 자바의 다차원 배열에서는 배열 속 배열의 값을 각각 다르게 할당 가능(다차원 배열의 관리)
= 2차원 배열에서 행별로 열의 개수가 다를 수 있음
🔽 반이 총 3개, 1반은 3명, 2반은 10명, 3반은 7명 학생이 있는 school 배열

int[][] school = new int[3][];  // 열 개수가 달라서 비워둠

school[0] = new int[3];
school[1] = new int[10];
school[2] = new int[7];  // 각각 나누어 배열 속 배열 선언

System.out.println(school.length);  // 행의 값, 3
System.out.println(school[0].length);  // 0행의 열 값, 3
System.out.println(school[1].length);  // 1행의 열 값, 10
System.out.println(school[2].length);  // 2행의 열 값, 7

▶ 위의 경우, 다른 언어는 최대치인 2반 학생 수(10명)에 맞추어 메모리를 할당하고 남는 부분은 쓰지 않음 => 3행 10열 배열 설계
▶ 자바는 참조하여 배열을 설계하기 때문에 각각의 값을 다르게 설계 가능


배열 복사(shallow copy, deep copy)

배열은 참조형 변수이기 때문에 기본형 변수처럼 복사되지 않음

💡 얕은 복사(shallow copy)

int[] arr = {1,2,3,4,5};
int[] brr = {10, 20, 30, 40, 50};

arr = brr;		// arr과 brr이 같은 인스턴스 참조

arr[2] = 99;		// arr[2] 값을 99로 다시 할당

System.out.println(arr[2]);  // 99
System.out.println(brr[2]);  // 99
// arr에 brr값을 복사하고 arr값만 바꿨다고 생각했는데 brr값도 영향을 받음

🧨 배열에 저장된 값은 인스턴스 자체가 아니고 인스턴스의 주소 값
🧨 객체 배열을 복사할 때 인스턴스를 따로 생성 X, 기존 인스턴스의 주소 값만 복사
▶ 두 배열이 같은 인스턴스를 참조
▶ 하나의 배열 값만 바꿔도 해당 인스턴스 값이 변경되어 두 배열이 다 영향을 받음

💡 깊은 복사(deep copy)
주소 값만 복사해오는 것이 아니라 값 자체를 복사해오고 싶다면 System.arryCopy() 메서드를 통해 deep copy를 해야함

int[] arr = {1,2,3,4,5};
int[] brr = {10, 20, 30, 40, 50};

System.arrayCopy(brr, 0, arr, 0, arr.length);
// (복사할 배열, 복사할 배열의 첫 위치, 붙여넣을 배열, 붙여넣은 배열의 첫 위치, 복사할 요소 개수)

arr[2] = 99;		// arr[2] 값을 99로 다시 할당

System.out.println(arr[2]);  // 99
System.out.println(brr[2]);  // 30


4. for문과 배열

2차원 배열과 이중 for문

for문은 배열과 함께 사용되는 경우가 많음
for문을 통해 배열의 요소를 전체 출력할 수 있음
2차원 배열의 요소를 전체 출력하기 위해서는 이중 for문이 필요함

🔽 2차원 배열의 전체 요소 출력하기

int[][] arr = new int[2][3];

for (int i = 0; i < arr.length; i++) {
	for (int j = 0; j < arr[i].length; j++) {
    	System.out.print(arr[i][j]);
    	}
    System.out.println();
}

개선된(향상된) for문(enhanced for loop)

  • 배열의 처음부터 끝까지 모든 요소를 참조할 때 사용
  • 부분만 돌 수는 없음, 전체 돌아야 함
  • 읽기 전용만 되어서 개선된 for문에서 값 수정 불가
// 개선된 for문
for (**변수** : **배열이름**) {
	반복 실행문;
}
-----------------------------------------------------------------
String[] strArray = {"Java", "C", "Python", "JavaScript"};

for (String lang : strArray) {  // 배열의 요소를 받을 lang 변수 선언
	System.out.println(lang);  // 배열의 각 요소가 출력됨
}
-----------------------------------------------------------------
int[] arr = {90, 30, 50, 80, 50};

for (int data : arr) {
	System.out.println("초기 데이터: "+data);
    	data = 100;  // data 값은 100으로 변경
    	System.out.println("for문 안에서 변경된 데이터: "+data);
}
System.out.println(arr[3]);  // 80
// for문 안에서 데이터 값을 다 100으로 바꿨지만,
// 이는 그 안의 data라는 변수 값만 바꾼 것
// 실제 arr값은 바꾸지 못함
profile
사부작 사부작

0개의 댓글