프로그래밍 공부

전체 글 700

카테고리 설명
프로그래밍 공부하는 블로그
  • 포인터와 포인터배열을 알아보자. 포인터를 선언할 때 배열을 지정하기 위해서는 배열을 지정하고 배열의 열이 어느정도 있는지를 포인터에 알려주어야 한다. 배열 포인터 = 포인터를 배열처럼 사용하겠다. 포인터 배열 = 포인터에 int형을 하나하나 넣어서 배열처럼 만들겠다. 라는것이다. 구조체, Structure에 대해 알아보자. 구조체는, 각각의 같은 데이터가 무수히 많이 필요할 때 전부 타이핑하여 사용할 수 없음으로 다양한 데이터를 한개로 묶어서 여러개 사용할 수 있도록, 하는 것을 이야기 한다. 쉽게 말해서 도장을 파서 그때그때 파서 사용하는거라고 생각하면 편하다. 더 쉽게 이해하자면, 전에 배웠던 함수를 만드는것. 을 변수로 만든다고 생각하면 된다. 자료형 이라고 생각하면 된다. 자료형을 만들 때 cpp..

  • 더블포인터에 대해 알아보자. 더블포인터는 포인터를 가르키는 포인터를 의미한다. 포인터를 가르키는 포인터는 **을 붙여서 표현한다. 간단하게 포인터의 포인터이니까 더블포인터 포인터 두개 라고 이해하면 기억이 편하다. 예시를 살펴보자. 포인터를 사용해서 데이터의 변환을 실험해보자 간단하게 swap코드를 작성하여 테스트를 진행한다. 내부 데이터가 변환된다는 가정 하에 함수 내부에서 외부변수를 받아와서 변환해주어도,함수가 끝나는 순간 할당된 메모리는 전부 반환되고 리턴값을 제외한 모든 데이터가 사라지게 된다. 이것을 막기 위해 포인터를 사용하여 함수 연산을 진행할 수 있다. 예시를 살펴보자. 이중포인터 접근방법을 통해서 데이터가 아닌 주소만 바꾸어 보자. 포인터를 사용하면 주소만 변경함으로 써 데이터가 바뀐것 ..

  • 문자열 형태로 포인터를 선언할 수 있다. 포인터 변수를 문장으로 선언하였을 경우를 알아보자. 위와같이 선언했다고 가정해보자. 문자열은 전부 배열형태로 이어지게 메모리에 생성이 되고 마지막에 '\0'이 붙게된다. 그리고 char*pstr은 ptrSting 의 p를 가리키게 된다. 배열과 다른점이 무엇일까? 배열은 다음값을 배열의 list[0], list[1]이런식으로 접근이 가능하다. 그러나, 포인터로 선언된 문장의 경우에는 이런식으로 접근을 할 수 없다. 접근하게되면, 이런식으로 나타나게 된다. 이유가 무엇일까? pstr은 포인터이지 배열이 아니기 때문이다. 포인터는 위치좌표를 나타낼 뿐, 배열처럼 접근방법을 제공하지 않기 때문에 접근하기 위해서는 배열처럼 접근이 아닌, ++나 --같이 좌표를 직접 지정..

  • stream = 한방향으로 흐르는 단방향 통신이다. 콘솔 입출력을 위한 스트림은 생성이 자동으로 생성되고 자동으로 소멸된다. 이것은 표준 입출력시스템 stdio.h 라고 한다. 따로 생성하지 않아도 OS에서 자동으로 해준다. buffer = 데이터 처리장치간의 처리속도 때문에 임시로 저장해놓았다가 출력한다. getchar = 버퍼를 비워준다. 한단어씩 리턴해준다. 이번에는 포인터를 알아보자. 포인터는 주소라고 생각하면된다. 메모리의 주소값을 이야기한다. 포인터 변수 = 메모리의 주소값을 저장하기 위한 변수 이다. 포인터는 * 을 표기하여 포인터를 선언해줄 수 있다. 밑 예시를 살펴보자. 배열의 이름또한 포인터를 사용한다. 이러한 예시를 밑에서 확인해보자. 여기서 데이터 포인터가 1씩 증가하는것이 각 바이..

  • 이번에는 전역변수에서의 함수가 어떤식으로 전역변수와 지역변수를 받는지 알아보자 local count 가 1이 되는것 을 알 수 있다. 지역변수가 1이 계속 선언됨 으로 선언될 때 마다 1이 한개 더해지고 1이 되고가 반복되어 local count가 1로 출력된다. 여기서 static 으로 선언하면 어떻게 되는지 보자. 위와 같이 나타남을 알 수 있다. static int 가 count가 데이터가 중첩됨을 알 수 있다. 즉, count가 전역변수 처럼 취급되어 데이터가 중첩됨을 볼 수 있다. static은 한번만 초기화를 (최초선언시에만 변형이 가능하다.) 유효범위는 선언한 위치에서만 동작한다. Memory structure ---------------------------------------------..

  • 로또생성기 만들기 로또 생성기를 만들어보자 먼저 로또번호를 생성하기 위해서는 무엇이 필요한지 나열한다.로또번호는 랜덤함수로 생성해야한다.보너스번호 가 존재한다면, 일반번호 와 보너스번호를 나누어 주어야 한다.모든 코드가 순환하며, 내가 입력한 번호가 랜덤 생성한 번호와 같은지 검사해야한다.예시를 보자.이렇게 작성할 수 있다.만약, 복권번호를 작은수 부터 나열한다고 가정하면, Sort함수를 사용해서 값들을 정렬해야 한다.재귀함수 를 사용한 파보나치 수열 재귀함수를 사용한 피보나치를 출력한다. 코드는 매우 간단하다. 예시를 보자.단 3줄만 들어가면 출력할 수 있다. 쉽게 이해가 가지 않는다면, 풀어서 이해해보자. 파보나치 수열의 5번째 수를 출력하려고 한다고 가정한다.파보나치 수열의 5번 째 수는 0 1 1..

