728x90

9.1 포인터 개요

1) 메모리
프로그램이 실행되기 위해 필요한 정보(값)을 저장하는 공간
- 1byte (8 bits) 단위로 물리 주소가 부여되어 있음
- 개념적으로, 메모리는 일렬로 연속되어 있는 크기가 1 byte인 방들의 모음이라고 볼 수 있음
- 일반적으로 주소의 길이는 4 bytes이고 주소는 16진수로 표현

2) 메모리와 변수의 관계
변수는 선언될 때, 메모리에 그 변수를 위한 공간이 할당
- 주소연산자(&): 변수에 할당된 메모리 공간의 시작 주소를 구해줌
- 한번 할당되면 주소는 고정된다.

3) C프로그램에서 변수의 의미
- 그 변수에 할당된 공간: 선언 또는 대입문의 왼쪽 변수로 사용될 때
- 그 변수에 저장된 값: 대입문의 오른쪽 변수, 조건식, 함수의 인수로 사용될 때

4) 포인터(자료형)
주소를 나타내는 특수 자료형
- 주소는 기본적으로 양의 정수로 표현됨
- 하지만 int와는 구별되어 처리됨

(1) 선언
- 변수명 앞에 *(참조연산자) 사용

char *pch;



(2) 연결
- &(주소연산자)를 이용해 포인터 변수를 다른 변수에 연결

pch = &ch;



(3) 참조
- *(참조연산자)를 이용해 포인터에 연결된 변수에 접근

printf("%c", *pch);



9.2 포인터 선언과 사용

1) 포인터(변수) 선언
- 변수명 앞에 *(참조연산자)만 덧붙이면 된다
- 기존의 자료형 표시 + 포인터라는 표시

int *pch;
char *pnum;



2) 초기화
- 일반변수 초기화 형태와 동일하다
- 초기화할 주소를 가진 변수(num)가 먼저 선언되어야 한다

int num, *pnum = #



3) 포인터 변수 선언의 다양한 형태
- 동일 기본 자료형에서 파생된 자료형의 변수는 모아서 선언 가능
- 그러나 가독성 때문에 추천 안함

4) 포인터 대입(연결)
- 포인터(변수)에 주소를 대입하여 특정 변수와 연결 시키는 것을 "가리킨다"라고 표현

pch = &ch;



5) 포인터 참조
- 포인터(변수)가 가리키는 변수에 접근하는 것
- 참조연산자 * 를 사용

printf("%c", *pch);



6) 참조 연산자를 이용한 대입
>>코드

char ch = 'A', *pch = &ch;
*pch = 'B' // 간접 접근: ch를 'B'로 변경
ch = 'C' // 직접 접근: ch를  'C'로 변경


7) 추가
- int *pnum = # 은 정수를 나타내므로 정수를 사용하는 어떤 형태나 계산에 사용가능
- 단, 참조연산자와 다른 연산자와의 우선순위에 주의해서 사용

8) 정리
주소연산자(&): 해당 변수의 주소값
- 변수 이름: 변수 영역 또는 변수에 저장된 값
참조연산자(*): 포인터가 가리키는 변수
- pnum과 &num의 값은 동일하지만, 지칭하는 부분은 다르다.
pnum은 num과 연결된 포인터 변수의 값이고, &num은 num에 할당된 메모리 시작 주소이다.

9) Null 포인터
주소 값 0을 나타내는 특별한 기호
- 아무것도 가리키지 않음을 의미
- null의 값은 0 이므로, 조건문에서 사용하면 거짓에 해당
- 예기치 못한 오류 방지를 위해 포인터 변수를 null로 초기화

int *pnum = NULL;



10) 포인터 주의 사항
- 주소연산자(&)는 포인터를 포함한 모든 변수에 사용 가능
참조연산자(*)는 포인터 변수에서만 가능
- 포인터의 자료형과 연결된 변수의 자료형은 일치해야 한다

11) 포인터의 크기
- 포인터의 종류(자료형)에 관계없이 주소를 저장하기 위해 필요한 공간은 동일
- 단, 포인터의 크기는 시스템에 따라 다를 수 있음

9.3 배열과 포인터

1) 배열 이름의 비밀
배열 이름은 배열의 0번 원소의 시작 주소를 의미한다. (특별하다)
- 만약 ar[10]이란 배열이 있다면 
>> ar은 ar[0]의 주소를 의미
>> &ar은 전체 배열(ar[])의 주소를 의미

2) 주소를 이용한 배열 참조
- 배열 이름은 주소를 의미하므로, 참조 연산자와 함께 사용 가능
- ar: 0번 원소의 주소( == &ar[0])
- *ar: 0번 원소의 주소에 저장된 값, 즉 0번 원소의 값을 의미

3) 배열 주소에 대한 증감 연산
- 배열 원소 하나의 크기만큼 증가 or 감소
ar+i: 배열 ar의 i번째 원소의 주소
*(ar+i): 배열 ar의 i번째 원소의 값

