ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • C programming 기초 8강
    과외 수업 자료/C 2022. 11. 30. 13:24

    이전 시간에 이어서 포인터에 대해서 더 알아보고 C언어 기초를 마무리하도록 할 것이다.


    1. 포인터


    1.1 포인터와 1차원 배열

    배열의 이름은 배열의 시작 주소이다.

    배열 이름은 배열 요소에 접근하기 위해서 꼭 필요하다.

    포인터를 이용한 배열 요소 접근 예제 코드와 실행 결과

    &array[idx] 를 통해서 각 index의 주소에 접근이 가능할 수 있음을 확인할 수 있다.

    배열의 주소를 그림으로 표현하면 다음과 같다.

    배열의 주소 표현

    array의 이름은 시작 주소이며 indexing을 통해 각 index의 주소로 접근이 가능하다는 것을 알 수 있다.

    배열 요소 접근

    다음 코드는 참조하고 있는 배열 요소에 접근하는 코드이다.

    기존의 참조 변수 접근과 indexing하는 부분을 제외하고는 방법이 크게 다르지 않다는 것을 알 수 있다.

    1차원 배열에서 *(array + i) == *&array[i] == array[i]값을 표현한다.

     

    1.2 포인터와 2차원 배열

    1차원 배열과 달리 2차원 배열에서 *(array + i) == *&array[i] == array[i] 주소를 표현한다.

    1차원 배열 *(array + i) == *&array[i] == array[i]
    2차원 배열 *(array + i) == *&array[i] == array[i] 주소

    다음 표와 같이 1차원 배열과 2차원 배열의 차이를 구분할 수 있다.

    *&가 붙여서 사용될 경우 서로 상쇄되어 없어진다고 생각해도 무방하다.

     

    2차원 배열 포인터 접근

    다음 코드는 2차원 배열의 주소 값을 얻고 접근하는 방법을 나타낸 코드이다.

    *& 연산자를 통해서 2차원 배열의 index값에 접근할 수 있음을 확인할 수 있다.

     

    1.3 배열 포인터 변수를 통한 2차원 배열의 접근

    배열 포인터 변수는 배열을 가리키는 포인터 변수라는 의미를 갖는다.

    배열 포인터 변수 선언

    위와 같이 배열 포인터 변수를 선언할 수 있다.

    용어를 정리해보자.

    자료형 배열 포인터 변수가 저장하는 배열의 자료형
    배열 포인터 변수 이름 * 연산자와 배열 포인터 변수 이름을 함께 괄호로 묶음
    열의 길이 배열 포인터 변수가 가르키는 배열의 길이를 지정

    배열 포인터 변수를 사용한 2차원 배열 접근 코드 및 결과

    위 코드와 같이 배열 포인터 변수를 선언하여 접근이 가능하다.

    int (*p) [3] = NULL은 길이가 3인 배열 포인터 변수 p를 선언하겠다는 의미이다.

    이때 배열 포인터 변수 p의 길이는 int array[2][3] 의 가로길이를 기준으로 3이라 지정해 준 이것이다.

    p = array; 에서 배열 포인터 변수 p에 array의 주소를 넣어 참조하도록 한다.

    p의 각 요소에 접근해 보면 다음과 같이 결과 나옴을 확인할 수 있다.

     

    1.4 포인터 배열

    이전에 우리는 배열 포인터 변수를 공부하였다.

    지금부터는 포인터 배열을 공부해 볼 것이다.

    포인터 배열의 의미는 주소를 저장하는 배열을 말한다.

    포인터 배열 선언

    위는 포인터 배열을 선언하는 방법을 나타낸 것이다.

    배열 포인터 변수와 선언하는 법이 다름을 확인할 수 있다.

    그럼 용어를 살펴보자.

    자료형 포인터 배열의 자료형을 지정, 자료형 다음에 * 연산자를 붙임
    포인터 배열 이름 주소를 저장할 배열의 이름을 지정
    배열 길이 주소를 저장할 배열의 전체 길이를 지정

    포인터 배열 실습 코드 및 실행 결과

    위와 같이 포인터 배열을 사용할 수 있다.

    int* ap[3] = {NULL, NULL, NULL}을 통해서 비어있는 포인터 배열 ap를 선언해 준다.
    포인터 배열 각각의 index에 변수 a, b, c의 주소를 넣어 참조하도록 하여 밑의 printf 문과 같이 접근할 수 있다.

     

    1.5 포인터 배열 vs 배열 포인터 변수

    - 배열 포인터 변수 : int (*p)[3] = NULL;

    배열 포인터 변수 p는 3열짜리 2차원 배열의 주소를 저장할 수 있다.

     

    - 포인터 배열 : int* p[3] = NULL;

    괄호가 생략되어 있으며, 각 index에 변수의 주소를 저장할 수 있는 배열이다.


    2. 구조체


    우리가 동아리라는 단체를 보는 시각을 생각해보자.

    우선 동아리에는 동아리 이름, 동아리 회원,  동아리 회장과 같은 정보가 있다.

    동아리의 의미를 쉽게 표현해 본다면 같은 목적을 가진 회원들의 모임 즉, 그룹이라고 할 수 있다.

     

    컴퓨팅 세계에서도 이 동아리와 같은 역할을 하는 자료형이 존재한다.

    그것이 바로 구조체이다.

    구조체는 사용자가 정의해서 사용하는 사용자 정의 자료형으로 하나 이상의 변수들을 그룹화하여 새로운 자료형을 만들게 된다.

    동아리와 구조체를 매핑

    위와 같이 동아리의 형태를 구조체로 가져와서 생각해 본다면..

    동아리의 이름 == 구조체 이름, 동아리 회원 == 구조체 멤버 변수, 동아리 회장 == 구조체 변수 이렇게 mapping 하여 생각해볼 수 있을 것이다.

     

    다시 정리해 보자면, 구조체란 하나 이상의 변수를 묶어 그룹화하는 사용자 정의 자료형이다.

    그룹화할 때 같은 자료형을 가진 변수들을 묶어 그룹화할 수 있고, 서로 다른 자료형을 가진 변수들을 묶어 그룹화할 수도 있다.

    구조체의 구조

    구조체 키워드 구조체의 시작을 알리는 struct 키워드 지정
    구조체 이름 구조체를 구분하는 이름 (동아리 이름)
    멤버 변수 구조체를 구성하는 구조체 멤버 변수 이름

     

    2.1 구조체 변수로 멤버 변수에 접근

    구조체 변수로 멤버 변수에 접근 예시 코드 및 실행 결과

    위와 같이 main문 밖에서 group이라는 구조체를 먼저 정의한다.

    main문에서의 "struct group g1"의 의미는 struct group이라는 자료형의 g1이라는 변수로 선언한 것이다.

    g1.a = 10, g1.b = 1.234로 구조체 내부에 있는 멤버 변수에 값을 저장하여 출력할 수 있다.

    구조체 변수로 멤버 변수에 접근 예시 코드 및 실행 결과

    이렇듯 scanf를 통해서 멤버 변수에 값을 넣을 수도 있다.

     

    앞에서 두 예제로 살펴본 것처럼 구조체 변수로 멤버 변수에 접근할 때 접근( . ) 연산자를 사용한다.

    구조체 변수를 적고 Dot을 찍은 다음에 접근할 멤버 변수를 적으면 된다.

    멤버 변수 접근 방법

    구조체 변수 멤버 변수에 접근하게 해주는 구조체 변수의 이름을 지정
    접근 연산자 구조체 변수로 멤버 변수에 접근하기 위해 연산자를 지정
    멤버 변수 접근하려는 멤버 변수의 이름을 지정

     

    2.2 구조체 변수의 초기화

    구조체 변수의 초기화

    위 코드와 같이 구조체 변수를 중괄호로 초기화할 수 있다.

    또한 "p3.x = p2.x - p1.x"와 같이 각 멤버 변수에 접근하여 연산 또한 가능하다.

     

    2.3 중첩 구조체

    중첩 구조체

    구조체를 중첩하여 사용할 수도 있다.

    student 구조체 안에 다른 구조체인 score가 사용되어 중첩되어 있음을 확인할 수 있다.

    이렇게 되면 student 구조체를 사용하는 것만으로도 score 구조체에 접근을 할 수 있게 된다.

    코드에서 "stu.s.math = 90" 이 라인을 확인해보자.

    stu 안에 있는 멤버 변수 s에 우선 접근을 하고 s안에 있는 멤버 변수 math에 접근을 한 것이다. 이를 코드로 표현하면 "stu.s.math" 가 되는 것이다.

     

    2.4 멤버 변수로 배열 사용하기

    멤버 변수로 배열 사용하기

    위 코드와 같이 멤버 변수로 배열을 사용하여 구조체를 만들 수도 있다.

    멤버 변수로 배열 사용하기

    멤버 변수로 배열을 사용할 때 이전 배열에 값을 넣던 것과 마찬가지로 for문을 사용하여 indexing이 가능하다.


    마치며..

    포인터와 구조체에 대한 개념을 알아보았다.

    1~8강까지 총 8개의 강의를 통해 C언어의 기본적인 개념을 공부해 보았다.

    제대로 다루지 못한 내용도 많지만 기본적인 C언어 문법의 개념이 잡혔다면 아마 성공한 것일 것이다.

    C언어는 모든 언어의 기초가 되고 다른 언어를 배우더라도 문법이 크게 바뀌지 않는다.

    그렇기 때문에 C언어를 본 강의 내용보다도 깊게 공부하는 것이 좋을 것이다.

     

    그럼 이로써 C언어의 기본적인 문법 강의를 마치도록 하겠습니다.

    지금까지 부족한 내용이지만 강의를 읽어주셔서 다시 한번 감사합니다.


    < 참고 자료 >

    책 : 열혈강의 C언어 본색 / 박정민

    '과외 수업 자료 > C' 카테고리의 다른 글

    C programming 기초 7강  (0) 2022.11.28
    C programming 기초 6강  (0) 2022.11.17
    C programming 기초 5강  (0) 2022.11.07
    C programming 기초 4강  (0) 2022.11.03
    C programming 기초 3강  (0) 2022.10.20
Designed by Tistory.