C/C++ 개발툴 및 환경

공식 홈페이지
http://en.wikipedia.org/wiki/ANSI_C
그런거 없지 아마?

IDE
- VisualStudio
- DevC++
http://www.bloodshed.net/devcpp.html

MinGW(Minimalist GNU for Windows)
GCC환경을 윈도우에서 사용할 수 있게 해주는 그런거
http://www.mingw.org/

Eclipse
역시 가능

Netbeans
도 가능

Xcode
맥에선 이걸로

CodeBlocks
http://www.codeblocks.org/
크로스플랫폼 여러언어 지원되는 개발툴

SciTE
http://www.scintilla.org/SciTE

gcc
GNU C 컴파일러
http://gcc.gnu.org/
http://ko.wikipedia.org/wiki/GNU_%EC%BB%B4%ED%8C%8C%EC%9D%BC%EB%9F%AC_%EB%AA%A8%EC%9D%8C

g++
c++용 gcc

라이브러리나 개발환경이나 컴파일러 등등
STL (Standard Template Library)
C++ 라이브러리
http://ko.wikipedia.org/wiki/%ED%91%9C%EC%A4%80_%ED%85%9C%ED%94%8C%EB%A6%BF_%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC

WinAPI
윈도우용 api

MFC
win api를 쓰기쉽게? 만들어놓은 프레임워크

.net
닷넷에 얹는것도 가능..
근데 미쳤다고 복잡한 씨언어를 닷넷에서? 그냥 C#을 써야지

Objective C(objc)
맥에서는 여기 얹어서도 구동가능.. xcode환경에서 gcc이용하는듯? 아님말고 안해봐서 모른다

GTK
QT랑 용도는 비슷한데 gpl라이센스

QT프레임워크 ㅄ프레임워크 lgpl
라이브러리... 윈/맥/리눅스 환경 지원해주는 라이브러리

define 매크로와 inline 함수

매크로 함수

#define PI 3.14
#define SQUARE(x) ((x)*(x))

result=SQUARE(5);

result=SQUARE((5)*(5));
로 교체된다.

C++에서 in-line화

inline int ADD(int x, int y)
{
 return x+y;
}
int main()
{
 std::cout<<ADD(2,3)<<std::endl;
 return 0;
}

매크로를 이용한 함수의 in-line은 전처리기에 의해서 처리
키워드 inline을 이용한 함수의 inline은 컴파일러에 의해서 처리 - inline이 성능에 안좋다고 판단되면 무시

레퍼런스 = Reference = 참조

같은 &를
int &ref = val; //레퍼런스 선언에 사용
int *pval = &val; //포인터 주소값을 가져오는데 사용

int &ref = val;
val과 ref는 같은 것이다. 하나의 이름이 더 생긴것..

int &ref1 = val;
한개 더 선언해도 됨

int &ref2 = ref1;
레퍼런스로 레퍼런스를 선언해도 됨? 될듯

레퍼런스를 활용한 Call-By-Reference

71p
포인터를 이용한 Call-By-Reference도 가능하지만..

void swap(int *a, int *b);
//포인터를 통해 함수에 값을 전달한다.
a의 값을 변경할 때 *a라고 쓰는것도 귀찮고,
작은 조작 실수로 에러가 잘 발생한다.
가능하지만 좀 불편하다.

그래서 좀 더 안전한

레퍼런스를 이용한 Call-By-Reference를 사용

void swap(int &a, int &b);
//값을 레퍼런스로 받는다.
int main(void)
{
swap(val1, val2)
...
}

Call-By-Value는 값을 전달한다.
데이터의 복사가 발생해서 비효율적이다.
int swap(int a, int b);
인 경우에는 int값 2개를 받고 1개를 내보내지만
구조체일 경우에는 값이 커진다.

typedef struct _Account
{
    int id;
    int balance;
    char name[100];
} Account;
형태로 구조체가 선언된 상태에서..

