반응형
반응형

 

📝구조체 (struct), typedef(별칭)

#include <stdio.h>
#include <stdlib.h>

typedef struct Point
{
    int x;
    int y;
} PointAlias;
// typedef struct Point PointAlias; 와 동일한 표현
// struct Point라는 글자를 PointAlias라는 글자로표현하겠다는 의미


int main()
{
    struct Point p1;
    struct Point p2; // C++은 struct 안 붙혀도 인식한다.

    PointAlias p3;   // typedef로 별칭을 부여한 이름을 사용한 예제

    Point pt = {1, 2}; // pt.x = 1 , pt.y = 2

    p1.x = 20;
    p1.y = 30;

    p2.x = 30;
    p2.y = 40;

    printf("(%d, %d)\n", p1.x, p1.y); // 20, 30
    printf("(%d, %d)\n", p2.x, p2.y); // 30, 40
}

 

struct 구조체명 {

    구조체 내용...

}

위와 같은 구조를 통해 변수를 관련 있는 변수를 하나로 관리할 수 있습니다. 위에서 Point란 x좌표 ,y좌표를 가진 2차원 점의 위치를 의미합니다.

 

 

📝 구조체 변수에 접근하기, 구조체 포인터

#include <stdio.h>
#include <stdlib.h>

typedef struct Point
{
    int x;
    int y;
} Point;


int main() 
{
    Point pt = {1, 2}; // pt.x = 1 , pt.y = 2
    Point* pp = &pt;

    // pt의 주소의 x에 접근, pt의 주소의 y에 접근
    printf("(%d, %d)\n", pt.x, pt.y);         // 1, 2
    printf("(%d, %d)\n", (*pp).x, (*pp).y);   // 1, 2
    // 주소로 참조변수에 접근시 (pp의 주소 즉, pt의 주소) ->로 표현
    printf("(%d, %d)\n", pp->x, pp->y);       // 1, 2
    // 위와 같은 형식으로 pt의 주소에 x 또는 y에 접근할 수 있다.
    printf("(%d, %d)\n", (&pt)->x, (&pt)->y); // 1, 2
}

 

구조체 포인터의 경우 일반 포인터와 동일하게 사용하면 됩니다.

  • 구조체명* 포인터변수명 = &구조체 변수명
    • (*포인터변수명)을 통해 값을 출력할 수 있으며 → *은 주소값을 실제 값으로 변환
    • 포인터변수명->을 통해서도 값을 출력할 수 있습니다. → ->은 주소값을 실제값으로 변환
    • (&pt)의 경우->의 역할이 주소값을 실제값으로 변환시키기 때문에 주소값 자체를 저장하고 있는 pp의 경우 그냥 사용하면 값이 출력되지만 pt의 경우 값 그 자체를 저장하고 있지 주소값이 아니기 때문에 &을 이용해 주소로 변환시키고 ->을 통해 실제 값으로 바꿔서 접근이 가능합니다. → 물론 이러한 행위는 의미없긴 합니다. pt.x, pt.y로 바로 접근하면 되기 때문이다

 

#include <stdio.h>
#include <stdlib.h>

typedef struct Point
{
	int x;
	int y;
} Point;


int main() 
{
	Point p1 = { 2, 3 }; // Stack 영역에 저장
	
	Point* p = (Point*)malloc(sizeof(Point)); // Stack영역에 포인터 생성 후 실질적 값은 Heap 영역에 저장
	p->x = 2;
	p->y = 3;

	printf("(%d, %d)\n", p1.x, p1.y); // 2 , 3 출력
	printf("(%d, %d)\n", p->x, p->y); // 2 , 3 출력
	 
	Point arr[5] = { {1,1}, {2,2} };
	Point* arr_p = (Point*)malloc(sizeof(Point) * 2);
	
	// 배열 포인터 접근
	arr_p[0].x = 1; 
	arr_p[0].y = 1; 
	arr_p[1].x = 2; 
	arr_p[1].y = 2;

	// 포인터로 다음 배열 접근시 + 1 (int만 그런건지 테스트가 필요한 부분이긴 하다.)
	printf("arr_p[0].x %d == (arr_p)->x) %d\n",arr_p[0].x, (arr_p)->x);
	printf("arr_p[0].y %d == (arr_p)->y) %d\n",arr_p[0].y,(arr_p)->y);
	printf("arr_p[1].x %d == (arr_p + 1)->x) %d\n", arr_p[1].x,(arr_p + 1)->x);
	printf("arr_p[1].y %d == (arr_p + 1)->y) %d\n", arr_p[1].y,(arr_p + 1)->y);

	

}
반응형
반응형

