우리 학교 1학년 2학기 전공 필수 과목인 고급 C프로그래밍 스터디의 멘토를 맡아 진행하게 되었다.
1학년 학생들의 전공에 대한 흥미를 확대하고 다음 학기에 대한 예습과 개념 이해를 통해 프로그래밍 능력을 증진 시키고 공학인증에 어려움을 겪었던 우리 신입생들에게 도움을 주기 위한 스터디다.
포인터(1주) - 문자열(1주) - 구조체(1주) - 동적 할당(1주) 총 4주간 진행했다.
강의 자료를 활용한 수업을 진행한 뒤 간단한 실습 문제를 풀이해준 후 몇가지 문제를 풀어보게 하고 숙제로 과제 문제도 부여했다.
다음 수업에 과제 문제를 서로 어떻게 해결했는지 스터디원끼리 발표하고 다른 사람의 코드도 이해해보며 성장하는 시간을 가졌다.
스터디 내용들을 살짝 적어보자면, 요런 내용들로 진행했다.
메모리란 ?
프로그램이 실행되기 위해 필요한 정보를 저장하는 공간으로, 1바이트 단위로 16진수로 표현된 물리주소가 부여되어 있다. 일반적으로 주소의 길이는 4바이트다.
포인터란 ?
프로그래머가 변수를 선언하면 컴퓨터는 메모리에 우리가 사용할 변수를 위한 공간을 할당해주게 되고 이 할당된 변수에 접근하기 위해서는 해당 위치에 대한 주소가 필요한데, 이때 0x00~같은 주소를 가리키는 것이 바로 포인터다.
주소 연산자 & : 메모리 내 위치를 보는 방법은 바로 변수 앞에 주소 연산자인 '&'를 붙이는 것이다. 이는 변수의 시작 주소를 출력해주는 연산자이다. 주소 연산자는 포인터 변수를 포함한 모든 변수에서 사용할 수 있다.
포인터 선언 방법 : 자료형 앞에 *을 붙여 포인터 자료형으로 선언할 수 있다 (ex. int *A;). 포인터라는 자료형은 기본적으로 양의 정수로 표현되나, 일반적인 정수형 자료형과 구별되어 처리된다.
참조 연산자 * : 포인터 변수 앞에 참조 연산자 '*'를 붙이게 되면 해당 주소가 가리키고 있는 변수의 '값'을 참조하게 된다. 참조 연산자를 이용한 포인터 변수의 덧셈 등의 계산 또한 가능하다. 참조 연산자는 오직 포인터 변수에서만 사용 가능하다.
포인터 변수를 아무 변수에도 연결하지 않고 그냥 정수를 넣어 사용한다면 컴파일 에러가 발생한다. 정수에는 주소값이 없기 때문이다. 이 오류는 포인터 변수를 처음 선언했을때 안에는 목적지 없는 주소인 쓰레기 값이 들어가 있기 때문이다. 따라서 처음 포인터 변수를 선언하고 바로 변수를 연결하지 않을 것이라면 'NULL' 값을 이용해 초기화 해두는 편이 좋다. ex. int *pA = NULL ;
또한, 포인터 변수를 일반 변수에 연결 할 때는 같은 자료형끼리만 가능하고 포인터의 크기는 어떤 자료형의 포인터인지에 관계 없이 모두 동일하다. sizeof 연산자를 통해 확인 가능하며 컴퓨터 시스템에 따라 값은 다를 수 있다.
포인터와 배열 : 기존 C프로그래밍 및 실습 수업에서는 배열을 그저 자료형으로 선언해서 사용했다. 사실 배열은 연속된 포인터의 나열이라 볼 수 있다. 일반 변수 x,y,z를 선언하면, 커다란 메모리 안에서 임의의 주소 3개를 받아 각각 할당한다. 즉 모두 따로 떨어져 존재하게 된다. 그러나 크기 3짜리 배열 ar[3]을 선언하면 붙어있는 주소 3개를 한번에 할당해주게 된다. 이때 이 배열의 이름이 바로 배열의 시작 주소를 가리키는 '포인터'이다.
다중 포인터 : 변수의 주소를 저장하는 변수는 포인터 변수이고 이 포인터 변수의 주소를 저장하는 곳에는 이중 포인터를 사용할 수 있다. 간단히 *을 하나 더 붙이는 것으로 해결 가능하다. *을 붙일수록 N중 포인터로 사용이 가능하다.
그렇다면 C언어에서 이러한 복잡한 개념인 포인터를 사용하는 이유는 무엇일까? 함수를 통해 설명할 수 있는데, 함수의 인자로 변수를 넘긴 경우 변수가 아닌 정수값만 이동하기 때문에 함수 내에서 값을 바꾸었다 하더라도 main의 값이 변하지 않는다. 이에 반해 함수의 인자로 포인터(주소)를 넘긴 경우, 이동할 때 pA의 값이 넘어가는 것이지만, 이는 main에서 pA가 가리키는 a와 함수로 넘어간 주소값이 가리키는 a가 동일하므로 변경 내용이 유지된다. 정리하자면 c언어에서 변수는 선언된 블록 즉, 함수 내부에서만 그 변수를 사용할 수 있고 같은 변수명을 사용한다 하더라도 블록이나 함수가 다르면 별도의 저장 공간을 확보하므로 전혀 다른 변수로 사용된다. 이 때 변수 대신 메모리의 주소 값을 이용해 메모리에 접근하는 포인터를 사용하면 사용 범위를 벗어난 경우에도 데이터를 공유할 수 있게 된다.
하지만 포인터를 사용하려면 추가적으로 포인터 변수를 선언해야 하고 주소, 참조 연산 등 추가적인 작업이 필요해 굳이 즐겨 쓸 필요는 없다. 그러나 임베디드 프로그래밍 등 메모리에 직접 접근하는 경우나 동적 할당한 메모리를 사용하는 경우에는 포인터가 반드시 필요하다.
대면 스터디와 비대면 스터디를 병행했는데, 비대면 스터디는 Discord를 이용했었다.
직접 코드를 작성해보게끔 하고 피드백을 주고 다시 코드를 작성하게 한 뒤
샘플 코드를 짜서 보여주는 식으로 진행했다.
인증시험 잘봤다고 연락 줬을때 젤 기뻤다 ..
뿌듯하고 .. 방학에 스터디 나와서 공부했던 친구들도 기특하구 .. ㅎㅎ
1학년땐 나도 어려웠던 C였지만 나름 3학년이라고 쉽게 느껴지는 게 신기하기도 했고,
멘티들이 알려준 내용을 이해했을 때의 쾌감과 시험 잘봤다고 연락 줬을 때의 뿌듯함이 참 좋았다~
앞으로 더 멋찐 선배가 돼서 마니 아르켜 줄게 ~
'Else' 카테고리의 다른 글
[ Terminal ] 터미널 커스텀 (0) | 2025.03.03 |
---|