'C, C++'에 해당되는 글 21건

  1. 2018.09.26 C++ 벡터 사용법 2
  2. 2018.09.25 C언어 포인터 8
  3. 2018.09.08 C++ 자바 상속 비교
  4. 2018.09.06 C 랜덤 - 난수 생성하기 7
  5. 2018.08.20 C++ String 문자열 사용법 정리

C++ 벡터 사용법



안녕하세요 열코입니다.


C++에서 벡터는 표준 템플릿 라이브러리(STL)에서 제공하는 동적 배열구조 클래스입니다.


C의 배열처럼 빠른 랜덤 접근이 가능하며 자동으로 배열의 크기 조절과 추가 삭제가 가능합니다.


모든 자료형에 대해 배열처럼 저장할 수 있지만 한번에 한 타입만 저장이 가능합니다.


자바의 벡터와 마찬가지로 배열 크기를 추가할때 기존 배열 크기의 100%가 늘어납니다.(2배)



먼저 벡터를 선언하는 방법에 대해 알아보겠습니다.



vector<int> integer_vector;

vector<double> double_vector;

vector<char> char_vector;


벡터 클래스는 C++ 모든 자료형의 저장을 지원하며 위 코드와 같이 만들수 있습니다.


벡터에서의 데이터 추가 및 삭제는 배열의 끝에서 O(1), 배열의 중간 O(n)만큼의 시간복잡도가 소요됩니다.



벡터에 데이터 추가하기



for (int i = 0; i < 5; i++) {

integer_vector.push_back(i);

double_vector.push_back((double)i);

char_vector.push_back('a' + i);

}


벡터 클래스에서 push_back() 함수를 이용하여 요소의 끝에 데이터를 추가할 수 있습니다.


지정된 위치에 요소를 추가하려면 insert() 함수를 사용하세요.



벡터의 데이터 삭제하기



integer_vector.pop_back(); // 요소 끝의 데이터 삭제

double_vector.erase(double_vector.begin()); // 지정된 위치의 데이터 삭제

char_vector.clear(); // 모든 데이터 삭제



벡터는 다음과 같은 내부 함수가 존재합니다.



begin() - 벡터의 첫번째 요소를 가리킵니다.


end() - 벡터의 마지막 요소를 가리킵니다.


size() - 벡터의 요소 수(크기)를 반환합니다.


resize() - 벡터의 크기를 재조정합니다.


empty() - 벡터가 비어있는지 여부(true or false)를 반환합니다.


at() (또는 [ ]) - 벡터의 인덱스에 접근할 수 있습니다.


front() - 벡터의 첫번째 요소를 반환합니다.


back() - 벡터의 마지막 요소를 반환합니다.


data() - 포인터가 접근할 수 있도록 벡터의 주소값을 반환합니다( int *p = vector1.data() )



더 상세한 내용을 확인하고 싶다면 여기를 방문하세요.






이상 'C++ 벡터'에 대해 알아보았습니다.


질문 또는 오타나 잘못된 정보가 있는 경우 댓글로 달아주세요!


공감♡ 버튼을 눌러주시면 더욱 유용하고 좋은 포스팅으로 찾아 뵙겠습니다.


'C, C++' 카테고리의 다른 글

C++ 클래스와 객체  (0) 2018.10.09
C/C++ 구조체 사용법 및 예제  (1) 2018.10.08
C/C++ 배열 사용법  (0) 2018.10.05
C 파일처리  (0) 2018.10.02
C언어 포인터  (8) 2018.09.25
C++ 자바 상속 비교  (0) 2018.09.08
C 랜덤 - 난수 생성하기  (7) 2018.09.06
C++ String 문자열 사용법 정리  (0) 2018.08.20

C언어 포인터



안녕하세요 열코입니다.


이번시간에는 C언어 포인터에 대해 알아보겠습니다.


