함수포인터 활용

이론/C/C++ 2016. 10. 27. 01:36 |

함수 포인터에 대한 정의 이다.

일반 포인터가 변수에 대한 주소를 가지고, 변수를 가리킬 수 있는것 처럼 함수, 즉 실행가능한 코드를 가리키고 있는 포인터이다.


위키에서의 예시를 먼저 확인 해본다면

func1 은 하나의 더블형 매개변수를 가지며, 다른 더블형을 반환한다.
(기능은 센티미터를 인치로 변환하게 된다)
func2 는 정수형, 상수 문자 배열에 대한 포인터를 매개변수로 가진다. 그리고 문자에 대한 포인터를 반환한다.
(기능은 문자배열에서 주어진 문자의 첫번째 발생에 대한 포인터를 반환하는 문자열 라이브러리 함수의 역할이다.)

함수 포인터로 선언 하는 방법은 :  함수의 리턴형  (*함수포인터명)(매개변수); 이런 식으로 된다
선언된 함수 포인터에 수포인터명 = 원하는 함수 방식으로 사용할 수 있게 되는 것이다.

이제 이 함수포인터 들을 조금 더 꼬아서 작성 해보자.


함수포인터가 익숙하지 않는 상태에선 이해하기 힘든 코드로 보인다. 그러니 하나씩 뜯어보자.

(실제로 이렇게 쓰는 경우도 있다고 어디서 듣긴했다...)


먼저 함수 선언부를 보자면

int func1(int a);

가장 기본적인, 처음에 배우는 정수형을 리턴하는 함수이다.


int func2(int (*p)(int),int a);

이전의 위키의 예시와 같이 생각하면 된다. 매개변수로 함수 포인터를 받는, 가장 기본적인 응용이라 생각된다.

함수의 내용에서 받은 함수를 호출하여 리턴값을 다시 리턴하는 방법을 활용하였다.


int (*func3(void))(int);

이번엔 리턴값이 함수포인터인 경우이다. 

위의 정의식을 그대로 첫번째 int 값에 넣어버리고 싶지만, 컴파일러가 그렇게 읽을 수는 없나보다.

따라서 해당 함수명의 앞에 리턴값이 포인터임을 알리는 *을 붙이고, 괄호로 해당 함수의 마지막까지 감싼다.(괄호를 하지 않으면 int*를 리턴값으로 인식할것이다)

마지막에 리턴하는 함수포인터의 매개변수 형식을 붙여주면 된다.

(위의 식에서 초록 글이 함수명이고, 노란글이 리턴형식이다.)


그냥 보기엔 어려워 보이지만, 몇번 보니까 조금은? 익숙해지는 거 같기도 하다..


다음은 메인에서의 호출 내용을 확인 해보자


int(*(*p)(void))(int) = func3;

p 라는 함수 포인터 변수를 선언하는 부분이다. 

원하는 함수는 리턴형이 리턴값을 int형으로 가지며 매개변수를 int형을 갖는 함수포인터 이고, 

자신의 매개변수는 void인 함수이다.


이후 호출 내용은 직접 확인 해볼 수 있도록 printf의 순서를 확인하자.



그래도 헷갈리는거 같다... ㅠㅠ


'이론 > C/C++' 카테고리의 다른 글

간단한 함수 포인터 예제  (0) 2015.06.16
C/C++ 시간 정보 얻기  (0) 2015.03.08
C++ 문자열 너비포함 출력  (0) 2015.03.08
C++에서 2차원 배열 동적할당, 반납  (0) 2015.01.10
Posted by *me
:

함수 포인터는 특정 함수에 대한 메모리 주소를 담을 수 있는 것이라고 한다.


함수 포인터를 쓰는 이유는

1. 프로그램 코드가 간결해진다.

2. 함수포인터를 배열을 이용하여 중복되는 코드를 줄일수 있다.

3. 상황에 따라 해당되는 함수를 호출 가능(ex: 계산기...)

그 외에도 콜백함수를 함수포인터로 구현할 수 있다.


int (*FuncPtr) (int,int); //함수포인터의 정의

반환형이 int형이고 인자로 int형 변수 2개를 가지는 함수를 담을 수 있는 함수 포인터이다.

