Yeom's
Yeom's Coding Note
Yeom's
전체 방문자
오늘
어제
  • 분류 전체보기 (262)
    • 백준온라인 (94)
    • 운영체제 (14)
    • 프로그래머스 (0)
    • Go Language (40)
    • AWS (1)
    • 자료구조 (21)
    • Effective Java 3E (41)
    • JPA (1)
    • Tech Interview (33)
    • MySQL 8.0 (7)
    • CS 기술면접 (7)
    • Linux (3)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • https://mangkyu.tistory.com/94
  • 출처 : 망나니 개발자
  • 망나니 개발자
  • Real MySQL 8.0
  • maeil-mail
  • UTM
  • m1 linux
  • 백준 설탕 배달
  • https://mangkyu.tistory.com/93
  • https://mangkyu.tistory.com/91
  • java
  • https://mangkyu.tistory.com/89
  • https://mangkyu.tistory.com/88
  • 망나니개발자
  • boj 2839
  • https://mangkyu.tistory.com/92
  • 교보dts
  • https://mangkyu.tistory.com/90
  • RealMySQL 8.0

최근 글

티스토리

hELLO · Designed By 정상우.
Yeom's

Yeom's Coding Note

포인터, 배열, 구조체
자료구조

포인터, 배열, 구조체

2023. 3. 18. 18:01
728x90
반응형

포인터 변수

  • 주소 값 만을 저장할 수 있는 변수
  • 팬 핸들을 통한 변수 접근
  • 즉, 변수명을 통한 접근

포인터 선언

int Date, Month;  <- Date Month 변수는 정수 타입

int *p  <- p가 가리키는 것은 정수 타입

float *q  <- q가 가리키는 것은 부동소수 타입

 

동적 변수 공간 할당

  • p = (int*) malloc(sizeof(int));
  • *p = 15; 
  • *p 는 힙 메모리 변수, p는 스택 메모리 변수

C/C++의 동적 변수 할당

  C C++
동적변수 할당 p = (int *)malloc(sizeof(int)); p = new int;
동적변수 해제 free p; delete p;

 

동적 변수 공간의 반납

  • *p 공간은 반납
  • p 공간은 그대로 유지
    -> p 안에 있는 값도 그대로 유지
    -> 결국, p를 따라가는 것은 문제가 됨

널 포인터

  • '현재 아무것도 가리키지 않고 있다' 는 의미
    - 값이 정의가 안된(Undefined) 포인터와는 의미가 다름
    - 포인터를 통하여 가지 말아야 할 곳을 가지 않도록 조치하는 역할을 함
  • free(p);  p가 가리키는 변수 공간을 반납
  • p = NULL;  p를 따라가지 않도록

주소 연산자 앰퍼샌드(Ampersand, &)

int Date, month;

int *p;

p = &Date;

 

  • &Date <- 'Address of Date'
  • p = &Date; <- 변수 Date의 주소 값을 포인터 변수 p에 할당
  • 변수 Date에 대한 두 가지 접근 방법: Date = 12 또는 *p=12;

Reference, Dereference

  • *&Date = 15;
    - *(&Date)는 '변수 date의 주소 값이 가리키는 곳의 내용(가리키는 곳의 공간)'
    - 변수 Date의 주소 값이 가리키는 것이라는 것은 변수 Date 그 자체
  • 변수를 주소 값으로 매핑(Mapping)시키는 함수가 앰퍼샌드(&)
  • 주소 값을 그 주소가 가리키는 변수로 매핑시키는 함수가 애스터리스크(*)
  • 역함수 이므로 *&Date = Date와 동일한 의미

저네릭 포인터(Generic Pointer)

  • 포인터는 그것이 가리키는 변수의 타입에 따라 분류
  • 가리키는 변수에 따라 읽어와야 할 데이터의 분량이 달라짐
  • void *Ptr;
    - 선언 시에는 가리키는 대상을 명시하지 않음

Ptr = (float*)malloc(sizeof(float));

  • 타입변환 연산자에 의해 실행 시 포인터의 타입을 할당
  • float *Ptr; 로 선언되었다면 (float*)는 없어도 된다.
  • 단, 주석 효과를 기대하기 위해 사용할 수는 있다.

댕글링 포인터(Dangling Pointer)