작성일
2023. 3. 23. 15:44
작성자
WDmil
728x90

포인터와 포인터배열을 알아보자.

포인터를 선언할 때 배열을 지정하기 위해서는 배열을 지정하고 배열의 열이 어느정도 있는지를 포인터에 알려주어야 한다.

배열 포인터 = 포인터를 배열처럼 사용하겠다.

포인터 배열 = 포인터에 int형을 하나하나 넣어서 배열처럼 만들겠다. 라는것이다.


구조체, Structure에 대해 알아보자.

구조체는, 각각의 같은 데이터가 무수히 많이 필요할 때 전부 타이핑하여 사용할 수 없음으로 다양한 데이터를 한개로 묶어서 여러개 사용할 수 있도록, 하는 것을 이야기 한다. 쉽게 말해서 도장을 파서 그때그때 파서 사용하는거라고 생각하면 편하다.

더 쉽게 이해하자면, 전에 배웠던 함수를 만드는것. 을 변수로 만든다고 생각하면 된다.

위와 같이 편리하게 만들고 사용이 가능하다.

자료형 이라고 생각하면 된다.

자료형을 만들 때 cpp에서는 struct라고 붙이지 않아도 생성이 가능하다. 그러나 c환경에서는 불가능함으로 참고하자.

c환경
cpp환경

위와같이 오류의 유무를 확인할 수 있다.

 

그러나, 사용하고 싶다면 typedef를 사용하여 별칭을 넣어 사용할 수 있다

typedef 사용예시

위와 같이 c환경에서 오류가 나오지 않는것 을 알 수 있다.

익명 구조체를 사용하는 방법 또 한 있다.

익명 구조체는 처음 typedef를 선언할 때 옆에 이름을 선언하지 않고 마지막에만 별칭을 붙여주는 것 을 말한다.