(ex: int add(int x, int y) 같은 함수)


사용시에는 FuncPtr = add 혹은 FuncPtr = &add 라고 사용 하면됨.


typedef 활용가능,

typedef int (*funcPtr)(int ,int )


(ex: FuncPtr testFP = NULL;

testFP = add; )


//내가 해본 함수포인터 예제


// 다른 블로그에서 가져온 예제


출처: http://norus.tistory.com/8 - 노루의 씨분투 세상



'이론 > C/C++' 카테고리의 다른 글

함수포인터 활용  (0) 2016.10.27
C/C++ 시간 정보 얻기  (0) 2015.03.08
C++ 문자열 너비포함 출력  (0) 2015.03.08
C++에서 2차원 배열 동적할당, 반납  (0) 2015.01.10
Posted by *me
:

안드로이드 가상머신

달빅(Dalvik) 댄 본스타인이 만듬

- 레지스터 머신 형태의 가상 머신이다.

- 안드로이드 4.4.4 이하 버전에 탑재, 이후 버전부터는 ART 사용

- 적은 메모리 요구 사양에 최적화됨, 밑에 깔린 프로세스 아이솔레이션, 메모리관리, 스레딩 지원 등 운영체제의 지원에 의존하나, 여러개의 VM 인스턴스가 동시에 돌아갈 수 있다. (사실 항상 돌아감)

- 달빅 가상머신과 자바 가상머신은 다르다.

- 달빅 가상 머신은 자바 바이트코드를 사용하지 않기 때문에 자바 가상 머신과는 전혀 다르다. 

 대신 안드로이드 SDK에 함께 들어 있는 dx 라는 이름이 붙은 도구를 이용하면 자바 클래스 파일을 .dex 포맷으로 바꿀 수 있다.


가상머신

Virtual Machine, VM : 컴퓨팅 환경을 소프트웨어로 구현한것, 즉 컴퓨터를 에뮬레이션하는 소프트웨어. 가상 머신상에서 운영체제나 응용프로그램을설치/실행 가능

가상머신은 원래 실제 컴퓨터의 효율적이고 고립된 복제물로 정의함(현재는 실제 H/W와 직접적인 통신이 없는 가상 컴퓨터를 가리킴)

가상머신은 실제 컴퓨터와 어느정도의 통신과 사용을 기반으로 두가지로 나뉨

1. 시스템 가상머신 : 완전한 시스템 플랫폼을 제공,완전한 운영체제(OS)의 실행을 지원한다.

2. 프로세스 가상머신 : 하나의 단일 프로그램을 실행하기 위해 만들어져 있다. 단일 프로세스를 지원한다.

가상머신의 중요한 특징은 안에서 돌아가는 소프트웨어가 가상머신이 제공하는 환경과 자원에 제한을 받으며 가상세계를 벗어날 수 없다는 것이다.

시스템 가상머신

- 하드웨어 가상머신이라고도 하며 각 운영체제를 실행하는 가상머신 사이 기초가 되는 물리컴퓨터를 다중화 한다. 가상화를 제공하는 소프트웨어 계층은 가상 머신 모니터 or 하이퍼 바이저 라고 한다. 하이퍼 바이저는 순 그대로의 하드웨어 또는 호스트 운영체제 위에서 실행할 수 있다.

주요 이점: 여러 운영체제를 쓰는 환경은 운영체제가 완벽히 고립된 채로 같은 컴퓨터에서 존재가능.

가상 머신은 실제의 컴퓨터가 제공하는 것과 다른 형태의 명령어 집학 구조(ISA)를 제공한다.

각각의 운영체제를 실행하는 여러개의 가상 머신들을 게스트 운영체제라고 하며, 다른 장치가 충돌을 피하기 위해 각 장치에서 실행하기 위한 서버통합(server conslidation)에 쓰이며, 각 가상 머신에서는 같은 물리 컴퓨터에서 실행된다.

원래 취지는 여러개의 운영체제를 사용한다는 것이었다. 여러개의 단일 운영체제들 사이에서 시분할 단일 컴퓨터를 허용한다.