포인터(Pointer)란 프로그래밍 언어에서 변수의 메모리 주소를 가리키는 변수를 말합니다.


포인터는 Low Level 언어(C/C++/어셈블리...등)에서 많이 사용됩니다.



이번 포스트는 다음과 같이 진행됩니다.


1. 포인터 사용법


2. 포인터 활용


3. 포인터와 배열의 차이점



준비되셨으면 그럼 시작하겠습니다!!


먼저 포인터에 대한 사용법에 대해 알아보겠습니다.



1. 포인터 사용법


포인터를 사용하려면 먼저 두가지 연산자에 대한 이해가 필요합니다.


& 연산자와 * 연산자입니다.


scanf에 대해 공부하셨다면 &연산자에 대해 보신적이 있을텐데요.


& 연산자에 대해 조금 설명하자면 변수의 주소에 액세스 하기위한 단항 연산자입니다.


(참고 영어로는 ampersand라고 합니다.)


그래서 scanf는 표준 입력함수로 콘솔에서 입력을 변수에 메모리에 접근하여 저장하기 위해 


& 연산자를 사용하는 것입니다.


아래 예제는 & 연산자를 이용하여 변수의 주소를 출력하는 코드입니다.


#include <stdio.h> // 표준 입출력 라이브러리


int main(void) {

int num = 10; // 정수형 변수 선언

printf("%p", &num); // num의 주소값 출력

}


위 코드는 num이라는 이름을 가진 정수형(Integer) 변수를 선언하고 그 값으로 10이라는 


정수(10진수)를 정의했습니다.


그리고 이 num이라는 변수는 메모리 어딘가(스택영역)에 할당됩니다.


(참고 : 메모리공간은 크게 데이터, 스택, 힙 공간으로 분류됩니다.


여기서 num 변수는 main() 함수의 지역변수이기 때문에 지역변수의 저장 공간인 스택영역에 저장되게 됩니다.)


표준 출력함수인 printf() 함수를 통해 num 변수의 주소값을 출력해보겠습니다.



첫번째 매개변수로 %p를 주었습니다. 왜 %d가 아닌 %p일까요?


%d 는 decimal의 줄임말로 변수를 10진수로 표현하기 위한 포맷(format)입니다.


%p 는 주소값을 표현하기 위한 포맷이라고 생각하시면 되겠습니다.


두번째 매개변수로는 num앞에 &연산자를 추가했습니다. 이는 num변수안에 저장된 값 10이 아닌


num변수가 저장된 메모리 주소에 접근하기 위해 연산자 &를 사용한 것입니다.



우리가 사용하는 컴퓨터의 메모리는 RAM인거 다 아시죠?


RAM은 Random Access Memory의 줄임말로 접근이 임의인 메모리입니다.


따라서 num 변수의 주소값은 출력할 때마다 매번 다른 값을 출력하게됩니다.(직접해보세요)



이제 포인터를 사용하기 위해 * 연산자에 대해 알아보겠습니다.


앞서 배운 & 연산자를 일반적으로 참조 연산자라고 부르며, * 연산자를 역참조 연산자라고 부릅니다.


포인터를 사용하기 위해서는 변수와 자료형 사이에 * 연산자를 추가하면 됩니다.


아래 예제 코드를 참고하세요.


#include <stdio.h> // 표준 입출력 라이브러리


int main(void) {

int num = 10; // 정수형 변수 선언

int *p; // 정수형 포인터 선언

p = &num; // 포인터가 num 변수의 주소값을 가리킴


printf("%d\n", p); // 포인터가 가리키는 변수의 주소 출력

printf("%d\n", *p); // 포인터가 가리키는 변수의 값 출력

printf("%d\n", &p); // 포인터 변수의 주소 출력

}


자 *도 많고 &도 많고 참 헷갈린다 그쵸?


먼저 글로 최대한 간단히 설명하고 그림으로 설명드리겠습니다.


첫번째 줄 부터 설명하겠습니다.




