Program/C++
- [C++강좌] - 1-5-2. namespace에 대해 2012.04.17
- [C++강좌] - 1-5-1. namespace에 대해 2012.04.17
- [C++강좌] - 1-4.인라인함수 2012.04.17
- [C++강좌] - 1-3.디폴트 매개변수 2012.04.17
- [C++ 강좌] - 1-2.함수 오버로딩 2012.04.17
- [C++ 강좌] - 1-1.달라진 입출력 2012.04.17 1
- 입/출력(cin,cout) 2012.04.17
- [C언어] 문자열을 숫자(정수 int long; 실수 double)로 변환하는 함수 2012.04.16
- typeid, type_info 2012.03.24
- [C 프로그래밍] 함수포인터 2012.03.24
[C++강좌] - 1-5-2. namespace에 대해
[C++강좌] - 1-5-1. namespace에 대해
위 예제는 인자값과, 함수명이 동일하기 때문에 함수 오버로딩도 성립하지 않습니다.
[C++강좌] - 1-4.인라인함수
위와 같이 매크로 함수를 이용하면, 소스내에 매크로가 완전히 대치되기 때문에,
[C++강좌] - 1-3.디폴트 매개변수
위 코드는 디폴트 매개변수의 예를 보여주고 있습니다.
[C++ 강좌] - 1-2.함수 오버로딩
[C++ 강좌] - 1-1.달라진 입출력
[출처] [C++ 강좌] - 1-1.달라진 입출력 -|작성자 leanix
안녕하세요? leanix입니다!
이제부터 C++에 대한 강좌를 시작할 것이며, 많은 것을 알아가셨으면 하는 마음을 가지고 시작합니다.
강좌에 나온 모든 예제는 컴파일후, 소스와 프로그램을 올리겠습니다.
*C언어를 배우셨다는 전제하에 실시합니다.
┌───────────────┐
---앞으로의 목차---
1. 달라진 입출력
2. 함수 오버로딩
3. 디폴트 매개 변수
└───────────────┘
1-1. 달라진 입출력
C언어를 배우며 제일 처음 접해본 프로그램이 아마, HelloWorld.exe 였을 것이라 생각합니다.
#include
int main(){
printf("Hello World!");
return 0;
}
이런 간결하고도 간결한 코드였죠.
C++에서도 마찬가지로 C++스타일의 Hello Word 를 작성하는 것으로 그 장대한 시작을 울려봅시다!
/*
HelloWorld.cpp
.cpp 를 사용하셔야 합니다. C++의 문법을 적용시키기 위함입니다.
*/
#include
int main(){
std::cout<<"Hello World"<
std::cout<<'A'<<123<
return 0;
}
이것이 C++의 출력의 기본입니다.
C++에서는,
iostream 헤더를 포함시킵니다.
std::cout<<출력할것 의 형식으로 출력을 합니다.
std::endl은 한줄을 넘기는 의미를 지닌다.(=\n)(endline의 약자)
std::cout<<출력1<<출력2; 등의 형식으로 이어쓸수 있다.
간단하죠??
그렇다면 이번에는 C++스타일의 입력을 알아봅시다.
/*
Plus.exe
*/
#include
int main(){
int v1,v2;
std::cout<<"1번쨰 숫자입력 : ";
std::cin>>v1;
std::cout<<"2번째 숫자입력 : ";
std::cin>>v2;
int result=v1+v2;
std::cout<<"덧셈 : "<
return 0;
}
그렇게 어렵지 않아 보입니다.
std::cin>>변수 의 형식을 통해 값을 입력받습니다.
역시, std::cin>>변수1>>변수2; 의 형식을 취할수 있습니다.
C와는 다르게, 변수의 선언이 앞부분 뿐만이 아닌, 어디서도 할수 있습니다.
이것이 printf, scanf를 대신하는 C++의 다입니다! 간단하죠??
덤으로, C++에서는
int i;
for(i=0; i<10; i++){...}
같은 코드를,
for(int i=0; i<10; i++){...}
처럼 줄일수 있습니다.
또한 Visual Studio 7.0 이상부터는 지역변수로 인정이 되어서,
for(int i=0; i<10; i++){
std::cout<
}
int i;
처럼 변수를 두번 선언하는 코드도 상관이 없답니다!!
그럼 다음강(1-2) 에서는 함수 오버로딩에 대해 알아봅시다!!
[출처] [C++ 강좌] - 1-1.달라진 입출력 -|작성자 leanix
입/출력(cin,cout)