int *p,*q;

p = (int*)malloc(sizeof(int));

*p = 15;

q = p;

free(p);

p = NULL;

*q = 30;

 

가비지(Garbage)

반납도 접근도 할 수 없는 공간

int *p, *q;

p = (int*)malloc(sizeof(int));

q = (int*)malloc(sizeof(int));

*p = 5; *q = 20;

p = q;

상수 변수, 상수 포인터, 배열

상수 변수

  • int a = 24;
  • const int* Ptr = &a;

상수 포인터

  • 포인터가 항상 일정한 메모리 주소를 가리킴
  • int* const Ptr = new int; *Ptr = 25;
  • int a;
  • Ptr = &a (이것은 오류)

배열

  • 배열 이름은 배열의 시작 주소 값을 지님. 즉 포인터에 해당
  • 배열은 프로그램 시작 시에 메모리 위치가 고정
  • 따라서 배열 변수는 일종의 상수 포인터에 해당

참조 호출, 값 호출 (Call by Reference, Call by Value)

참조 호출

  • Call by Reference
  • 원본 전달 호출

값 호출

  • Call by Value
  • 사본 전달 호출

실제 파라미터, 형식 파라미터

  • CallMe(int a); 가 있을 때, 호출 함수가 CallMe(n);으로 호출
    - 호출 함수의 n = 실제 파라미터(Actual Parameter)
    - 피호출 함수의 a = 형식 파라미터(Formal Parameter)
  • 참조 호출에서는 실제 파라미터와 형식 파라미터는 동일한 객체
  • 값 호출에서는 실제 파라미터와 형식 파라미터가 서로 다른 독립적인 객체

에일리어스

앰퍼샌드(&)

  • Address 연산자가 아님
  • 에일리어스(Alias, Reference, 별명)을 의미
  • 호출함수에서 던져준 변수 n을 '나로서는 일명 pi'로 부르겠다
  • 참조호출의 효과(본명이나 별명이나 동일한 대상)

왜 에일리어스를 사용하는가?

  • 포인터 기호 없이 간단하게 참조 호출
  • 호출함수에서는 변수 자체를 전달
    - 피호출 함수에서 에일리어스로 받으면 참조 호출, 그냥 받으면 값 호출
    - 즉, 호출함수 입장에서는 피호출함수가 참조 호출을 지원하는 지, 값 호출을 지원하는지를 인식하지 않아도 됨

두 가지 스왑

  void swap (int *x, int *y)              

  {   int temp; 

      temp = *x; *x = *y; *y = temp; 

  } 

  void main( ) 

  {   int a = 20; 

      int b = 40; 

         swap(&a, &b);  변수 a, b의 주소 값 전달 

      cout << a; cout << b; 

  } 

  void swap (int& x, int& y)  int& x와 int &x는 동일한 기호임 

  {  int temp;                    

      temp = x; x = y; y = temp; 

  } 

  void main( ) 

  {  int a = 20; 

     int b = 40; 

       swap(a, b);   변수 a, b를 그대로 전달 

       cout << a; cout << b; 

  }

 

C++의 복사 생성자

세 가지 경우 호출됨

  • 함수 호출 시 객체가 파라미터로 전달될 때
    - triangleClass T1; Call(T1);
  • 객체를 선언하면서 바로 다른 객체 값으로 초기화 했을 때
    - triangleClass T1; T1.Base = 10; T1.Height = 20; triangleClass T2 = T1;
  • 피호출함수가 호출함수에게 객체를 리턴 값으로 전달할 때
    - triangleClass T1; ..., return T1;

기본 복사 생성자

  • 시스템이 자동으로 적용하는 디폴트 복사 생성자
  • 프로그래머가 직접 관리하는 사용자 복사 생성자를 사용하는 것이 좋음

얕은 복사, 깊은 복사

  • 사용자 복사 생성자 : 깊은 복사(Deep Copy)
  • 디폴트 복사 생성자 : 얕은 복사(Shallow Copy)

복사 생성자와 할당 연산자

복사 생성자 할당 연산자
triangleClass T1;
T1.Base = 10; T1.Height = 20;
triangleClass T2 = T1;
triangleClass T1, T2;
T1.Base = 10; T1.Height = 20;
T2 = T1;

 