선언과 초기화는 다음과 같이 순서대로 입력하여 사용한다.


메인문에서 기본적으로 초기화 하는 방법을 사용해보자.

임의 구조체 Point 를 선언해서 초기화하여 출력해보자.

이렇게 출력됨 을 알 수 있다. 위와같이 구조체 내부의 변수를 수정하여 출력할 수 있다.


응용해서 두 점 사이의 거리를 구하는 코드를 짜보자, 예시는 밑과 같다.

위와 같은 방법으로 두 점 사이 2차원평면에서의 거리를 구할 수 있다.


이번에는 데이터를 직접 구조체에 for문을 사용하여 입력해보도록 하자.

이렇게 출력이 나오면 성공이다. 입력과 출력, 그리고 데이터유형을 잘 생각해야한다.

각 변수의 데이터 종류를 생각해야한다.

 

728x90
작성일
2023. 3. 22. 15:45
작성자
WDmil
728x90

더블포인터에 대해 알아보자.

더블포인터는 포인터를 가르키는 포인터를 의미한다.

포인터를 가르키는 포인터는 **을 붙여서 표현한다. 간단하게 포인터의 포인터이니까 더블포인터  포인터 두개 라고 이해하면 기억이 편하다.

 

예시를 살펴보자.

포인터를 선언하는 방법


포인터를 사용해서 데이터의 변환을 실험해보자

간단하게 swap코드를 작성하여 테스트를 진행한다.

 

내부 데이터가 변환된다는 가정 하에 함수 내부에서 외부변수를 받아와서 변환해주어도,함수가 끝나는 순간

할당된 메모리는 전부 반환되고 리턴값을 제외한 모든 데이터가 사라지게 된다. 이것을 막기 위해 포인터를 사용하여

함수 연산을 진행할 수 있다. 예시를 살펴보자.

주소접근 변환방법과 일반 변수를 사용해서 변환해보자.


이중포인터 접근방법을 통해서 데이터가 아닌 주소만 바꾸어 보자.

포인터를 사용하면 주소만 변경함으로 써 데이터가 바뀐것 같은 효과를 보여줄 수 있다. 주소를 출력해보자.

이중 포인터를 사용해서 데이터연산을 할 수 있다. 이러면 데이터가 변하는게 아니라 포인터의 주소값만 바뀌는 걸 볼 수 있다.
출력 결과

 

728x90
작성일
2023. 3. 18. 00:19
작성자
WDmil
728x90

문자열 형태로 포인터를 선언할 수 있다.

포인터 변수를  문장으로 선언하였을 경우를 알아보자.

위와같이 선언했다고 가정해보자.

문자열은 전부 배열형태로 이어지게 메모리에 생성이 되고 마지막에 '\0'이 붙게된다.

그리고 char*pstr은 ptrSting 의 p를 가리키게 된다.

 

배열과 다른점이 무엇일까?

배열은 다음값을 배열의 list[0], list[1]이런식으로 접근이 가능하다.

그러나, 포인터로 선언된 문장의 경우에는 

이런식으로 접근을 할 수 없다. 접근하게되면,

이런식으로 나타나게 된다. 이유가 무엇일까?

pstr은 포인터이지 배열이 아니기 때문이다. 포인터는 위치좌표를 나타낼 뿐, 배열처럼 접근방법을 제공하지 않기 때문에 접근하기 위해서는 배열처럼 접근이 아닌, ++나 --같이 좌표를 직접 지정해주어야 한다.


2차원 배열의 포인터 주소 접근방법을 알아보자

위와 같이 표현할 수 있을것이다.

2차원 배열을 포인터로 저장하는 방법을 살펴보자.

다른방법으로도 출력해보자. 밑 예시를 살펴보자.


포인터를 상수화 시켜줄 수 도 있다. 상수화 하면 변경할 수 없는 데이터가 된다.


보이드 포인터 에 대해 알아보자.