① num이라는 정수형 변수를 선언했습니다. 이로써 스택영역에 num 변수의 메모리가 할당됩니다.


② p라는 정수형 포인터를 선언했습니다. 이로써 힙영역에 p 변수의 메모리가 할당됩니다.


(num이라는 정수형 변수를 가리키기 위한 포인터로써 정수형 포인터를 선언합니다. 


또한 포인터는 힙 영역에 할당 됩니다.)


③ p라는 정수형 포인터에 num 변수의 주소값을 대입했습니다.


(포인터의 주소값을 대입하는 표현을 편의상 가리킨다라고 표현합니다.)



여러분들의 이해를 돕기위해 그림을 직접 그려서 대령했습니다.(짝짝)


메모리는 데이터, 힙, 스택영역이 있다고 위에 설명했죠?


따라서 지역변수인 num은 스택영역할당되고, 포인터 변수인 p는 힙 영역에 할당되었습니다.


그리고 num의 주소값을 p에게 대입(p가 num을 가리킴)을 화살표로 표현했습니다.



여기서 출력값에 대해 알아보면


printf("%d\n", p); // 포인터가 가리키는 변수의 주소 출력


printf("%d\n", *p); // 포인터가 가리키는 변수의 값 출력


printf("%d\n", &p); // 포인터 변수의 주소 출력


은 각각 어떤 값을 출력할까요?


맞추시는 분께는 열코 블로그 3개월 구독권을 드립니다! (필요없음)




자 하나씩 살펴보도록 합시다.


첫번째 p의 출력값은 p가 가리키는 변수의 주소 출력, 따라서 num의 주소값이 0(임의의 주소값)이 출력되겠죠?


두번째 *p의 출력값은 p가 가리키는 변수의 값 출력, 따라서 num의 값 10이 출력됩니다.


세번째 &p의 출력값은 p의 주소값, 따라서 100이 출력됩니다.


위 과정에 대한 이해가 안되시는분은 댓글로 질문남겨주시면 더욱! 더욱! 상세히 설명드리겠습니다.



2. 포인터의 활용은 다음 포스팅에서 소개하겠습니다. ^0^




이상 'C언어 포인터'에 대해 알아보았습니다.

질문 또는 오타나 잘못된 정보가 있는 경우 댓글로 달아주세요!

공감♡ 버튼을 눌러주시면 더욱 유용하고 좋은 포스팅으로 찾아 뵙겠습니다.



'C, C++' 카테고리의 다른 글

C/C++ 구조체 사용법 및 예제  (1) 2018.10.08
C/C++ 배열 사용법  (0) 2018.10.05
C 파일처리  (0) 2018.10.02
C++ 벡터 사용법  (2) 2018.09.26
C++ 자바 상속 비교  (0) 2018.09.08
C 랜덤 - 난수 생성하기  (7) 2018.09.06
C++ String 문자열 사용법 정리  (0) 2018.08.20
[C++] C# 연동하기 / C# dll 파일 만들기  (1) 2018.08.18

C++ 자바 상속 비교



상속의 목적은 C++과 자바 모두 동일합니다.

우리가 상속을 받는 목적은 코드를 재사용하거나 is-a 관계를 생성하기 위함입니다.

그렇다면 이 두 객체지향언어(Object-Oriented Laguage)의 상속의 차이점에 대해 비교해보겠습니다.


◎ 자바에서 모든 클래스(Class)는 직접 또는 간접적으로 Object Class에서 상속받습니다. 자바에서 상속받지 않는 클래스를 작성하면 기본적으로 Object 클래스에서 자동으로 상속됩니다. 


◎ 자바에서는 부모의 부모(조부모; GrandParent) 클래스에 직접 접근할 수 없습니다.(not directly accessible, c++에서는 :: 연산자를 사용하여 접근 가능합니다.) 부모의 부모 클래스에 접근하기 위해서는 부모 클래스를 통해 접근할 수 있습니다. 