4) 배열을 포인터 변수에 연결하여 사용하기
- 배열 이름은 주소를 의미하므로, 포인터 변수에 대입가능
- 포인터 변수에 대한 증감연산 
포인터 변수가 나타내는 자료형의 크기 단위로 끝자리가 증가 or 감소

5) 포인터 변수도 배열의 첨자 형태로 값을 참조할 수 있다

int ar[5] = {1, 2, 3, 4, 5};
int *p = ar;



6) 배열과 포인터의 관계 정리
배열과 포인터는 동일한 형태로 사용가능(둘다 주소이기 때문)
주소에 1을 더하면 원소의 크기만큼 주소가 증가
- 주소가 주어졌을 때, 해당 주소에 저장된 원소값은 다음 두가지형태로 참조 가능
>> ar[3]과 p[3]: 배열의 첨자 연산자 [] 사용
>> *(ar+3)과 *(p+3): 포인터의 참조 연산자 * 사용

7) 배열과 포인터 주의 사항
포인터를 배열의 중간 원소에 연결 시키는 것도 가능
- 포인터는 단지 자신이 가리키는 주소를 기준으로 배열처럼 쓰는 것일 뿐
- 포인터의 참조 연산자 사용 시 괄호에 유의
포인터 변수의 증감량은 가리키는 배열의 원소 크기가 아니라 포인터 자신의 자료형에 의해 결정

728x90
728x90

20240318 백준 C언어 공부
10798번 세로 읽기

1. 문제
아직 글을 모르는 영석이가 벽에 걸린 칠판에 자석이 붙어있는 글자들을 붙이는 장난감을 가지고 놀고 있다. 

이 장난감에 있는 글자들은 영어 대문자 ‘A’부터 ‘Z’, 영어 소문자 ‘a’부터 ‘z’, 숫자 ‘0’부터 ‘9’이다. 
영석이는 칠판에 글자들을 수평으로 일렬로 붙여서 단어를 만든다. 
다시 그 아래쪽에 글자들을 붙여서 또 다른 단어를 만든다. 
이런 식으로 다섯 개의 단어를 만든다. 아래 그림 1은 영석이가 칠판에 붙여 만든 단어들의 예이다. 

A A B C D D
a f z z 
0 9 1 2 1
a 8 E W g 6
P 5 h 3 k x
<그림 1>

한 줄의 단어는 글자들을 빈칸 없이 연속으로 나열해서 최대 15개의 글자들로 이루어진다. 
또한 만들어진 다섯 개의 단어들의 글자 개수는 서로 다를 수 있다. 

심심해진 영석이는 칠판에 만들어진 다섯 개의 단어를 세로로 읽으려 한다. 
세로로 읽을 때, 각 단어의 첫 번째 글자들을 위에서 아래로 세로로 읽는다. 
다음에 두 번째 글자들을 세로로 읽는다. 
이런 식으로 왼쪽에서 오른쪽으로 한 자리씩 이동 하면서 동일한 자리의 글자들을 세로로 읽어 나간다. 
위의 그림 1의 다섯 번째 자리를 보면 두 번째 줄의 다섯 번째 자리의 글자는 없다. 
이런 경우처럼 세로로 읽을 때 해당 자리의 글자가 없으면, 읽지 않고 그 다음 글자를 계속 읽는다. 
그림 1의 다섯 번째 자리를 세로로 읽으면 D1gk로 읽는다. 

그림 1에서 영석이가 세로로 읽은 순서대로 글자들을 공백 없이 출력하면 다음과 같다:

Aa0aPAf985Bz1EhCz2W3D1gkD6x

칠판에 붙여진 단어들이 주어질 때, 영석이가 세로로 읽은 순서대로 글자들을 출력하는 프로그램을 작성하시오.

2. 입력
총 다섯줄의 입력이 주어진다. 
각 줄에는 최소 1개, 최대 15개의 글자들이 빈칸 없이 연속으로 주어진다. 
주어지는 글자는 영어 대문자 ‘A’부터 ‘Z’, 영어 소문자 ‘a’부터 ‘z’, 숫자 ‘0’부터 ‘9’ 중 하나이다. 
각 줄의 시작과 마지막에 빈칸은 없다.

3. 출력
영석이가 세로로 읽은 순서대로 글자들을 출력한다. 이때, 글자들을 공백 없이 연속해서 출력한다. 

>>>코드

# include <stdio.h>
int main(void){
    char x[5][15] = {0}, tmp;
    for (int i = 0; i<5; i++){
        scanf("%s", x[i]);
    }
    for (int i = 0; i<15; i++){
        for (int j = 0; j<5; j++){
            if (x[j][i] == NULL) continue;
            printf("%c", x[j][i]);
        }
    }
    return 0;
}



>> Char 문자형에서 0은 NULL이다

>>>문제링크
https://www.acmicpc.net/problem/10798

728x90

+ Recent posts