보이드 포인터는 일반 포인터와 다르게 포인터의 경로에 어떠한 데이터를 지정할 것 인지 알 수 없을 때 사용한다.

즉, void * 변수 선언문은 포인터 가 가르키는 데이터의 종류에 상관없이 포인터를 지정할 수 있다는 말 이다.

위 void*voidptr 처럼 선언한다.

사용할 때 에는 해당 포인터의 데이터 종류에 따라 선언방법이 달라진다. 사용방법의 간단한 예시를 살펴보자.

위와 같이 형변환 후 사용할 수 있다.

포인터에 (int*)은 int형의 포인터를 받기위해 int 포인터 로 형변환 하겠다는 의미 이다. 그 후 모든 데이터 문에 *를 선언하여 포인터에 들어있는 데이터를 호출하게 된다.

728x90
작성일
2023. 3. 16. 19:25
작성자
WDmil
728x90

stream = 한방향으로 흐르는 단방향 통신이다.
콘솔 입출력을 위한 스트림은 생성이 자동으로 생성되고 자동으로 소멸된다.
이것은 표준 입출력시스템 stdio.h 라고 한다. 따로 생성하지 않아도 OS에서 자동으로
해준다.

buffer = 데이터 처리장치간의 처리속도 때문에 임시로 저장해놓았다가 출력한다.
getchar = 버퍼를 비워준다. 한단어씩 리턴해준다.

자세한 설명을 주석으로 적어놓았다.


이번에는 포인터를 알아보자.

포인터는 주소라고 생각하면된다. 메모리의 주소값을 이야기한다.

포인터 변수 = 메모리의 주소값을 저장하기 위한 변수 이다.

포인터는 * 을 표기하여 포인터를 선언해줄 수 있다. 밑 예시를 살펴보자.


배열의 이름또한 포인터를 사용한다. 이러한 예시를 밑에서 확인해보자.

이렇게 나타나게 된다.

여기서 데이터 포인터가 1씩 증가하는것이 각 바이트당 증가하는것으로 이해하면 된다.

그 이유를 살펴보면,

1 2 3 4
0x000 0x004 0x008 0x012

이런식으로 배열이 이루어져 있고 밑부분이 주소라고 생각 하였을 때.

한 주소는 최대 어떠한 4byte로 이루어져 있어야 한다. 이 데이터 배열, 데이터의 주소가 어떠한 위치에 생성되는지는 알 수 없다.

 

그 이유는 데이터를 저장 할 때 데이터의 위치값을 지정하는것은 사용자가 아니라 OS가 임의의 저장장소에 저장하기 때문이다. 

그렇기에 일정 저장공간 안에 어떠한 위치에 있는지 좌표를 표기하기 위해 4byte 또는 8byte를 사용하는것 이다.

이로써 우리는 4byte의 저장좌표, 8byte 저장좌표를 통해 더 넓은 데이터 범위 저장이 가능하다는것을 이해할 수 있다.

 

컴퓨터에서 32bit 또는 64bit가 있다는것 을 기억할 것이다. 이러한 bit값으로 주소를 결정하게 되는것이다.

즉, 단순하게 64bit는 더 많은 주소를 할당할 수 있어서 더 큰 저장공간을 활용할 수 있다는 의미이다.

  포인터 변수 배열이름
이름이 존재하는가? 존재 존재
무엇을 나타내거나 저장하는가? 메모리 주소 값 메모리 주소 값
주소값의 변경이 가능한가? 가능 불가능
728x90
작성일
2023. 3. 15. 17:54
작성자
WDmil
728x90

이번에는 전역변수에서의 함수가 어떤식으로 전역변수와 지역변수를 받는지 알아보자

local count 가 1이 되는것 을 알 수 있다.

지역변수가 1이 계속 선언됨 으로 선언될 때 마다 1이 한개 더해지고 1이 되고가 반복되어 local count가 1로 출력된다.

여기서 static 으로 선언하면 어떻게 되는지 보자.