Account ShowData(Account p) //구조체로 입력받고 구조체로 반환하려면 큰 값이 복사가 발생한다.
void ShowData(Account &p) //레퍼런스로 하면 편하기도 하고 속도도 빠르다.

레퍼런스로 리턴하는 방법
int &increment(int &val)
{
  val++;
  return val;
}
int main(void)
{
..........
 int &ref=increment(n)
........}

위 예는 main함수에서 전달받은 레퍼런스값을 반환 하는거고...
지역변수로 선언됐다면 레퍼런스로 반환할 수 없다. 80p
지역변수는 함수가 없어질 때 없어지기 때문에 레퍼런스로 반환하면 갈 길을 잃게된다.

malloc - free → new - delete , 그리고

cin<<size; //할당할 배열의 크기
int* arr=(int*)malloc(sizeof(int)*size);
arr의 포인터를 선언해서 재미보고
free(arr);
풀어준다.

왜 이따위로 복잡하게 만들었는지... 외웠는데 기억도 잘 안난다.
그냥 쓸때마다 찾아봐야지

int i, j
arr[i][j];로 쓸 수 있게 해놓음 편하잖아
컴파일러에서 자동으로 매크로처럼 돌려주면 좋을 것 같은데..

c++ 에서는 조금 더 편해졌다.

int * val = new int;
//포인터까지는 동일한데 new int로 쉽게 메모리를 할당한다.
int형태로 하니까 sizeof도 필요없고..

int * arr = new int[size];
// size는 배열의 사이즈.. 앞에서 입력받는다. cin<<size;
구조체 선언
typedef struct Person
{
 name[100];
 num[100];
} Person;

Person * arr= new Person[size];
//구조체도 가능..하겠지?

반환방법도 간단
delete val;
delete []arr;
delete []Person;

new연산자 메모리 할당 성공 실패 체크

new는 메모리 연산을 실패할 경우 NULL포인터를 리턴한다.
if(arr==NULL)
{
  cout<<"메모리 할당 실패"<<endl;
  return -1; //프로그램 종료
}

프로그램에 if가 들어가서 시스템 효율만 떨어뜨린다.

그래서...p88
#define DEBUG 1 //테스트시 1로...
//#define DEBUG 0  //최종 버전 컴파일시 0으로..

#if DEBUG==1
  cout<<"디버그 모드 "<<endl;
  if(arr==NULL)
  {
    cout<<"메모리 할당 실패"<<endl;
    return -1;
  }
#endif

#if, #endif는 컴파일 단계에서 DEBUG가 1이면 저걸 컴파일 하라는 전처리 명령 1이 아니면 컴파일 하지 않고 넘어간다.

구조체structure를 대체하는 클래스Class , public, private, protective

- struct은 기본 멤버의 속성이 public이고


- class는 기본 멤버의 속성이 private이다.

클래스는 구조체를 포함
클래스 = Attribute + Method
Attribute - 멤버 변수
Method - 멤버 함수
그렇다고 하는데 이걸 구별해서 써야 될 필요가 있는지는 모르겠다.
class에 public protective private를 나눠서 쓰면 되는건데

구조체
각각의 변수를 모아서 쓰기 편하게 뭉쳐놓은 것

struct나 typedef는 선언하기 귀찮고 불편한다.

C++에서는 이 부분이 개선된다.

typedef struct Person
{
}Person;
이런식으로 선언해야 되서 귀찮았는데

struct Person
{
};
으로 간단해졌다.

struct Person
{
 int a;
 int b;

 void ShowData(int id); // 함수도 막 넣는다.
};

그럼 구조체가 아닌 클래스Class

Class는 변수가 아닌 객체
객체Object는 현실의 모든 사물, 또는 추상적인 개념으로 구분할 수 있는 한 덩어리를 말한다.
완전한 대상체'라는 의미를 지닌다.