배열

직접 접근

  • 인덱스 계산에 의해 해당 요소의 위치를 바로 알 수 있음
  • &A[i] = &A[0] + i * Sizeof(Element Type)

배열과 포인터

배열의 정체는 다름 아닌 포인터

  • 배열 요소를 포인터로 표현할 수 있음
  • 포인터 산술연산(Pointer Arithmetic)
    - A + 1 = A + 1 * Sizeof(Array Element)

배열의 전달

  • 단순타입과 달리 값 호출로 배열요소가 복사되지는 않음
  • 배열변수 이름, 즉 포인터 값만 값 호출로 복사되어 넘어감
  • 따라서 피호출함수에서 작업을 가하면 이는 원본을 건드리는 참조호출 효과

동적 배열

정적 배열과 동적 배열

void Fuction1(int Size)

{

   int MyArray[Size];    정적 배열 선언

}

voic Function2(int Size)

{

   int *MyArrayPtr = new int[Size];    동적 배열 선언

   ...

   delete[ ] MyArrayPtr;

}

  • 정적 배열은 스택에(변수 선언에 의함) 생성됨
  • 동적배열은 힙에 (malloc, new 등 함수 실행에 의함) 생성됨
  • 정적 배열 크기는 컴파일 시에, 동적 배열 크기는 실행 중에 결정
  • 동적 배열도 실행 중에 그 크기를 늘릴 수는 없음

구조체 - 구조체 타입선언

typedef struct

{

   char Title[12];

   int Year;

   int Price;

} carType;

MyCar.Year = 2001;

carType MyCar {"RedSportCar", 2005, 2000};

Title RedSportCar\0 200
Year 2005 212
Price 1200 216

구조체 배열

구조체 포인터

(*p).Year와 *p.Year는 다르다.

(*p).Year와 p->Year는 같다.

활성화 레코드 - 메모리 구성

High Address(높은 번지) 힙(Heap) ò
  미사용 공간(Available)
스택(Stack) ñ
전역변수(Global Variables)
Low Address(낮은 번지) 기계코드(Machine Code)

 

메인함수 호출에 따른 활성화 레코드

int a;    전역 변수

void main()

{

   int b; char *s;    지역변수(스택)

   s = malloc(10);   10 바이트짜리 동적변수(힙)

   b =fcn(5);

   free(s);

}

힙 *s
미사용 공간  
스택
(main 함수의 활성화 레코드)
Local Variables b, s
Return Address 204
Value Parameters  
Return Value  
전역변수  a
기계코드 main( ) fcn1( ) fcn2( )

fcn 호출에 따른 활성화 레코드

int fcn(int p)    파라미터(스택)

{

   int b = 2;

   b = b+p;

   return (b);

}

힙 *s
미사용 공간  
스택
(fcn 함수의 활성화 레코드)
Local Variables b
Return Address 5번
Value Parameters p: 5
Return Value 7
스택
(main 함수의 활성화 레코드)
Local Variables b, s
Return Address 204
Value Parameters  
Return Value  
전역변수  a
기계코드 main( ) fcn1( )

 

활성화 레코드 스택

함수 호출

  • 새로운 활성화 레코드 생성
  • 연속적인 함수호출에 따라 활성화 레코드 스택이 생성
  • 함수 종료시 제일 위의 활성화 레코드가 사라짐으로써 직전의 상황을 복원

무한 루프

  • 스택 오버플로우(Stack Overflow)

표준 라이브러리 헤더와 프로그래밍 - C/C++ 명령 비교

 

  C C++
동적변수 할당 p = (int *)malloc(sizeof(int)); p = new int;
동적변수 해제 free p; delete p;
화면출력 명령 printf("%d\n", x); cout << x << endl;

 

728x90
반응형

'자료구조' 카테고리의 다른 글

리스트 - 2  (0) 2023.03.19
리스트 - 1  (0) 2023.03.19
재귀 호출  (0) 2023.03.19
추상 자료형  (0) 2023.03.18
객체지향 방법론  (0) 2023.03.17
    '자료구조' 카테고리의 다른 글
    • 리스트 - 1
    • 재귀 호출
    • 추상 자료형
    • 객체지향 방법론
    Yeom's
    Yeom's

    티스토리툴바