반응형

C, C++ : 운영체제를 구분할 수 있는 매크로변수

알게된 배경

 규모가 큰 프로젝트의 경우 운영체제별로 빌드되는 파일이 달라야 하기 때문에 이를 구분하기 위해서 매크로 변수를 정의하여 구분을 하고 있다.


원리

 컴파일러가 컴파일을 하기 전에 매크로를 먼저 실행을 하는데, 이 때 각 컴파일러는 환경에 대한 매크로변수가 정의 되어 있다. 이 매크로변수의 존재 유무를 가지고 운영체제를 판단하는 것이다. 단, 주의 할 점은 컴파일러자신이 있는 운영체제가 반영된 것이 때문에 윈도우에서 빌드한것은 윈도우에서 실행되고 리눅스에서 빌드된것은 리눅스에서 실행된다. 대신 소스코드만 같은 파일을 사용할 수 있다는 점이다.(그리고 이를 핑계로 고용주에게 운영체제 사달라고 하겠지..)

 실제로 규모가 큰 프로젝트는 C보다는 C++에서 많이 진행되므로 실제 사용하는 경우는 C++에서 사용될 것이다.


매크로 변수들

// windows
// 32 bit, 64 bit
#ifdef _WIN32
#endif
// only 64 bit
#ifdef _WIN64
#endif

// unix
#ifdef unix
#endif
#ifdef __unix
#endif
#ifdef __unix__
#endif

// Mac OS X
#ifdef __APPLE__
#endif
#ifdef __MACH__
#endif

// Linux
#ifdef __linux__
#endif
#ifdef linux
#endif
#ifdef __linux
#endif

// FreeBSD
#ifdef __FreeBSD__
#endif


참고자료

스택오버플로워 답변들 중


반응형

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

gcc C++ : 리눅스 라이브러리 만들기 입문  (0) 2017.06.12
STL C++ : vector 중복원소 제거  (0) 2017.04.28
STL C++ : string을 이용한 뒷단어 검사  (0) 2017.04.24
C++ : 네임스페이스  (0) 2017.04.21
표준 레퍼런스  (0) 2017.02.18
반응형

리눅스/윈도우 C : 현재날짜와 시간 가져오기

알게된 배경

 서버애서 생성하는 파일명에 날짜와 시간요소를 넣어서 생성하기 위해서 시스템의 시간을 알아야 할 필요가 있었다.


리눅스 계열(유닉스)과 윈도우

 윈도우 엄밀하게 말하면, MVC(VS 20xx)에서 사용하는 컴파일러는 C++에 대해서는 지원을 잘하지만, C에대해서는 지원이 잘 안되고 있다. 따라서 본의 아니게 소스코드를 실행할 때 차이점이 발생한다. 물론 이를 해결하기 위해서는 새로 소스코드를 작성하거나 minGW, Cygwin 처럼 리눅스 함수를 윈도우에 맞게 포팅해주는 컴파일러를 사용하면된다(하지만 socket 계열은 지원이 안되는 걸로 기억한다).

 시간에 대해서 더 자세히 알기 위해서는 struct tm에 대해서 검색을 해보도록 하자.



리눅스 소스코드

 C++에서는 헤더파일을 ctime으로 호출이 가능하며, 동일하게 사용이 가능하다.

// clock.c
#include <stdio.h>
#include <time.h>

void printTime(void)
{
    time_t timer;
    struct tm* t;

    timer = time(NULL);
    t = localtime(&timer);

    printf("UNIX Time : %d [sec]\n\n", timer);
    printf("year : %d\n", t->tm_year + 1900);
    printf("month : %d\n", t->tm_mon + 1);
    printf("days : %d\n", t->tm_mday);
    printf("hour : %d\n", t->tm_hour);
    printf("min : %d\n", t->tm_min);
    printf("sec : %d\n", t->tm_sec);
}


윈도우 소스코드

 리눅스 소스코드와 차이점은 struct tm 포인터 객체 대신 객체 자체를 선언하면 되며, localtime_s()를 사용한다.

// clock.c
#include <stdio.h>
#include <time.h>

void printTime(void)
{
    time_t timer;
    struct tm t;

    timer = time(NULL);
    localtime_s($t, &timer);

    printf("WINDOWS Time : %d [sec]\n\n", timer);
    printf("year : %d\n", t->tm_year + 1900);
    printf("month : %d\n", t->tm_mon + 1);
    printf("days : %d\n", t->tm_mday);
    printf("hour : %d\n", t->tm_hour);
    printf("min : %d\n", t->tm_min);
    printf("sec : %d\n", t->tm_sec);
}


참고자료

블로그: 유닉스 현재시간 아는 방법 소개


반응형

'C' 카테고리의 다른 글

리눅스 C : TCP 소켓 프로그램  (0) 2017.05.24
Linux C : 파일이나 폴더 조회하기  (0) 2017.04.24
C : 구조체를 네임스페이스처럼 사용하기  (0) 2017.04.22
C : 문자열 숫자 변환  (0) 2017.04.21
C : extern 키워드  (0) 2016.11.28
반응형

STL C++ : string을 이용한 뒷단어 검사

정리한 배경

 문자열 처리에 대해서는 C++외에 다른 프로그래밍 언어에서도 거의 비슷한 기능들을 지원하며, 동시에 문자열 처리를 잘하는 사람이 보통 프로그래밍도 잘한다는 말도 있다. 또한 매번 필요할때 마다 손코딩을 하는 것보다는 미리 작성해놓고 보기 위함도 있다(근데 막상 보면 간단하다).


소스코드