예)

class GrandParent {

public void Print() {

System.out.println("GrandParent");

}

}


class Parent extends GrandParent {

public void Print() {

System.out.println("Parent");

}

}


class Child extends Parent {

super.super.Print(); // 에러 발생!!

public void Print() {

System.out.println("parent");    

}

}


class Main {

public static void main(String args[]) {

Child c = new Chid();

c.Print();

}

}


위 코드는 super.super.Print() 줄에서 오류가 발생합니다. 아래 코드처럼 수정할 수 있습니다.


class GrandParent {

public void Print() {

System.out.println("GrandParent");

}

}


class Parent extends GrandParent {

super.Print();

public void Print() {

System.out.println("Parent");

}

}


class Child extends Parent {

super.Print(); // 부모 클래스를 통해 접근 가능!

public void Print() {

System.out.println("parent");

}

}


class Main {

public static void main(String[] args) {

Child c = new Chid();

c.Print();

}

}


◎ 상속받지 않은 다른 클래스에서 protected 멤버에 접근할 수 있습니다.(클래스가 같은 패키지에 존재 해야합니다.)


예)

class A {

protected int x = 10;

}

class B {

public static void main(String[] args) {

A a = new A();

System.out.println(a.x); // 접근 가능!!

}

}


◎ 자바에서 상속은 extends 키워드를 사용합니다. C++과 달리 public, protected, private과 같은 지정자를 제공하지 않습니다. 


◎ 자바에서 메소드는 기본적으로 가상(Virtual) 메소드입니다. C++에서는 virtual 키워드를 명시적으로 사용해야 합니다.


예)

class A {

public void Print() {

System.out.println("A");

}

}


class B extends A {

public void Print() {

System.out.println("B");

}

}


class Main {

public static void main(String[] args) {

A a = new B();

b.show(); // B가 출력!!

}

}


◎ 자바는 추상클래스(abstract)와 인터페이스(interface)를 구분된 키워드로 사용합니다.


◎ 자바는 다중 상속(둘 이상의 클래스에서 상속)을 지원하지 않습니다. C++은 지원합니다.




코드는 직접 작성했기 때문에 오타 때문에 정상적으로 작동하지 않을 수 있습니다.

해당 게시글에 대한 궁금한점 있으시면 댓글로 달아주시면 답변 해 드리겠습니다.

공감♡ 버튼을 눌러주시면 더욱 유용하고 좋은 포스팅으로 찾아 뵙겠습니다.

'C, C++' 카테고리의 다른 글

C/C++ 구조체 사용법 및 예제  (1) 2018.10.08
C/C++ 배열 사용법  (0) 2018.10.05
C 파일처리  (0) 2018.10.02
C++ 벡터 사용법  (2) 2018.09.26
C언어 포인터  (8) 2018.09.25
C 랜덤 - 난수 생성하기  (7) 2018.09.06
C++ String 문자열 사용법 정리  (0) 2018.08.20
[C++] C# 연동하기 / C# dll 파일 만들기  (1) 2018.08.18


C언어 프로그래밍에서 코드를 작성하다보면 무작위의 숫자가 필요한 경우가 존재합니다.

보통 무작위 숫자를 난수라고 표현합니다.

C언어에서 난수를 표현하기 위해서는 라이브러리를 사용해야합니다.


※ 알고가기

라이브러리란 자주 사용하는 함수들을 미리 작성하여 저장해둔 파일로써 보통 헤더파일로 저장됩니다.

이 헤더파일은 #include 라는 코드를 통해 추가해 줄 수 있는데

C언어에서 기본적으로 사용하는 헤더파일은 stdio.h 이며 이는 Standard Input Ouput(표준 입출력)의 약자입니다.

사용방법은 프로그램 코드 맨 윗줄에 #include <헤더파일명.h> 또는 "헤더파일명.h" 으로 사용할 수 있습니다.