위와 같이 나타남을 알 수 있다. static int 가 count가 데이터가 중첩됨을 알 수 있다.

즉, count가 전역변수 처럼 취급되어 데이터가 중첩됨을 볼 수 있다.

static은 한번만 초기화를 (최초선언시에만 변형이 가능하다.) 유효범위는 선언한 위치에서만 동작한다.


    Memory structure
    ------------------------------------------------------------------------ High Address
    |                        스택 영역                              |
    |                         Stack                                   | -->  메모리 크기를 컴파일러가 예측 가능 할때 사용,

   ㅣ                        ㅣ                                       ㅣOS에 메모리를 받아올때 속도가 빠름
    |                           |                                         |
    . . . . . . . . . . . . . . | . . . . . . . . . . . . . . . . . . .
    |                           |                                         |
    |                           v                                        |
    |                          Free                                   |
    |                           ^                                        |
    |                           |                                         |
    . . . . . . . . . . . . . . | . .  . . . . . . . . . . . . . . . . . . .
    |                           |                                         |
    |                         Heap                                   | --> 메모리 크기를 예측 불가능 할때
    |                        힙 영역                                 |
    ---------------------------------------------------------   이 아래는 프로그램 시작전 메모리가 잡힌다
    |                           bss                                    | 초기화 되지 않은 전역변수가 저장되는 공간.
    |                            |                                        |
    |            Initialized Global/Static Variables     |
    |                        Data                                      |
    |                      데이터 영역                             |
    ---------------------------------------------------------
    |                                                                      |
    |                  Program Code(Read Only)         |
    |                         code                                     |
    |                        코드 영역                              |
    ---------------------------------------------------------- Low Address

    위로갈수록 가지는 주소값이 크다
    os에따라 다를수 있다.

 

전역변수는 0으로 선언하지 않아도 자동으로 0으로 초기화된다. 이러한 전역변수는 

bss에 저장된다.

stack

데이터가 저장된다. 저장되는것은 후입선출로 관리된다. 스텍은 영역이 크지 않아서 오버플로우가 발생할 수 있다.

for문이나 while문이 조건이 잘 들어가지 않아서 무한적으로 동작하면 메모리오버플로우가 일어나서 정지하는것 을 확인할 수 있다. 그것을 스텍오버플로우 라고 한다.

지역변수가 저장된다.

 

Heap

데이터의 메모리크기를 예측 불가능 할 때 동적영역을 조정해주어야 할 때 사용한다.

그러나 메모리를 직접적으로 건들여야 하기 때문에 불안정하고 느릴 수 있다.

그리고 사용자가 메모리 할당을 해제해줘야 하는 필요성이 있다.

이렇게 보면 되는데, 이걸 순서대로 작업해보면 다음과 같다.

1 sum              
2 sum num1            
3 sum num1 int n          
4 sum num1 int n num2        
5 sum num1 int n          
6 sum num1            
7 sum num1 int n           
8 sum num1 int n  num2        
9 sum num1 int n          
10 sum num1            
11 sum              
12                

이런 순서로 후입선출의 방식으로 동작하게 된다.


문자열, String에 대해 알아보자.

문자열은 char의 배열로 관리하게 되는데,

위와 같이 문자열이 스트링으로 출력된다.

이러한 문자열은 어떤식으로 저장되는지 표시하면,

h e l l o .... g e NULL  

이렇게 저장된다.

마지막은 NULL로 저장되어 문자열이 끝났다는 표시를 해주어야 컴퓨터가 그만 읽고 종료할 수 있기 때문이다.

예시를 보자.

이런식으로 표시가 되는데, \0, 0, NULL로 모두 표현이 가능하다. 그러나 '0'은, 아스키코드의 0을 표기하기 때문에 사용하면 48이 출력되어 사용하면 안된다. 표현예시를 한번보자.

 