데이터 추상화(Data Abstraction)
사람
 → 멤버 변수 : 이름, 나이, 친구명단, 재산, ...
 → 멤버 함수 : 밥하기, 운전하기 (좀 아닌가..), ...

프로그램에서 한 형태에게 필요로 하는 것을 추가...
도서관에서 사람의 멤버함수라면 ... 대여, 반납, 도서신청 등이 추가될 수 있을듯..

인스턴스화(instantiation)
: 클래스를 기반으로 객체를 생성하는 것

public protective private
public - 공용 : 클래스 밖에서 접근 가능
protective - 상속전에는 private, 상속후에는 public처럼 동작
private - 클래스 안에서만 접근 또는 변경 가능

class Person
{
 int a;
 int b;
void Borrow();
void Return();
void Application();
}

void Person::Borrow() //class의 밖에서 함수를 선언할 때
{
}

inline void Person::Return() //class의 밖에서 내부에 선언하는것처럼 선언
{
}

먼 차인지는 몰겠다.

헤더 파일을 이용한 파일 분할

Door.h
#include <iostram>
using std::cout;
using std::endl;

const int OPEN=1;
const int CLOSE=2;

class Door
{
private:
    int state;

public:
    void Open();
    void Close();
    void ShowState();
}

Door.cpp
#include"Door.h"
void Door::Open()
{
    state=OPEN;
}
void Door::Close()
{
    state=CLOSE;
}
...........생략
}

Main.cpp
#include"Door.h"

int main()
{
    Door d;

    d.Open();
    d.ShowState();

    return 0;
}

정보은닉Information Hiding, 캡슐화Encapsulation

기본 속성은 private로 되어 있다.
class Larbor
{
 int pay;
 int time;
};
라고 해 놓으면 pay와 time은 private속성을 갖는다.

class Larbor
{
private:
int pay;
int time;
public:
int SetPay(int a);
int SetTime(int a);
int GetPay(int a);
int GetTime(int a);
}

변수들을 외부에서 직접 접근을 할 수 없게 만든다.
public으로 공개된 함수를 통해서만 변수를 조작할 수 있다.

Get,Set으로 시작하는 함수들은 멤버 변수로 접근하기 위한 함수로 엑세스(Access) 메소드(함수) 라고 부른다.

캡슐화 Encapsulation
: 관련있는 데이터와 함수를 한 덩어리로 묶는것
그냥 함수랑 변수랑 관계있는걸 다 묶는거다.
캡슐화의 필요성은 : p132

C++에서 바뀐 입출력 스타일 헤더, cout, cin, namespace와 std::의 의미, using

헤더
C언어
#include <stdio.h>
C++의 옛날 스타일
#include <iostream.h> //오류발생
C++ 현재 스타일
#include <iostream>

C++에서 추가된 namespace 40p

여러 사람이 동시에 한 프로젝트를 만들 때 중복된 함수명, 변수명을 쓰게 된다면..?
컴파일 오류가 발생한다.
그럼 일일이 중복되는 것들을 다 고쳐줘야된다.
namespace는 이런 상황을 방지하기 위해 나온 것

namespace AAA
{
  void function()
 {
 }
}
namespace BBB
{
 void function()
 {
 }
}

int main(void)
{
 AAA::function() //A함수 호출
 BBB::function() //B함수 호출
}

cout와 cin, endl은 std라는 namespace에 정의된 함수이기 때문에
std::cout, std::cin, std::endl로 사용됨
int k, l;
std::cin>>k>>l;
std::cout<<"하이"<<k<<"명"<<std::endl;
이런식으로 사용..

std::라고 쓰는게 귀찮으니까... 이걸 계속 쓰겠다는 명령을 내려줄 수 있음

using std::cout;
using std::endl;
using std::cin;
이 세 가지는 std::를 안 붙이고 그냥 계속 쓰겠다는 선언

using namespace std;
std의 모든 명령어를 std::안 붙이고 쓰겠다는 선언...
이 경우 중복되는 함수가 있으면 오류가 날 수도 있다.