보통 < > 는 Standard Library Header에서 사용하며 " "는 User Defined Header를 사용할 때 쓰는것이라 알려져있는데 크게 틀린말은 아닙니다.

< >와 " "의 차이는

- < > : 컴파일러가 미리 정해놓은 위치에서 헤더파일을 찾습니다.

- " " : 컴파일러가 미리 정해놓은 위치에서 헤더파일을 찾고 만약 찾지 못한다면, < >로 바꾸어 헤더파일을 찾습니다.

로 생각하면 되겠습니다. 결국 Header파일을 읽은 것인지 Source파일을 읽을 것인지에 따라 사용을 구분하면 되겠습니다.


다시 본론으로 와서, C언어에서 난수를 만들기위해서는 rand()라는 함수를 사용하면 됩니다.

rand()함수는 stdlib.h 헤더파일에 포함되어있기 때문에 코드 맨 윗줄에 #include <stdlib.h>를 작성해 줍니다.


☞ rand()함수 사용법

#include <stdio.h>

#include <stdlib.h> // rand() 함수 포함 라이브러리


int main()

{

int random = 0; // 정수형 변수 선언

for (int i = 0; i < 10; i++) { // 10번 반복

random = rand()%9; // 난수 생성

printf("%d\n", random); // 출력

}

}


☞ 실행결과


8번째 줄을 보시면 random = rand()%9; 라는 코드가 있습니다.

해석하면 rand() 함수에 의해 난수를 생성하고 그 숫자를 9로 나눈 나머지를 random 변수에 대입하는 코드입니다.


※ 알고가기

rand() 함수에 의해 생성되는 난수 : 0 ~ 32767


rand() 함수에 의해 생성된 난수를 9로 나눈 나머지(%)의 값은 0부터 8까지입니다.

이를 1부터 9까지 난수를 생성하고 싶을때는 다음과 같이 8번째 줄 코드를 변경합니다.


random = rand()%9 + 1;


이는 0부터 8까지 반환되는 난수에 1을 더해줌으로써 1부터 9까지 반환할 수 있도록 하는 코드입니다.


하지만 여기서 문제점이 발생합니다.

분명 개발자가 원하는 난수를 생성하고 출력했지만 그 패턴(규칙)이 매번 일정하다는 겁니다.



다시말해, 프로그램 실행 시(또는 반복문) 항상 같은 난수가 생성된다는 겁니다.

이는 진정한 난수라고 말할 수 없죠.

그렇다면 프로그램 실행 시 매번 다르게 난수를 생성하는 방법은 무엇일까요?


그건 바로 srand()라는 함수를 사용하면 됩니다!

rand() 함수를 사용하기 전에 다음과 같은 코드를 추가합니다.


srand(time(NULL));


무슨뜻이냐면 srand()함수는 rand()라는 함수에 무작위의 시드값을 주기위한 함수이며 그 파라미터로 time(NULL)이라는 매개변수를 전달합니다.

time(NULL)은 1970년 1월 1일 이후 경과된 시간을 초 단위로 반환하는 함수입니다.

이로써 1초 단위로 매번 다른 시드값을 생성해 rand()함수를 호출하는 것입니다.

이해가 안가시는분은 그냥 이걸 써야 진정한 난수가 생성되는구나! 라고 생각하시면 됩니다.

물론 time()함수를 사용하기 위해서 #include <time.h>를 추가해주시는걸 잊지마세요!


☞ 진정한 난수 생성코드

#include <stdio.h>

#include <stdlib.h> // rand()함수 포함 라이브러리

#include <time.h> // time()함수 포함 라이브러리


int main()

{

srand(time(NULL)); // 매번 다른 시드값 생성

int random = 0; // 정수형 변수 선언

for (int i = 0; i < 10; i++) { // 10번 반복

random = rand()%9; // 난수 생성

printf("%d\n", random); // 출력

}

}


☞ 실행결과