게스트 운영체제는 모두 달라도 상관없다. 다시 말해 같은 컴퓨터에서 다른 운영체제를 돌릴 수 있게 해준다. 다른 게스트 운영체제를 지원하기 위해 가상머신을 사용하는 것은 임베디드 시스템에서 자주 사용된다. 일반적으로 리눅스와 윈도 같은 높은 수준의 운영체제로써 실시간 운영체제를 지원한다.

다른 사용으로는 신뢰할 수 없는 운영제제를 sandbox하는 것이다. 왜냐하면 그 시스템이 개발 하의 시스템일 수도 있기 때문이다. 가상 머신들은 더 나은 오류 수정의 접근과 더 빠른 다시 시동과 더불어 운영체제 개발에 다른 이점들을 가져다준다.

 

프로세스 가상머신

VM은 응용프로그램 가상머신이라고도 하며, 운영 체제 안에서 일반 응용 프로그램들을 돌리고 단일 프로세스를 지원한다. 프로세스가 시작하고 '끝내기'되어 파괴될 때 만들어진다. 

목적은 플랫폼 - 아무 플랫폼에서나 같은 방식으로 실행하는 프로그램을 허용하고 기초가 되는 하드웨어나 운영체제의 상세한 부분을 가져오는 독립 프로그래밍 환경을 제공하기 위함이다.

가상 머신이라고 하는 프로세스는 고급 프로그래밍 언어에서 높은 수준의 추출을 제공한다. - 가상 머신 프로세스 들은 해석기를 사용하여 추가된다.

(이러한 종류의 가상 머신은 자바 가상머신을 사용하여 추가되는 자바와 더불어 인기를 끌었다. 또다른 예는 닷넷 프레임워크가 있다. 공통 언어 런타임이라고 불리는 가상 머신을 실행한다.)


에뮬레이션(에뮬레이터)

- 한 시스템에서 다른 시스템을 복제, 두번째 시스템이 첫번째 시스템을 따라 행동하는것, 시뮬레이션과 반대.

에뮬레이터는 다른 프로그램이나 장치를 모방하는 "컴퓨터 프로그램 또는 전자기기의 능력"을 뜻한다. 예를 들어, 많은 프린터들은 HP 레어저젯 프린터를 따라하려고 한다. 왜냐하면 꽤나 많은 소프트웨어가 HP 프린터에 맞춰 만들어져 있기 때문이다. HP 프린터를 따라함으로써, 프린터는 진짜 HP 프린터에 맞춰진 소프트웨어에서 돌아갈 수 있다. 

에뮬레이션은 소프트웨어를 한 장치가 정말로 다른 장치라고 믿도록 "속이는 것이다".


컴퓨팅 플랫폼

- 소프트웨어가 구동 가능한 하드웨어 아키텍처나 소프트웨어 프레임 워크(응용프로그램 프레임 워크를 포함)의 종류를 설명하는 단어. 일반적으로 컴퓨터의 아키텍처, 운영체제, 프로그램언어, 관련 런타임 라이브러리, GUI를 포함함

플랫폼은 소프트웨어 응용 프로그램들을 돌리는데 쓰이는 하드웨어와 소프트웨어의 결합.

응용 프로그램 소프트웨어는 특정한 플랫폼 - 하드웨어나 운영체제 아니면 기기의 기능들에 맞추기 위해 프로그래밍 된다. 자바 플랫폼은 가상 기기 플랫폼으로 여러가지의 운영체제와 하드웨어에서 실행되며 소프트웨어가 만들어지는 일반적인 플랫폼의 한 종류이다.

플랫폼을 간략히 정의해보면 S/W를 실행할 수 있는 기반이다. 또한 플랫폼은 이를 이용하는 소프트웨어 개발자에게는 다른 어떤 플랫폼 위에서 자신의 로직 코드가 돌아가건 동일하게 작동 할 수 있도록 약속하는 하나의 계약 이다. 로직 코드란 바이트코드,소스코드, 기계코드도 될 수 있다. 이를 통해 프로그램의 실행이 특정 운영체제에 제약되지 않을 수 있다.

이는 언어는 독립적으로 기계들을 쉽게 교체 할 수 있게 한다.



ART(Android RunTime)

- 구글에서 달빅 VM의 한계를 해결하기 위해 개발한 런타임