// Utils.h
#pragma once

#include <string>

bool isHasBackword(const std::string str, const std::string backword);

// Utils.cpp
#include "Utils.h"

using namespace std;
bool isHasBackword(const string str, const string backword)
{
    string strBack(str.c_str() + (str.size() - backword.size()) );
    return strBack == backword;
}


 C 를 쓰다가 C++의 STL로 코드를 적고 보니 역시 C++이 C보다 편한 장치가 많다는 것을 다시 느껴진다.

반응형
반응형

C++ : 네임스페이스

정리하게 된 배경

 네임스페이스는 C와 C++의 표준함수의 가장 큰 차이점을 보이는 기능중 하나이다. 때문에 명확히 알고 활용을 해야 하기 때문에 정리한다.

 기초이지만, 중요한 개념이기도 하다. 또한, 학교나 학원 그리고 혼자 공부하는 사람입장에서는 예제에서 많이 적용하기 않기 때문에 의외로 활용을 못하는 초보 프로그래머를 많이 볼 수 있다.


개념

 프로그램이 커지고 복잡해지면서, 작명의 한계(?)로 인해서 발생되는 문제를 해결하기 위한 개념으로 등장을 했다. 이후 자바스크립트(JavaScript)나 파이썬(Python) 같은 스크립트계열 언어에서는 모듈이라는 이름으로 발전한다.

 C++에서는 네임스페이스(namespace)를 통해서 같은 이름의 클래스(class)명이나 함수(function)명을 선언 및 정의가 가능해졌다. 때문에 이로 인해 프로그래머들은 작명의 스트레스가 줄게 되었다.


사용방법

 네임스페이스는 클래스를 선언하는 방식과 비슷하게 namespace 키워드 바로 뒤에 선언하고자 하는 네임스페이스 명을 붙여서 선언을 하고 나서 중괄호 안에서 선언 및 정의를 하면 된다.

// A.h
namespace hg
{
    class A
    {
        // ...
        void func();
    }
}

네임스페이스의 내부에 선언 및 정의된 것들(함수, 변수, 클래스 등)을 호출하여 사용할 경우에는 앞에서 선언한 네임스페이스 이름 뒤에 "::" 붙여서 선언할 수 있다.


// A.cpp
// 클래스의 함수정의
#include "A.h"

void hg::A::func()
{
    // ...
}
// main.cpp
// 클래스의 함수호출
#include "A.h"

int main(int argc, char* argv[])
{
    hg::A a;
    a.func();
    return 0;
}

 사용할때 마다 네임스페이스 이름을 매번 적는 것은 상당한 노동과 타이핑양이 많기 때문에 기본적으로 네임스페이스 이름을 사용중인 상태를 나타내는 using 키워드를 사용하면 된다.


// A.cpp
// 클래스의 함수정의
#include "A.h"
using namespace hg;

void A::func()
{
    // ...
}
// main.cpp
// 클래스의 함수호출
#include "A.h"
using namespace hg;

int main(int argc, char* argv[])
{
    A a;
    a.func();
    return 0;
}

네임스페이스의 내부에 선언 및 정의된 것들(함수, 변수, 클래스 등)을 호출하여 사용할 경우에는 앞에서 선언한 네임스페이스 이름 뒤에 "::" 붙여서 선언할 수 있다.

 여기서 using namespace hg;의 유효범위는 해당 키워드가 사용된 파일내에서는 유효하다. 즉, 다른 cpp(혹은 cc) 파일에서는 다시 using 키워드를 사용해서 네임스페이스 사용중임을 알려야 한다.


주의 할점

 개념이 잡힌 사람에게는 당연한 말이 겠지만, using 키워드를 이용한 네임스페이스 선언을 할 경우 헤더 파일에서는 사용하지 않는 것이 정석이다. 따라서 네임스페이스는 정의는 보통 헤더 파일에서 된다. 그리고 using 키워드의 경우 헤더의 클래싀 정의 할 경우에 사용된다. 여러 네임스페이스에서 정의된 것들은 같이 써야 될 경우 가능하면, using은 사용하지 않는 것이 좋다.

 헤더파일에서 using을 쓰면 안되는 이유는 논리적으로 헤더파일은 cpp파일에서 include 될때마다 포함되는데, 이는 include 하는 cpp 마다 강제로 using 키워드를 사용한것처럼 되어버리기 때문에 사실상 네임스페이스가 없는 것처럼 되어 버린다.


추가사항

 헤더파일을 include 할 경우 C와 C++의 몇 가지 차이점이 있는데, C의 stdio.h의 경우 C++에서는 cstdio로 include하게 된다. 이 뿐만 아니라 기존의 C 표준 헤더 파일들 앞에 'c'를 붙어 있는 것을 알 수 있다.

 이 두 헤더 파일간의 차이는 바로 네임스페이스의 존재의 차이가 있다. C에서는 네임스페이스 키워드가 없지만, C++에서는 네임스페이스가 있어서 표준함수 네임스페이스인 std내에 표준함수들이 정의 되어 있다.(물론 C에는 네임스페이스가 없어도 있는 것처럼 사용할 수 있다.)

반응형
반응형

표준 레퍼런스

각종 스크립트형 프로그래밍 언어가 계속 나와도 굳건히 자리를 지키고 있는 프로그래밍 언어중 하나가 C/C++ 가 될 것이다(실질적으로는 C++)


 아쉽게도 한글은 번역이 안되어 있는 등 많은 부분이 부족하다. 심지어 C++14도 전부 업데이트가 안되어 있다.


반응형

+ Recent posts