위와 같이 표시가 될 것 이다.
배열이 5개가 아닌 6개임을 알 수 있다. 마지막에 0이 들어가기 때문
각각의 str을 다루는 변수를 예시로 출력한것이다. define으로 오류코드를 무시하게 선언해주어야 한다.

728x90
작성일
2023. 3. 10. 15:52
작성자
WDmil
728x90

로또생성기 만들기

 

로또 생성기를 만들어보자

 

먼저 로또번호를 생성하기 위해서는 무엇이 필요한지 나열한다.

  • 로또번호는 랜덤함수로 생성해야한다.
  • 보너스번호 가 존재한다면, 일반번호 와 보너스번호를 나누어 주어야 한다.
  • 모든 코드가 순환하며, 내가 입력한 번호가 랜덤 생성한 번호와 같은지 검사해야한다.

예시를 보자.

이렇게 작성할 수 있다.

만약, 복권번호를 작은수 부터 나열한다고 가정하면, Sort함수를 사용해서 값들을 정렬해야 한다.


재귀함수 를 사용한 파보나치 수열

 

재귀함수를 사용한 피보나치를 출력한다.

 

코드는 매우 간단하다. 예시를 보자.

단 3줄만 들어가면 출력할 수 있다.

 

쉽게 이해가 가지 않는다면, 풀어서 이해해보자.

 

파보나치 수열의 5번째 수를 출력하려고 한다고 가정한다.

파보나치 수열의 5번 째 수는 0 1 1 2 3 임으로 3이다. 어째서 3이 나오는지를 풀어서 해석해보면,


n5 = [n4 + n3] = [n3 + n2] + [n2 + n1] = [n2 + n1] + 1 + 1 + 0 = 1 + 0 + 1 + 1 + 0 = 3
n4 = [n3 + n2] = [n2 + n1] + 1 = 1 + 0 + 1 = 2
n3 = [n2 + n1] = 1 + 0 = 1
n2 = 1
n1 = 0


위와같이 나타난다.

 

정리하면, 파보나치 수열은 수많은 n1+n2로 이루어져 있고, 그것을 밑부터 전부 더해서 결과값을 도출하게 된다.

이렇게 재귀함수를 풀어서 계산하거나 어떠한 함수의 규칙성을 찾아내면 쉽게 코드로 구현할 수 있다.

 

출력 예시는 다음과 같다.


각 학생의 평균점과 합점, 그리고 총점을 구하는 코드

 

각각 학생의 평균점과 합점 그리고 총점을 구하는 2차원배열과 코드를 만들어본다.

 

먼저 필요한 데이터 산출을 나열해보자.

  • 학생들의 점수를 받아올 배열이 필요하다.
  • 배열값들의 총점을 구해야한다.
  • 배열값들의 평균점을 구해야한다.
  • 배열값들의 합점을 구해야 한다.

위와같이 작성할 수 있을것이다.


변수 간의 저장범위 와 조정범위

변수간의 저장범위와 조정범위를 알아보자.

 

변수는 전역변수, 지역변수 가 있다. 각각의 특징을 코드 예시로 살펴보면서 알아본다.

전역변수

 

쉽게 풀어쓰자면, 전역변수는 말 그대로 전(체 영)역 변수 라고 이해하면 된다.

 

int main()코드 이외의 부분에 작성되는 모든 데이터는 전역 변수 라고 한다.

자기자신 위에 선언된 모든 전역변수는 참조할 수 있다.

C++임으로, 순서에 유의해서 작성하도록 하자.

 

지역변수

 

쉽게 풀어쓰자면, 지역변수는 일정 지역에서만 활용할 수 있는 변수 라고 이해하면 된다.

 

{} 괄호 안에 넣은 변수는 {} 괄호를 벗어나면 사용할 수 없다. 초기화되어 사라지기 때문이다.

그렇기 때문에, { } 지역 안에서 사용한다. 한정된 지역에서 사용한다고 하여 지역변수 이다.

 

728x90