- 배경: 안드로이드는 java를 사용하기에 VM이 필수이다. JVM이 라이센스문제가 있어 달빅가상머신을 개발하여 안드로이드에서 사용해왔다. 

달빅 VM 은 안드로이드 2.2(프로요) 부터 JIT 컴파일러가 추가되었는데, 이로써 성능이 향상되었다. 하지만 JIT컴파일러가 돌아가는데 하드웨어 전체적으로 부하가 생겨 배터리가 많이 소모 되었다. 화면 전환이 증가할 수록 배터리 소모도 증가하였다. 게다가 달빅은 프로그램 실행직전에 실행 부분 전체를 RAM에다가 올려놔야 하기 때문에 다른 OS보다 램을 많이 소모 하는 단점도 있었다.

이를 해결하기 위해 만든것이 ART이다 (실생활에서 비교하자면 한국인->(한국어)->영어->(일본어)->일본인 이러한 구조가 가상머신 이라면, 지금까지 달빅머신에서는 한국인->(한국어)->영어->(한국어)->한국인 과 같은 비효율적인 구조였다. 이를 한국인->한국어->한국인 으로 구조를 변경한 것이 ART인 것이다.)

- 성능개선 : 안드로이드 4.4 이상 기기에서 런타임을 ART로 설정해놓으면, 앱이 설치 될 때 앱에 들어 있는 중간 언어를 모두 번역해놓는다. 그 덕에 기존의 JAVA기반 앱 플랫폼으로써의 문제점들은 모두 사라지고, native 언어와 동급의 성능을 체감하게 된다.

- 단점: 앱 설치시 1.5배에서 2배 가량 용량을 더 차지하고 설치속도가 느리다. 대부분의 앱이 달빅에 초점을 맞춰 개발을 하기때문에 호환성 문제도 있다. 

- 달빅과의 비교: ART이전에도 코드 보안이나 성능 보장이 매우 중요한 앱 개발은 NDK를 이용한 C/C++ 프로그래밍으로 개발했다.(상용앱에서도 네이티브 코드가 많이 있다) 최적화가 될만큼 되어있는 이러한 앱에서는 유의미한 성능 개선이 없을 가능성이있다.

- 기타: 안드로이드 5.0(롤리팝) 이상 부터는 달빅을 완전히 폐지하고 ART를 런타임으로 완전히 대체 하였다.

ART는 가상머신이 아니고 단지 네이티브로 번역된 안드로이드 앱을 동작 시키기 위한 런타임 라이브러리이다.


JIT컴파일

- Just-in-time compilation, 동적 번역(dynamic translation)은 프로그램을 실제 실행하는 시점에 기계어로 번역하는 컴파일 기법이다. 이 기법은 프로그램의 실행 속도롤 빠르게 하기 위해 사용된다.

컴퓨터 프로그램을 만드는 방법은 두가지가 있는데, 인터프리트 방식과 정적 컴파일 방식으로 나뉠수 있다. 

인터프리트 방식은 실행중 프로그래밍 언어를 읽어가며 해당 기능에 대응하는 기계어 코드를 실행

정적 컴파일은 실행하기전에 프로그램 코드를 기계어로 번역한다.

JIT 컴파일러는 두가지를 혼합한 방식으로 실행 시점에서 기계어 코드를 생성하면서 그 코드를 캐싱하여, 같은 함수가 여러번 불릴 때 매번 기계어 코드를 생성하는 것을 방지한다.

자바 가상머신과 .net에서는 JIT 컴파일을 지원한다. (즉, 자바컴파일러가 자바 프로그램 코드를 바이트 코드로 변환한 다음, 실제 바이트 코드를 실행하는 시점에서 가상 머신이 바이트 코드를 기계어로 변환한다.)


-----------------------------------------------------------------------------------------------------------------

요약한다면...,

구글은 안드로이드를 개발하면서 JAVA를 사용했는데, JAVA는 JVM이 있어야 동작가능하다. 하지만 JVM은 라이센스 문제가 있어 그대로 사용하지 못하였다. 그래서 만들어서 탑제한 것이 Dalvik 가상머신이다. Dalvik가상머신은 App 실행시 자바코드를 JIT컴파일을 통해 번역하고 기계어로 변환하여 실행한다. 하지만 이러한 방법이 배터리 소모와 프로그램 실행속도에 영향을 많이 미치기 때문에, 달빅의 중간 과정을 줄인것이 ART이다. ART는 안드로이드 런타임으로써 App설치시에 미리 컴파일을 해놓고 실행시 중간 과정없이 실행 가능하다. 

