이전 C에서 공부한 내용을 복습했다.

포인터와 구조체를 중점적으로 학습하였는데, 시스템프로그래밍에서 함수 선언에 포인터를 활용하는 것으로 메모리 활용을 더 합리적으로 하는 것이 목표이며, 또한 구조체를 활용하면 함수 내부에 많은 변수가 필요한 경우 변수를 하나의 구조체로 모아 함수로 넘겨주는 것이 가능하다.

이러한 코딩을 활용하면 메모리를 효율적으로 사용하고, 한눈에 읽기 편한 코드를 작성할 수 있다.

/*
C Review
포인터
구조체(Structure)
구조체를 매개변수로 사용(Call by pointer)
동적 할당(Dynamic Allocation : Wiki) : malloc(), free()
typedef
메모리 관리 : Wiki
변수의 생명 주기(variable lifetime) : automatic / static / dynamic
*/

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


//Structure (구조체)
//특정 객체의 여러 속성을 하나로 묶는다.
typedef struct complex {
    double real;        //real part
    double imag;       //imaginary part
} Complex;          //반드시 ;으로 종료해야 한다.
                    //typedef를 활용해 별명을 붙여준다.




//함수 setComplex()
//입력: 복소수포인터, 실수보, 허수부
//출력: 없음
//부수효과: 복소수의 실수부와 허수부가 입력한 매개변수로 설정됨
//이 부분을 보면 포인터를 활용하는 것으로 구조체의 전체 데이터를 활용하는 것이 아니라
//포인터를 활용하여 할당되는 메모리 공간을 아낄 수 있다.
//포인터의 경우 4byte 공간이 할당된다!
void setComplex(struct complex* ptr, double real, double imag) {
    //구조체 포인터 변수이다.
    //x.real과 동일한 저장소를 가리킨다.
    ptr->real = real;
    ptr->imag = imag;
}


//함수 printComplex()
//입력: 복소수포인터
//출력: 없음
//부수효과: 화면에 복소수 표시
void printComplex(struct complex* ptr) {
    //구조체 포인터 변수이다.
    //x.real과 동일한 저장소를 가리킨다.
    printf("%f + j%f\n", ptr->real, ptr->imag);
}

//함수 addComplex()
//입력: 두 복소수 포인터
//출력: 복소수
//부수효과: 없음
Complex* addComplex(Complex* ptr1, Complex* ptr2) {
    //Complex x;  //x는 스택영역에 할당.      (lifetime)

    //자동변수(automatic): 스택공간을 사용하고 함수초기에 할당받고 함수종료에 소명된다.
    //동적할당(dynamic allocation): heap공간을 사용하고 프로그램 수행 중 malloc()에 의해 할당 받고
    //free() 함수로 소멸한다.
    //정적할당(static allocation) : 프로그램 시작시 저장공간을 할당받고 종료시 소멸된다.
    //컴퓨터 분야에서 "동적"은 프로그램 수행 도중에 발생하는 것을 의미하고
    //"정적"은 컴파일 도중에 발생하는 것을 의미한다.


    Complex* ptr;
    ptr = (Complex*)malloc(sizeof(Complex));    //molloc()함수는 void* 형의 메모리 주소를 반환한다.
    //void* 형의 의미는 단순한 메모리 주소이다. 따라서 이 주소로 시작하는 메모리 공간을
    //Complex형의 변수로 사용하기 위해 (Complex*) 형변환이 필요하다.



  ///*  x.real = ptr1->real + ptr2->real;
  //  x.imag = ptr1->imag + ptr2->imag;*/

    ptr->real = ptr1->real + ptr2->real;
    ptr->imag = ptr1->imag + ptr2->imag;

    return ptr;
    //return &x;          //원래 
}



//처음 메모리 영역은 3가지이다
//static
//heap
//stack

//static 영역은 전역변수, 변수 초기 데이터, 상수값 데이터가 저장된다.

//기계어는 따로 할당된다.

//이때, heap에는 동적할당된 데이터가 포함된다.
//stack 자동할당!!!

