
제가 대학교 1학년 때 C언어 수업에서 배운 내용을 교재와 ppt를 중심으로 정리한 내용입니다. (2022.3 ~ 2022.6)
당시에 공부를 위해서 HWP 파일로 정리해 놓은 것을 그대로 올립니다.
대학에 처음 들어와 정리한 내용이라 모든 내용을 담고 싶은 욕심에 정리가 많이 지져분하고 어설픈점 양해 부탁드립니다..!
포인터 : 주소를 저장하는 변수
%p로 출력 or %#x로 출력하되 대응하는 변수를 적어줄 때 &붙이기메모리 : 연속된 바이트의 모음. 각 바이트 구분을 위해 주소(번지) 사용.
메모리 주소 공간 : 메모리 주소가 가질 수 있는 범위.
0x00000000번지 ~ 0xffffffff번지 사이의 값. (16진수 1자리는 4bit를 의미하므로)주소값 자체가 중요한 게 아니라 포인터가 어떤 변수를 가르키는지가 중요
포인터는 다른 변수를 가르킴. 다른 변수의 주소를 할당 받은 후, 해당 변수를 간접적으로 이용.
포인터는 변수의 이름을 사용할 수 없어도 주소로 변수에 접근 가능한 방법을 제공.
데이터형 *변수명; 데이터형 *변수명 = 초기화; 형식으로 선언,* : 포인터 수식어. 그다음에 써주는 변수를 포인터로 만듦.int* 형의 포인터 = int 포인터 = int 변수를 가르킴&를 이용. 데이터형 *변수명1 = &변수명2;NULL으로 초기화. 0번지를 의미하는 것이 아닌 포인터가 어떤 변수도 가리키지 않는단 것 의미.NULL 대신 0을 사용할 수도 있음.NULL : 널포인터. 표준 C라이브러리에 0으로 정의된 매크로 상수(int*)16진수주소를 대입시 컴파일 에러는 나지 않지만, 무엇이 들었는지 모르는 상황에서 포인터로 접근시 실행에러 발생 가능성 존재. & 연산의 결과는 해당 변수의 주소& 연산자는 반드시 변수와 함께 사용해야 하며, 상수나 수식엔 사용 불가.포인터 변수를 선언 후에, 포인터 변수 앞에 *를 쓰면 포인터가 가리키는 변수의 값을 읽어오거나 변경 가능.
연산의 결과는 포인터가 가르키는 변수
* 가 할당 연산자 오른쪽에 위치 → 포인터 변수가 참조하는 변수의 메모리 공간*를 단독으로 사용 → 현재 포인터 변수가 참조하는 변수의 데이터역참조 연산자를 이용하면 변수의 이름을 모르더라도 주소로 해당 변수에 간접적으로 접근가능.
역참조 연산자를 사용하면 포인터가 가르키는 변수가 대신 사용.
일반변수(포인터 변수가 아닌)이나 상수, 수식에는 *를 사용할 수 없음.
p가 a의 주소를 저장하는 포인터 변수일 때, 역참조 연산자를 포인터 변수에 사용하면 *p 대신 a가 사용되는 것처럼 처리.const 변수로 선언 가능const의 위치에 따라 의미가 달라짐.const type *variable; = type const *variable;const 변수인 듯 사용 → 변수의 const 여부와는 상관없이 const 포인터로 접근시에만 const 변수로 사용const int* p1 = &a; → a는 const 변수 X*p1 → p1으로 역참조한 변수를 const 변수인 듯 사용type *const variable; const type *const variable;p가 배열 arr를 가리킬 때 *(p+i) 는 arr[i]를 의미p + N → 주소에 p가 가르키는 데이터형의 크기를 N개만큼 더한 주소
p – N → 주소에 p가 가르키는 데이터형의 크기를 N개만큼 뺀 주소
p1 – p2 → 포인터가 가르키는 데이터형의 개수로 주소의 차를 구함.
같은 형의 포인터에 대해서 빼기 연산 수행 시 두 포인터의 주소 차, 즉 가리키는 데이터형이 몇 개 크기만큼 차이가 나는지 구할 수 있음.
p++ → 주소를 포인터가 가르키는 데이터형의 크기만큼 증가 → 포인터가 가리키는 배열의 다음원소를 가리킴.
p-- → 주소를 포인터가 가리키는 데이터형의 크기만큼 감소 → 포인터가 가리키는 배열의 이전원소를 가리킴.
p1 = p2 → 같은 형의 포인터끼리 대입
p1 == p2 → 주소가 같은지 비교
p1 != p2 → 주소가 다른지 비교
p[N] → 포인터 배열 이름인 것처럼 사용해서 N번째 원소에 접근
*p = p가 가리키는 변수에 접근
&p → p의 주소를 구함
p → m → p가 가리키는 구조체의 멤버 m에 접근
type*형의 포인터는 type형의 변수(크기가 1인 type형의 배열으로 볼 수 있음) 또는 type형 배열의 원소를 가리킬 수 있음.arr = &arr[0]p[i] = *(p + I) → 배열 시작 주소에서 배열 원소 I개만큼 떨어진 곳에 있는 int 변수sizeof(배열명)은 배열 전체의 바이트 크기를 구하지만, sizeof(포인터명)은 포인터 변수의 크기를 구함.데이터형 함수이름(데이터형 변수명, 데이터형 변수명);데이터형 함수이름(데이터형 변수명, 데이터형 변수명, 데이터형 *변수명, 데이터형 *변수명);함수의 원형을 정할때는 출력 매개변수를 포인터로 선언
함수를 호출 시 처리 결과를 받아올 변수의 주소 전달
&를 붙여서 전달함수 정의 시 포인터형의 매개변수가 가리키는 곳에 처리 결과를 저장.
*변수이름 = 값입출력 매개변수 → 참조에 의한 호출
데이터형 함수이름(데이터형 *변수명, 데이터형 *변수명);함수의 인자가 배열인 경우, 해당 배열의 값을 복사하여 전달하는 것이 아닌 항상 주소를 전달한 후 매개변수인 포인터로 해당 메모리 공간을 사용할 수 있게함.
C에선 배열을 함수의 인자로 전달할 때 항상 포인터로 전달, 참조에 의한 호출 사용.
배열의 크기는 별도의 매개변수로 받아와야함.
sizeof를 사용시 항상 같은 값이 나옴.함수 호출 시 배열을 전달하려면, 배열 이름(배열의 시작주소)를 전달
함수 안에서는 포인터형의 매개변수를 배열처럼 사용.
→ 배열의 주소를 전달해서 매개변수인 포인터를 이용해서 포인터를 배열처럼 사용한다고 이해.
배열이 입력매개변수 일때는 읽기 전용 포인터로 선언하는 것이 좋음.
함수의 원형을 정할 때 함수의 매개변수는 배열의 크기를 생략하고 선언하거나 배열 원소에 대한 포인터 형으로 선언.
→ 데이터형 배열이름[] = 데이터형 *배열이름