📝배열

// 배열
#include <stdio.h>
#include <stdlib.h>

int main() 
{
    int a=10, b=20, c=30, d=40;   // 비연속적으로 메모리에 저장
    int arr[4] = {10, 20, 30, 40}; // 연속적으로 메모리에 저장

    printf("%d %d %d %d\n", a, b, c, d); // 10, 20, 30, 40
    printf("%d %d %d %d\n", arr[0], arr[1], arr[2], arr[3]); // 10, 20, 30, 40

}

 

 

📝포인터

// 포인터
#include <stdio.h>
#include <stdlib.h>

int main() 
{
    int a=10, b=20, c=30, d=40;// 비연속적으로 메모리에 저장
    int arr[4] = { 10,20,30,40 };// 연속적으로 메모리에 저장

    int* p = &a;   // a의 주소값을 보관 (물론 주소값을 보관하기 때문에 p라는 변수로서 할당된다.)
    int* pa = arr; // arr[0]의 주소값을 보관

    printf("p : %d, pa : %d\n", p, pa);                          // 1823472356, 1823472488
    printf("&a : %d, arr : %d\n", &a, &arr[0]);                  // 1823472356, 1823472488
    printf("p의 값 = a의 값 = %d\n", *p);                        // 10
    printf("pa의 값 = arr[0]의 값 = %d\n", *pa);                 // 10
    printf("&p(p의 주소) : %d, &pa(pa의 주소) : %d\n", &p, &pa); // 1823472536, 1823472568

    // 배열 Pointer의 경우 배열처럼 사용가능
    printf("%d %d %d %d\n", pa[0], pa[1], pa[2], pa[3]); // 10, 20, 30, 40

}

 

포인터메모리에 할당된 주소를 가르키게 된다

 

  • 자료형* 변수명 = &할당된 변수명
    • 할당된 변수명의 주소(&)를 기억하는 변수가 만들어지게 된다.
    • *변수명을 통해 해당 주소의 실제 값을 읽어올 수 있다

배열의 경우 연속된 공간에 저장한다 그래서 포인터를 이용해 해당 주소를 가르키게 되면 포인터 변수명[0], 포인터 변수명[1] 과 같이 실제 값을 가져올 수 있습니다

 

📝메모리 저장 영역 (stack, Heap)

// 데이터 영역
#include <stdio.h>
#include <stdlib.h>

int g = 30; // G-D 영역 (전역변수, 정적변수, 상수)

int main() 
{
    int m = 20; // stack 영역 (함수내의 변수)
    int n = 20; // stack 영역

    int* p; // stack 영역
    p = (int*)malloc(4); // Heap 영역 (4byte 할당)

    *p = 10; // Heap 영역에 10 할당
    printf("%d", *p);

    // 4byte의 크기를 Heap 영역에 생성 후 p라는 포인터 변수가 그 주소값을 가르키게 된다.

    free(p); // 영역 할당을 free로 제거 시켜야 사라지게 된다.
}

메모리는 크게 2가지로 나뉘는데 stack영역과 Heap 영역으로 나뉘게 됩니다.

 

📝stack영역의 경우

호출된 함수가 마치고 복귀할 주소 및 데이터(지역변수, 매개변수, 리턴 값 등)를 임시로 저장하는 공간입니다 만약 재귀함수가 많이 발생해 stack영역을 초과하게 되면stack overflow 에러가 발생하게 됩니다. Stack은 컴파일 타임에 크기가 결정되기 때문에 무제한으로 할당 할 수 없습니다

 

📝Heap영역의 경우