//전역변수 global variable
static int ggggggg1 = 10;           //실제 내부에서 활용되지 않으면 asm에 저장조차 되질 않는다.
static int ggggggg2;                //ggggggg2를 실제 찾아보니 출력이 되질 않는 것을 볼 수 있었다.

void testStatic() {
    //static int s1 = 0;
    static int sssssss1 = 0;
    printf("s1=%d\n", sssssss1);
    sssssss1++;
}

int main()
{
    ////문장: 프로그램 수행의 기본 단위
    ////이름(식별자: identifier) 프로그래머가 프로그램(변수, 상수, 함수)을 위해 만들어 사용할 수 있는 단어(또는 )
    ////프로그래밍 언어에서 사용하는 단어는 "토큰"이라 한다.
    ////토큰은 예약어 (Reserved word: int float, =, + 등)와 이름(식별자: 변수이름, 함수이름...)으로 구분한다.
   
    ////보면 예약어는 int, ',' ';'
    //int a, b, c;    //변수 선언문 1. 변수이름 2. 변수 자료형
    //                //이 값은 stack 메모리 영역에 값이 할당된다.
    //                //ptr 변수 또한 이 메모리 영역에 값이 저장되는 것은 동일하지만
    //                //주소의 데이터가 저장되어 있는 것이다.

    //int* ptr;       //int형 pointer 변수 선언(1.포인터변수 이름  2.포인터 변수가 가리키는 곳에 저장된 값의 자료형)
    //                //C 언어에서 포인터는
    //                //1. 메모리 주소
    //                //2. 저장되어있는 주소가 가리키는 곳에 저장된 값의 자료형
    //




    //a = 10;         // 변수 이름 , 예약어, 리터럴(프로그램에서 수를 표현하는 토큰), 예약어
    //b = 20;         // "=": 대입연산자(assignment opertor)
    //                // 이 역할은 우변의 값을 좌변의 주소에 저장한다.

    //a = b;          // 대입연산자는 b의 값을 a의 주소에 복사해준다.
    //                
    //c = a + b;      // 수식(Expression): 연산자와 피연산자의 조합. 
    //                // 모든 수식은 값을 반환한다.
    //                

    //ptr = &a;       //변수 a의 주소값을 ptr의 저장공간에 복사
    //                //&: "address of:로 읽으면 편하다. 오른쪽 변수의 주소를 반환
    //
    //b = *ptr;       //*: "data of"로 읽으면 편하다.  
    //                // 오른쪽 포인터변수를 주소로 활용 주소에 존재하는값 반환
    //
    //*ptr = c;       //*ptr의 의미 (*ptr)의 저장장소
    //                //c의 값을 ptr이 가리키는 저장장소에 복사
    //    
    //                //포인터 변수 선언의 의미
    //                //1. ptr은 포인터 변수이고
    //                //2. 포인터 변수가 가리키는 곳에 저장된 값의 자료형

    //printf("c = %d\n", c);


    ////struct complex x, y;      
    //Complex x, y, z;               //이전 선언을 조금 더 편하게 선언
    //x.real = 1.2;
    //x.imag = 3.7;


    ////이때, 구조체의 크기는 많이 큰데, 이를 바로 활용하는 대신
    ////포인터를 활용하면 유용하게 사용 가능
    //struct complex* pComp;  // 구조체 포인터 변수 선언
    //Complex* ptr1;
    //pComp = &y;
    //setComplex(pComp, 7.7, 8.8);
    //printComplex(pComp);
    //
    ////z = addComplex(&x, &y);
    //ptr1 = addComplex(&x, &y);

    //printComplex(ptr1);

    //free(ptr1);
    //
    //printComplex(ptr1);

    printf("static test : %d\n", ggggggg1);

    testStatic();
    testStatic();

    return 0;
}

 

1.    WaitForSingleObject()

WaitForSingleObject()는 다음과 같은 변수를 필요로 한다.

DWORD WaitForSingleObject(

HANDLE hHandle,

  DWORD  dwMilliseconds

);

 

이러한 인자를 활용해 현재 thread가 종료될 때 까지 코드를 중지시킨다.

또한, 완료가 되지 않더라도, dwMilliseconds보다 긴 시간이 경과하면 중지된 코드를 다시 가동한다.

 

+ Recent posts