3번 실행 한 결과 모두 다른 난수값이 생성되는것을 확인 할 수 있습니다!

이로써 진정한 난수 생성하는 방법 및 코드에 대해 알아보았습니다.





정보가 유익하셨다면 아래 공감버튼 눌러주시면 감사하겠습니다.

질문사항은 댓글로 달아주시면 성의껏 답변해드리겠습니다.



'C, C++' 카테고리의 다른 글

C/C++ 구조체 사용법 및 예제  (1) 2018.10.08
C/C++ 배열 사용법  (0) 2018.10.05
C 파일처리  (0) 2018.10.02
C++ 벡터 사용법  (2) 2018.09.26
C언어 포인터  (8) 2018.09.25
C++ 자바 상속 비교  (0) 2018.09.08
C++ String 문자열 사용법 정리  (0) 2018.08.20
[C++] C# 연동하기 / C# dll 파일 만들기  (1) 2018.08.18


♣ string 헤더파일을 include 해준다. 

    #include <string> ← 추가!


※ append : 문자열 추가 

⇒ 추가 하고자 하는 문자열이 기존 문자열 뒤에 추가됨.

사용법 : str.append("문자열");

* str += "문자열"; 또는 str = str + "문자열"; 도 같은 원리로 작동합니다.


※ assign : 문자열 대입

⇒ 해당 변수에 문자열을 할당.(변수 정의와 같음)

사용법 : str.assign("문자열");

* str = "문자열" 도 같은 원리로 작동합니다.


※ clear : 문자열 삭제

⇒ 해당 변수의 문자열을 삭제한다.

사용법 : str.clear();


※ compare : 문자열 비교

⇒ 해당 변수와 입력 된 문자열을 비교한다.

사용법 : str.compare(str2);

반환값 : str == str2 이면 0 반환 / str > str2 이면 1 반환 / str < str2 이면 -1 반환

(여기서 str > str2 는 대소 비교가 아니라 사전순으로 비교해서 앞, 뒤를 의미)


※ erase : 문자열 삭제

⇒ 해당 변수의 문자열을 삭제한다.(범위 지정 가능)

사용법 : str.erase(시작 위치, 끝 위치); 또는 str.erase(); 

(시작 위치와 끝 위치를 지정해주면 해당 범위의 인덱스의 문자열이 삭제된다. 매개변수 없이 호출하면 clear와 같은 동작)


※ find : 문자 위치 검색

⇒ 해당 변수의 문자열 중 검색하려는 문자의 위치를 반환.

사용법 : str.find('문자');


※ length : 문자열 길이

⇒ 해당 변수의 문자열의 길이를 반환.

사용법 : str.length();

(문자열의 길이는 null을 포함하지 않는다.)


※ to_string : int to string

⇒ int 변수를 string 변수로 변환 

사용법 : string str = to_string(정수)


※ atoi : string to int

⇒ string 변수를 int 변수로 변환

사용법 : int i = atoi(str.c_str());

(atoi 매개변수 인자가 char*이므로 c_str() 함수를 사용하여 변환 해 주어야 함)


※ reverse : 문자열 뒤집기

⇒ 문자열을 역순으로 뒤집는다.

사용법 : 

string s = "abc";

reverse(s.begin(), s.end()); // "cba" 출력




오타나 질문사항은 댓글로 달아주세요!

'C, C++' 카테고리의 다른 글

C/C++ 구조체 사용법 및 예제  (1) 2018.10.08
C/C++ 배열 사용법  (0) 2018.10.05
C 파일처리  (0) 2018.10.02
C++ 벡터 사용법  (2) 2018.09.26
C언어 포인터  (8) 2018.09.25
C++ 자바 상속 비교  (0) 2018.09.08
C 랜덤 - 난수 생성하기  (7) 2018.09.06
[C++] C# 연동하기 / C# dll 파일 만들기  (1) 2018.08.18

to Top