런타임(프로그램 동작) 시 크기가 결정됩니다. malloc등으로 Heap영역의 메모리를 사용해 원하는 공간만큼 할당해 사용합니다. 이렇게 공간을 할당하고 해제하지 않으면 Memory Leak이 발생하게 됩니다. JAVA의경우 JVM이 이 행위를 대신 해주죠 Stack의 비해 메모리 공간이 많지만 포인터로 접근해야 하기 때문에 속도가 느립니다

 

 

📝 정적배열, 동적배열

// 정적배열, 동적배열
#include <stdio.h>
#include <stdlib.h>

int main() 
{
    int arr[20]; // 정적배열

    arr[0] = 0;
    arr[1] = 10;
    arr[2] = 20;
    arr[3] = 30;
    arr[4] = 40;

    for (int i = 0;i < 5; i++) {
        printf("%d\n", arr[i]); // 0, 10, 20, 30 , 40
    }

    int* p;
    p = (int*)malloc(40); // 동적 배열

    p[0] = 0;
    p[1] = 10;
    p[2] = 20;
    p[3] = 30;
    p[4] = 40;

    for (int i = 0;i < 5; i++) {
        printf("%d\n", p[i]); // 0, 10, 20, 30 , 40
    }

    free(p);
    
    // sizeof를 이용한 할당방식
    int* ps;
    ps = (int*)malloc(sizeof(int) * 5); // sizeof(int) * 5 → int형 5개를 생성

    ps[0] = 0;
    ps[1] = 10;
    ps[2] = 20;
    ps[3] = 30;
    ps[4] = 40;

    for (int i = 0;i < 5; i++) {
        printf("%d\n", ps[i]); // 0, 10, 20, 30 , 40
    }

    free(ps);

}

정적배열의 경우 stack영역을 사용하는 걸 의미하고 동적배열의 경우 Heap영역을 사용하는 걸 의미합니다.

 

📝 사용자에게 값을 입력 받기

// 사용자에게 배열크기 입력받기
#include <stdio.h>
#include <stdlib.h>

int main() 
{
    int size = 0;
    printf("배열의 크기를 입력해주세요 : ");
    scanf_s("%d", &size); // size을 사용자에게 입력 받는다.

    // int arr[size]; // 정적배열인 경우 배열크기에 변수 할당 불가
    int* pa = (int*)malloc(sizeof(int) * size); // 동적배열은 가능하다.


    for (int i = 0; i < size; i++) {
    printf("[%d] 배열의 값을 입력해주세요 ", i);
    scanf_s("%d", &pa[i]); // 배열을 입력해주세요
    }

    for (int i = 0; i < size; i++) {
        printf("pa[%d] : %d\n", i, pa[i]);
    }
}

 

반응형
반응형
#include <stdio.h>
#include <stdlib.h>

int main() 
{
    for (int i = 0; i <= 10; i++) { // 10번 반복
        if (i % 2 == 0) { // 짝수만 선별
            printf("even : %d\n", i); // i의 값을 출력
    	}
    }
}

 

반응형
반응형

설치 URL : https://visualstudio.microsoft.com/ko/vs/community/

 

Visual Studio 2022 커뮤니티 버전 – 최신 무료 버전 다운로드

Windows, Android 및 iOS용 최신 개발자 앱을 만들기 위한 모든 기능을 갖춘 확장 가능한 무료 IDE를 사용해 보세요. 지금 무료로 커뮤니티를 다운로드하세요.

visualstudio.microsoft.com

 

위에 링크를 통해서 다운을 받아주세요

 

C++를 사용한 데스크톱 개발을 클릭해서 추가 설치해줍니다.

 

 

새 프로젝트 만들기로 프로젝트를 만들어줍니다

 

 

빈 프로젝트를 선택해주세요

 

 

프로젝트 이름과 위치를 설정해줍니다 그러면 프로젝트가 만들어집니다. 그 후에 소스 파일을 만들어보도록 하겠습니다.

 

 

소스파일 - 우클릭 - 새항목으로 만들어줍니다.

 

cpp 확장자인 경우 C++컴파일러를 사용하고 c 확장자인 경우에는 C컴파일러를 사용합니다.

 

 

Ctrl + F5 → 컴파일 단축키

반응형