[C언어] 문자열을 숫자(정수 int long; 실수 double)로 변환하는 함수
컴퓨터에서는 같은 1234 라고 해도, 문자열로서의 1234 일 수도 있고, 진짜 숫자로서의 1234 일 수도 있습니다.
문자로서의 숫자를, 진짜 숫자로 바꾸어서 연산을 할 수 있게 해주는 함수들입니다.
atoi() : String To int
문자로 된 숫자를, 진짜 숫자의 정수로 변환
#include
int main() {
int num;
char *s = "1234.9999";
num = atoi(s);
printf("문자 = %s\n숫자(int) = %d\n", s, num);
return 0;
}
실행 결과:
문자 = 1234.9999
숫자(int) = 1234
만약 문자열에 소수점이 있다면 반올림하지 않고 소수점 이하를 무조건 무시합니다. 에러가 난다면 0을 반환합니다.
그래서 위의 소스가 만약 char *s = "ABCD"; 이렇게 되었다면 "숫자(int) = 0" 으로 출력됩니다.
atoi() 함수는 stdlib.h 에 정의되어 있습니다.
atol() : String To long
int 가 아닌 long형 정수로 변환할 때는 atol()을 사용합니다.
#include
int main() {
long num;
char *s = "98765432";
num = atol(s);
printf("문자열 = %s\n숫자(long) = %ld\n", s, num);
return 0;
}
실행 결과:
문자열 = 98765432
숫자(long) = 98765432
atof() : String To double
문자로 된 숫자를, 진짜 숫자의 실수로 변환
#include
int main() {
double f;
char *s = "12345.67";
f = atof(s);
printf("문자열 = %s\n실수(double) = %0.3f\n", s, f);
return 0;
}
실행 결과:
문자열 = 12345.67
실수(double) = 12345.670
atof() 함수는 double형 실수를 반환합니다. 그래서 이것을 float형 실수로 받으면
warning C4244: '=' : conversion from 'double' to 'float', possible loss of data
이런 경고가 나오게 됩니다.
▶▶ [C언어] 숫자(정수;int, long, unsigned long)를 문자열로 변환하는 함수 - itoa()
▶▶ [C언어] 숫자(실수;float)를 문자열로 변환하는 함수 - sprintf()
16진수 문자열을 숫자로 변환: ▶▶ C언어] 헥사(HEX; 16진수) 문자열을, 10진수 정수 숫자로 변환 함수; Hex String to Int Number
2진수 문자열을 숫자로 변환: ▶▶ C언어] 2진수 문자열을, 10진수 정수 숫자로 변환 함수; Base-2 String to Int Number
typeid, type_info
필요헤더 : typeinfo.h 또는 typeinfo( std 이름공간 사용, 밑에서는 생략 )
두 타입이 같거나 같지 않음을 비교, 또는 타입을 문자열로 바꿔줄 때 typeid와 type_info를 사용할 수 있다.
이 두 녀석은 '실행시간' 에 행해진다.
먼저 두 타입을 비교하기 위해서는 typeid( 타입 ) 을 사용한다. typeid 는 지정한 타입에 특정지어지는 type_info 의
참조값을 반환한다. type_info 는 ==, != 연산자를 가지고 있어서 이 연산자를 통해 비교할 수 있다. 즉,
if( typeid( int ) != typeid( char ) )
printf( "같지 않은데요.\n" );
위와 같이 사용할 수 있다.
만약 type_info 의 참조값을 어디엔가 유지하고 싶다면 다음을 주의하자. 타입에 대한 참조값은 항상 일정한 것은 아니다. 이것은
&typeid( int ) == &typeid( int ) 가 항상 성립한다고 볼 수 없다는 것이다. 참조값을 유지한다면 참조에 대한 포인터를 유지하고
비교시 포인터의 값을 비교해야 된다.
예 :
const type_info *int_type = &typeid( int );
const type_info *char_type = &typeid( char );
if( *int_type != *char_type )
printf( "같지 않은데요.\n" );
다음으로 타입에 대한 문자열을 얻는 방법인데, 이것은 type_info 객체를 이용하는 것이다.
type_info 클래스는 생성자와 복사대입연산자가 private 로 설정되어 있어서 객체를 직접 생성하는 것은 불가능하고
typeid 로부터 얻어내야 한다. type_info 멤버함수에는 name() 함수가 있는데 이것은 자료형에 대한 const char* 타입의 문자열을
반환해준다. 즉,
printf( "이 타입은 %s타입이네요.\n", typeid( int ).name() );
과 같이 작성할 수 있다. 하지만 타입에 대한 문자열 변환은 표준에 없는 내용이어서 그 결과를 예측하기는 어렵다.
VC++6.0 에서는 다음과 같은 형태로 출력해준다.
class A
{
...
};
printf( "이 타입은 %s타입이네요.\n", typeid( A ).name() );
결과 : 이 타입은 class A타입이네요.
[C 프로그래밍] 함수포인터
포인터? 생각만 하면 머리가 아파오는 녀석이죠..C 언어로 생계를 유지해온 저로서도 복잡한 포인터를 보면 피하고 싶습니다..이런 포인터 인데 함수포인터라니? 이건 뭐 대마왕급이군요...
그런데 이런 대마왕도 상황에 따라, 그리고 고급프로그래밍을 위해서 간간히 써주어야만 하는 돌발상황이 발생하곤 합니다..어쩔수 없는 운명이죠..TT
피할수 없다면 한번 부딪혀 보는 건 어떨까요? 기초 개념만 잡으면 너무 쉽다(?)고 느끼실 겁니다..자, 그럼 기본부터 한번 시작해 보겠습니다..
우선 다음과 같은 코드를 보죠..아주 단순한 코드입니다..
-----------------------------------------------------------------------------------
main()
{
int a = 10;
int* b = &a;
...
...
}
-----------------------------------------------------------------------------------
변수 a 에 10을 대입하고 변수 b 에는 a 의 주소값을 저장합니다. 그럼 여기서 질문하나 해볼까요? 변수 a 와 b 는 어디에 존재할까요? CPU ? 하드디스크 ? 아님 메모리?
모두 아시겠지만 변수는 메모리, 정확히 말하면 RAM 에 존재합니다. 아래 그림에 간략히 나타내보았습니다.
그럼 다음 코드를 한번 보겠습니다..좀전보다 조금 어렵습니다..(???)
-----------------------------------------------------------------------------------
void func(int x)
{
printf("x = %d\n",x);
}
main()
{
int a = 10;
int* b = &a;
func(a);
}
-----------------------------------------------------------------------------------
이번에는 함수 func 라는 놈이 등장했네요..여기서 다시 질문하나 할께요..변수는 RAM 에 저장되는데 그럼 함수 func 는 어디에 저장될까요? 또 main 도 특별한 함수죠..즉, 시작할때 제일 먼저 불리는 함수..이런 함수들은 도대체 어디에 존재하는걸까요????
함수는 변수와 마찬가지로 RAM 에 저장되어 있습니다...왜냐면 실행되는 모든 프로그램은 RAM 에 저장되어야 하는데 함수도 프로그램의 일부이니까요..그림으로 나타내 볼까요..
위 그림처럼 RAM 의 어딘가에 func 라는 함수부분이 저장되어 있습니다. RAM에는 언제나 주소가 있죠? 예를 들어 변수 a 는 &a 라는 주소에 있고 변수 b 는 &b 라는 곳에 있습니다. 그럼 func 는 어디에 있을까요?
주소를 나타내려면 & 를 붙인다고 했으니 &func? 아님 임의의 다른곳??
C 언어에서 함수가 저장되어 있는 주소값은 바로 함수 이름입니다. 즉, 함수이름이 함수가 저장되어 있는 첫번째 번지를 나타냅니다. (마치 배열과 비슷합니다. 배열 이름이 배열의 시작주소를 나타내는 것처럼요..) 그래서 func 라는 함수가 저장되어 있는 번지는 func 이고, main 함수가 저장되어 있는 번지는 main 입니다..(많이 헛갈리시죠..예전에 제가 그랬습니다...)
이제 함수가 저장되어 있는 주소값을 알았으니 그 값을 저장할수 있는 변수도 있어야겠죠..이렇듯 함수가 저장되어 있는 주소값을 저장할수 있는 변수를 '함수포인터' 라고 합니다. 즉, 함수포인터는 함수의 이름을 가지는 변수입니다..
그럼 함수이름을 저장할수 있는 변수는 어떻게 선언하고 초기화 할까요? 다음의 소스를 한번 보죠..
-----------------------------------------------------------------------------------
void func(int x)
{
printf("x = %d\n",x);
}
main()
{
int a = 10;
int* b = &a;
void (*test)(int);
test = func;
func(a);
}
-----------------------------------------------------------------------------------
우선 'void (*test)(int);' 부분입니다. 해석을 해보면 test 라는 변수는 인자로 한개의 정수(-int-) 를 가지고 반환형이 없는 (-void-) 함수를 가리키는 포인터이다 입니다. 이렇게 선언된 test 라는 변수에 func, 즉 func 가 저장되어 있는 주소값(-함수이름-)을 대입하는 곳이 소스에서 'test=func' 입니다. (func 함수가 인자로 정수한개를 받고 반환형은 없죠..확인해보세요)
그림을 통해 이해해보죠..
이제 마지막으로 함수포인터를 통해 함수가 어떻게 호출되는지 알아보겠습니다..소스코드에서 변수 포인터 b 를 통해 a 를 접근하고자 할때 '*b' 라고 기술했습니다. 그럼 함수포인터는 ? 함수포인터도 변수 이므로 *b 처럼 * 연산자를 이용해 함수를 접근할수 있습니다.다음의 코드를 보면서 결과값이 같다는 것을 확인해보시기 바랍니다...코드에서 (*test)(a) 의 해석은 다음과 같다고 할수 있습니다. 'test 라는 변수가 가리키는 곳에다 a 값을 넘겨준다'
-----------------------------------------------------------------------------------
void func(int x)
{
printf("x = %d\n",x);
}
main()
{
int a = 10;
int* b = &a;
void (*test)(int);
test = func;
func(a);
(*test)(a);
}
-----------------------------------------------------------------------------------
어떠신가요? 함수포인터라고 무시무시한 이름을 가지고 있지만 막상 별것 없죠..이런 함수포인터는 속도가 중요시되거나 그래픽관련 프로그래밍을 구현하고자 할때 가끔 쓰입니다. 또한 커널 프로그래밍을 할때도요..그러나 기본에 충실하시면 어렵지 않게 이해 할수 있을거라 믿습니다..
(이제 함수 포인터는 대마왕의 자리를 내주고 쓸쓸히 은퇴해야겠네요..)
다음의 예제를 한번 풀어보시고 이해해 보시기 바랍니다...(다음주제는 네트웍프로그래밍을 진행해 볼까 합니다..많은 응원부탁 ^^..)
언제나 즐거운 시간만 되세요...
[1] int (*fPtr1)(int); [이해난이도 : 하]
[2] int (*fPtr2)(int, int); [이해난이도 : 하]
[3] void (*signal(int, void(*handler)(int)) ) (int); [이해난이도 : 최상]