결국 이런 내용인데,, 중간중간 모르는 용어가 많아서 주저리주저리 타이핑 해보았다..

출처: 위키백과, 엔하위키 미러

'이론 > Java/Android' 카테고리의 다른 글

액티비티 생명 주기 Test  (3) 2015.01.29
Posted by *me
:
현재 날짜나 시간등이 필요한 경우가 많은데, 
time.h를 이용하면 현재 DATE정보를 받아올 수 있다.


간단한 소스를 검색해서 구현해보았지만, 대부분 그렇지만 시간에 관한 구조체나 함수에 대해 자세히는 이해가 되질 않는다. 그냥 일단 이렇게 쓰는걸로...ㅜㅜ ctime어쩌고.. 있던데.. 어려움..

'이론 > C/C++' 카테고리의 다른 글

함수포인터 활용  (0) 2016.10.27
간단한 함수 포인터 예제  (0) 2015.06.16
C++ 문자열 너비포함 출력  (0) 2015.03.08
C++에서 2차원 배열 동적할당, 반납  (0) 2015.01.10
Posted by *me
:

C++ 에서도 (C언어의 %5d였나?) 문자열 출력시 너비를 포함하여 출력할 수 있다.

즉,  "   a","abc"이거처럼 열을 맞춰서 출력한다고 해야할까..


ios에서 cout.width()를 이용하여 가능한데,

cout.width(폭의 크기), cout.file('문자') 로 사용한다.

예제를 작성해 보았다.




결과창:


'이론 > C/C++' 카테고리의 다른 글

함수포인터 활용  (0) 2016.10.27
간단한 함수 포인터 예제  (0) 2015.06.16
C/C++ 시간 정보 얻기  (0) 2015.03.08
C++에서 2차원 배열 동적할당, 반납  (0) 2015.01.10
Posted by *me
:

액티비티 생명주기에서 메인 액티비티에서 다른 액티비티가 호출되면 어떤 구조로 정지하고 실행되는지 로그를 찍어 보았다.

그 결과는


어플리케이션 실행

OnCreate - M (MainActivity)

onStart - M

onResume - M

MainActivity  동작

(버튼 선택으로 SecondActivity실행)

onPause - M

onCreate - S(SecondActivity)

onStart - S

onResume - S

onStop - M

SecondActivity 동작

백버튼으로 SecondActivity종료

onPause - S

onRestart - M

onStart - M

onResume - M

onStop - S

onDestroy - S

MainActivity 동작

백버튼으로 MainActivity 종료

onPause - M

onStop - M

onDestroy - M

메인 에서 서브 액티비티를 호출하면 메인 액티비티는 바로 pause되고 그동안 서브 액티비티가 생성된다. 다 생성된다면 메인액티비티는 Stop된다.

서브 액티비티를 종료할때는 종료시작 순간 서브액티비티는 pause되고 메인은 Restart부터 start - resume으로 다시 호출된다. 메인이 준비가 끝나면 서브액티비티는 stop - destroy과정을 통해 소멸된다.

즉, 액티비티간에 전환시 전환될 액티비티가 준비되어야 완전히 정지하고, 소멸된다는 것을 알 수 있다. 

사용한 소스코드 (다이얼 로그를 띄웠을때의 차이를 알아보려고 다이얼로그를 넣어봤지만 해당 액티비티는 계속 동작되는 상태인것 같다.)



'이론 > Java/Android' 카테고리의 다른 글

안드로이드 가상머신 동작 구조  (0) 2015.04.26
Posted by *me
:

미로찾기 알고리즘을 풀다가 만든 것입니다.


'이론 > C/C++' 카테고리의 다른 글

함수포인터 활용  (0) 2016.10.27
간단한 함수 포인터 예제  (0) 2015.06.16
C/C++ 시간 정보 얻기  (0) 2015.03.08
C++ 문자열 너비포함 출력  (0) 2015.03.08
Posted by *me
: