1. 메모리 구조


메모리는 크게 4개의 영역으로 나뉜다. 코드 영역, 스택 영역, 힙영역, 데이터 영역 이다.


1) 코드 영역 : 실행 명령어 저장

- 소스코드가 저장되는 영역으로, 실행할 명령어들이 순서대로 쌓인다.

- cpu가 이 영역에서 명령어들을 하나씩 가져다가 처리한다. (큐 구조)



2) 스택 영역 : 개발자가 제일 많이 사용하는 메모리는 스택 메모리 영역이다.  

- 스택이란 모든 원소들의 삽입 삭제를 한쪽 방향에서만 수행하도록 하는 선형 자료 구조이다.

- 이를 후입선출방식 (Last In First Out)이라 한다.

- 스택메모리는 지역변수와 매개변수같은 값들이 저장되는 공간이다.



void Test(int a)
{
    char b = 'A';
    int c = 1;
    double d = 3.14;
}

먼저 메모리에 int a 4바이트가 할당되고, char b 1byte, int c 4byte, double d 8 byte가 순서대로 할당되며 함수가 종료될때에는 거꾸로 메모리에서 제거된다. (d, c, b, a)



3) 힙 영역 : 개발자가 직접 할당

- 힙은 컴퓨터 메모리의 일부가 할당되었다가 회수되는 일들의 반복을 의미

- 합은 컴파일시가 아닌 실행 시 사용자로부터 할당 메모리를 입력 받음

- 생성과 삭제를 개발자가 직접 해줘야하는데, 삭제를 해주지 않으면 메모리 누수현상(메모리 릭)이 생긴다. 



4) 데이터 영역 : 전역 변수, 스태틱수 저장

- 전역 변수와 static변수가 저장되는 메모리이다.

- 프로그램 시작시 모든 전역변수와 static 변수가 데이터 영역에 저장되며, 프로그램이 종료시 메모리에서 소멸된다.






2. 동적 메모리 할당

1) 동적으로 메모리를 할당 하는 이유


일반적으로 변수는 컴파일타임에 할당된다. 

그렇다면 다음의 상황에서는 어떻게 될까?


Q. 전교생이 10명인 학교의 학생 수를 배열로 선언한다면?

A. int student[10];


Q. 학생수가 100명으로 늘어나게 되면?

A. int stduent[100];


학생수가 계속 유동적으로 변하게 된다면?

개발자가 그 상황에 맞게 계속 변수를 할당해줄 수 없다. 학생 수를 고정하지 말고 실행시 결정하자는 개념


int num;
fputs("학생수를 입력하세요 : ",stdout);
scanf("%d", &num);
int student[num];
문제점 
 - scanf는 런타임에 실행되지만 사용자가 값을 입력하는건 런타임이다. 
 - int student[num]은 컴파일타임에 실행된다. 런타임에 입력 받은 변수를 컴파일 타임에 대입하는 형태가 되기 때문에 컴파일 에러가 생긴다. 

 해결 방법

 - 실행 중에 학생 수를 알아야 하는 경우, 동적 메모리 할당 기법을 통해 문제 해결이 가능하다.





2) 메모리 할당 및 해제


malloc()

- 동적 메모리 할당 함수의 원형


void* malloc(size_t size);


- malloc 또는 말록이라고도 읽는다.

- 전달인자size는 바이트 단위로 입력한다.

- 메모리 할당이 되면 메모리의 주소값을 리턴한다.

- 메모리 부족 시 null 포인터 리턴한다.

- 리턴형이 void*인데, 타입이 지정되어 있지 않는 포인터를 리턴 한다.



free()

- 동적 메모리 해제 함수의 원형


void free(void* memblock);


- 메모리 사용후 반드시 해제 해야한다. (메모리 누수현상(메모리 릭)이 발생한다.)

- 전달인자로 메모리를 가리키는 포인터를 대입한다.



#include 
#include 

int main(void)
{
    int num;
    int* student);

    fputs("학생 수 입력 : ",stdout);
    scanf("%d", &num);
    student = (int*)malloc(sizeof((int)*num);

    if(student == null)
    {
        printf("메모리가 부족하가 부족하여 메모리를 할당 할 수 없습니다.\n");
        return 0;
    }

    printf("학당된 메모리의 크기는 %d 입니다. \n", sizeof((int)*num);
    free(student);

    return 0;
}



realloc()

- 실시간 메모리를 할당하여 사용한다 해도 사용중에 메모리 크기를 더 늘려야 하는 경우가 발생할 수 있다.

- malloc 함수로 할당된 메모리를 다시 동적으로 재할당해주는 함수가 realloc이다.




#include 
#include 

int main(void)
{
	int i;
	int *arr = (int*)malloc(sizeof(int) * 5);
	int *rearr; 

	for (i = 0; i < 5; i++)
	{
		arr[i] = i + 1;
	}
	rearr = (int*)realloc(arr, sizeof(int) * 10);
	for (i = 0; i < 10; i++)
	{
		rearr[i] = i + 1;
	}
	for (i = 0; i < 10; i++)
	{
		printf("%d\n", rearr[i]);
	}

	free(rearr);
	return 0;
}


calloc()

- malooc 함수와 똑같은 기능을 갖는다

- 전달인자의 형태와 조금 다른데, 메모리 개수와 자료형의 크기를 대입한다.


int* a = (int*)calloc(elt_count, elt_size);

int* a = (int*)malloc(size * sizeof(int));


#include <stdio.h>
#include <stdlib.h>

int main(void)
{
	int num, i, total = 0;
	int* student;

	fputs("학생 수 입력 : ", stdout);
	scanf("%d", &num);
	student = (int*)calloc(num, sizeof(int));

	if (student == NULL)
	{
		printf("메모리가 부족하가 부족하여 메모리를 할당할 수 없습니다.\n");
		return 0;
	}

	for (i = 0; i < num; i++)
	{
		printf("%d번째 학생의 성적 입력 : ", i + 1);
		scanf("%d", &student[i]);
	}
	for (i = 0; i < num; i++)
	{
		total += student[i];
	}
	printf("총점 : %d 평균 : %d \n", total, total / num);
	free(student);
	return 0;
}



memset()

- 메모리 블록에서 모든 바이트를 특정 값으로 설정 할 때 사용하는 초기화 함수


void* memset(void* dest, int c, size_t count)


#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

int main(void)
{
	int* arr= (int*)malloc(sizeof(int) * 10);
	int i;
	
	printf("=========초기화 하기 전========= ");
	for (i = 0; i < 10; i++)
	{
		printf("%d\n", arr[i]);
	}
	memset(arr, 0, sizeof(int) * 10);
	printf("=========초기화 하기 후-======== ");
	for (i = 0; i < 10; i++)
	{
		printf("%d\n", arr[i]);
	}
	free(arr);
	return 0;
}


>



memcpy()

- 메모리를 복사하는 함수


void* memcpy(void* dest, void* src, size_t count);


#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

int main(void)
{
	int* arr1 = (int*)malloc(sizeof(int) * 5);
	int arr2[5];
	int i;
	
	for (i = 0; i < 5; i++)
	{
		arr1[i] = i + 1;
	}
	memcpy(arr2, arr1, sizeof(int) * 5);
	for (i = 0; i < 5; i++)
	{
		printf("%d\n", arr2[i]);
	}
	free(arr1);
	return 0;
}


memcmp()

- 메모리를 비교하는 함수


void* memcmp(const void* ptr1, const void* ptr2, size_t num);


#include <stdio.h>
#include <string.h>

int main(void)
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[10] = { 1,2,3,4,5 };
	
	if (memcmp(arr1, arr2, sizeof(int) * 5) == 0)
	{
		printf("arr 1 == arr2");
	}
	else
	{
		printf("arr 1 != arr2");
	}
	return 0;
}


Posted by 루우지

[C언어] 열거형 enum

C 2018.08.24 19:56

열거형이란?

- 열거형은 enumeration의 약자로 enum(이넘)이라고 읽는다.

- 데이터들을 열거한 집합이다. 

- 컴파일러는 열거형 멤버들을 정수형 상수로 취급한다.




열거형의 사용법

- 키워드는 enum을 사용하여 정의한다.   

#include 

enum Week
{
	sun = 0,
	mon,
	tue,
	wed,
	thu,
	fri,
	sat
};

int main(void)
{
	int day;
	printf("요일을 입력하세요(1.일, 2.월, 3.화, 4.수, 5.목, 6.금, 7.토) : ");
	scanf("%d", &day);

	switch (day)
	{
	case sun:
		printf("sunday");
	case mon:
		printf("monday");
	case tue:
		printf("tueday");
	case wed:
		printf("weday");
	case thu:
		printf("thuday");
	case fri:
		printf("friday");
	case sat:
		printf("atday");
	default:
		printf("err");
	}
	return 0;
}


- 열거형의 멤버들은 각 요일을 나타낸다.

- 첫번째 멤버 sun을 0으로 설정하면 다음 멤버 mon은 각 1씩 증가한다.

Posted by 루우지

1. 구조체란?

- 하나 이상의 서로 다른 종류의 변수들을 묶어서 새로운 자료형을 정의하는 것이다.



구조체를 사용하는 이유

- 연관된 변수들을 하나로 묶어서 관리함으로써 데이터 관리에 유용하다.

- 데이터의 양이 많아지면 궂체가 유리하다.

- 예를 들어 학생정보 관리 변수를 생성할때 이름, 나이, 성별 등의 정보들은 모두 변수로 선언하여 각각의 변수를 별도로 관리하면 연관성을 알 수가 없다. 



구조체 정의 방법

#include 
struct student
{
	char name[10];
	int age;
	int height;
};	// 구조체 정의

int main(void)
{
	struct student st1;	// 구조체 선언
	struct student st2;
}


- struct 키워드는 구조체라는 자료형을 의미

- student 는 만든 구조체의 이름

- name, age, height는 구조체 멤버 변수

- 구조체는 사용자가 정의한 새로운 자로형이다.



구조체 멤버 접근 방법

- 구조체 변수를 통해 구조체 멤버의 값을 참조해야 한다.

- 멤버에 접근시 . 콤마를 사용하는데, 이를 직접 접근이라 한다.


[구조체 변수명].[구조체 멤버]

ex) st1.name, st1.age, st1.height




2. 공용체란?

- 공용체도 사용자가 정의한 자료형이다

- 구조체와의 차이점은 메모리 공간을 공유한다는 점이다.


struct stTemp
{
	char a;
	int b;
	double c;
}st;


위와 같은 구조체가 있을때 메모리가 차지하는 용량은

a = 1byte, b = 4byte, c = 8byte 로 총 13byte가 메모리에 적재된다.

union unTemp
{
	char a;
	int b;
	double c;
}un;


위의 공용체와 같은 경우는 구조체와는 전혀 다른 메모리 적재방식이 적용된다.

제일 큰 멤버변수 double형 c가 8byte가 메모리에 적재되어 각각의 변수가 1회용으로 8byte 메모리안에 적재된다.

구조체는 멤버변수가 각각의 메모리 공간을 할당받고 있지만 공용체는 같은 메모리공간을 모든 변수가 공유하는 형태이다.


#include 

union unTemp
{
	char a;
	int b;
	double c;
}un;

int main(void)
{
	printf("문자형 a의 주소와 크기 : %x, %d\n", &un.a, sizeof(un.a));
	printf("정수형 b의 주소와 크기 : %x, %d\n", &un.a, sizeof(un.b));
	printf("실수형 c의 주소와 크기 : %x, %d\n", &un.a, sizeof(un.c));

	un.a = 'A';
	printf("문자형 a의 값 : %c\n", un.a);
	un.b = 100;
	printf("정수형 b의 값 : %d\n", un.b);
	un.c = 3.14;
	printf("실수형 c의 값 : %.2f\n", un.c);
	printf("문자형 a의 값 : %c\n", un.a);
	return 0;
}



- 시작 주소는 세 변수가 모두 같다.

- 예제의 마지막줄 a값을 다시 출력 시 쓰레기값이 출력된다. 

- 그 이유는 double형 8byte에 저장된 값은 3.14인데 그중 1byte의 값만 읽어와 출력하는것이니 쓰레기값이 출력된다.


공용체를 사용하는 이유

- 메모리 절약을 위해서

- 구조체는 각 가정의 화정실, 공용체는 공원의 공중 화장실이라 생각하면 된다. 


공용체 사용 시 유의 사항

- 공용체 멤버는 동시에 사용하게 되면 데이터가 별질될 우려가 있으므로 따로 따로 사용해야한다.




Posted by 루우지


void CAVI_PROJECTDlg::OnBnClickedBtnFind()
{ 
	BROWSEINFO BrInfo;
	TCHAR szBuffer[512];                                      // 경로저장 버퍼 

	::ZeroMemory(&BrInfo,sizeof(BROWSEINFO));
	::ZeroMemory(szBuffer, 512); 

	BrInfo.hwndOwner = GetSafeHwnd(); 
	BrInfo.lpszTitle = _T("파일이 저장될 폴더를 선택하세요");
	BrInfo.ulFlags = BIF_NEWDIALOGSTYLE | BIF_EDITBOX | BIF_RETURNONLYFSDIRS;
	LPITEMIDLIST pItemIdList = ::SHBrowseForFolder(&BrInfo);
	::SHGetPathFromIDList(pItemIdList, szBuffer);				// 파일경로 읽어오기

	CString str;
	str.Format(_T("%s"),szBuffer);
	AfxMessageBox(str);
}


MFC 버튼컨트롤에 클릭이벤트를 건뒤 해당 함수에 위의 소스를 복붙해서 실행하시면 폴더 찾기 다이얼로그가 생성되는걸 확인 할 수있습니다. 





Posted by 루우지

1. OCI (Oracle Call Interface)

 - Application과 Oracle Database와 상호작용할 수 있도록 오라클에서 지원하는 Low-Level api이다. 일반적으로 C/C++에서 많이 사용된다. 그런데 OCI 프로그래밍은 Low-Level  API를 사용하는것이라 매우 어렵다. 다만 ODBC처럼 Oracle Client를 설치하지 않고 oci 관련된 dll을 같이 배포할때 포함해주면 되기 때문에 사용자가 oracle 을 설치하지 않아도 된다는 이점이 있다. 물론 단점은 위에서 언급했듯이 개발자가 사용하기 쉬운 API는 아니라른점.




2. OCCI (Oracle C++ Call Interface)

 - 약자와 같이 OCCI는 C++에서 오라클DB를 조작할 수 있게금 도와주는 API다. Low-Level로 작성된 OCI를 C++로 랩핑하여 API를 제공해주는데 공식 도큐먼트에서의 OCCI의 장점을 아래와 같이 설명하고 있다.




1) C++과 같은 객체지향 프로그래밍 활용

2) 사용하기 쉽다.

3) JDBC에 익숙한 사람들에게 배우기가 쉽다.









실제로 OCI와 OCCI의 사용 문법은 판이하게 다른다. JDBC에 익숙한 나에게는 OCCI에서 제공해주는 API가 더 친숙하고, 친절하다. 


하지만 OCCI는 단점이 있다..


VS2015에서 사용하면 버그가 생긴다. 

- 정확히는 OCCI가 VS2010 (V100) 까지의 라이브러리 파일을 제공해준다. (dll도 같이)하지만 나는 vs2015를 사용하는데 OCCI(oraocci11d.lib)를 사용할때 getString() 함수를 사용하는데 힙커런트 에러가 뜬다. 이는 내부적으로 2번 메모리를 delete해주는 현상이라고 한다. (정확히는 모름) 무려 저 에러때문에 하루를 다 날려먹었지만 결국 vs2010 으로 갈아타고 작업하는데 성공했다.


해당 에러를 잡으면서 많은 생각을 했다. OCCI를 버리고 OCI로 갈것이냐, ODBC방식으로 갈것이냐, 혹은 JVM을 위에올려서 JDBC로 갈것이냐 등,, 결국 VS2010으로 다운그레이드하여 OCCI를 끝까지 가져가보자라는 방식으로 마음 먹었다.


























Posted by 루우지


1. Hxd 에디터

https://mh-nexus.de/en/hxd/


위의 주소에서 Hxd에디터를 설치해주세요.





1. 다클을 하실려면 대항해시대 클라이언트가 설치된 폴더에서 GVOnline.bin 파일을 수정하셔야합니다.

기본 설치 경로는 C:\Netmarble\GV Online Kr 에 있습니다. bin파일 수정시 실패할경우를 대비해 미리 원본을 백업해두세요. (원본 파일을 복사해서 다른 폴더에 보관해주세요)







2. 설치한 HxD 에디터를 실행하여 수정할 GVOnline.bin 파일을 불러와주세요.

파일 -> 열기 -> 대항해시대 설치 경로에 있는 GVOnline.bin 파일 선택 후 열기 버튼 클릭

파일을 불러왔으면 아래의 스크린샷처럼 16진수 값들을 확인 할 수있습니다.







3. 수정할 16진수 값을 검색합니다.

Ctrl + F 키를 누르거나 찾기 -> 찾기 버튼을 클릭하면 아래와 같은 다이얼로그가 뜹니다. 

데이터 형식을 16진수 값으로  선택 후 검색 창에 3b 45 f0 7e 15 를 입력후 수락버튼을 눌러주세요.

아래의 스크린샷 처럼 해당 값을 찾을 수 있습니다.





(e0이 아니라 f0입니다. 실수..)







4. 이제 bin파일을 수정하겠습니다.

3b 45 f0 7e 15 값을 3b 45 e0 7e 15으로 수정 해주세요. (20클까지 되는거 같습니다)








5. 이제 저장하시면 bin파일 수정 작업은 끝납니다.

해당 bin파일 코드는 업데이트마다 바뀔 수가 있습니다. 현재 2018/08/17일 까지는 위의 코드가 유효한 상태입니다.







이제 네트워크 드라이버 추가 작업을 해야하는데 간단하게 글로 설명을 하자하면 한 IP당 클라이언트는 2개밖에 접속을 못합니다. 그래서 야매로 IP를 속여 접속해야하는데요. 그러기 위해서는 가상의 네트워크 드라이버를 추가해야합니다.




1) 윈도우 검색에 장치관리자를 검색하셔서 실행하신 뒤, 네트워크 어뎁터를 클릭 후 상단의 동작 -> 레거시 하드웨어버튼을 클릭합니다.



2) 목록에서 직접 선택한 하드웨어 설치를 선택후 다음 버튼을 누른뒤 스크롤을 내려 네트워크 어뎁터를 클릭 후 다음 버튼을 눌러주세요.



3) 제조 업체에서 Microsoft 사를 클릭 후 Microsoft KM-TEXT 루프백 어댑터를 선택후 다음 버튼을 누르면 어뎁터 설치가 끝나게 됩니다.



4) 제어판\네트워크 및 인터넷\네트워크 연결 경로로 들어가면 추가된 어뎁터가 보입니다. 

우클릭 -> 속성 버튼을 클릭후 인터넷 프로토콜 버전 4(TCP/IPv4)를 눌러 IP속성값을 임의로 수정해주세요 ex) 11.142.132.251 



5) 저장 후 어뎁터를 사용하지 않음으로 채크 후 2클라이언트 이상 접속할경우에 해당 어뎁터를 켜주시면 3클 이상부터 접속이 가능합니다. 하지만 어뎁터도 2개의 클라이언트만 가능하오니 5클을 사용하실려면 접속하실 때마다 ip를 바꿔주시거나 미리 여분의 어뎁터를 설치 후 어뎁터를 끄고 키는 방식으로 비교적 쉽게 접속하실 수 있습니다. 




'취미 > 대항해시대 온라인' 카테고리의 다른 글

대항해시대 다클 가이드  (6) 2018.08.17
Posted by 루우지




무려,, 3회에 걸친 시험 끝에 정보처리기사를 합격했다. ㅋㅋㅋ

주변 친구들은 필기와 실기를 모두 한번에 붙었는데



내가 노력이 부족한건지,

머리가 나쁜건지

필기 2번 실기 3번만에 합격을 했다;;

뭐 취업준비한다고 신경 못쓴게 있긴하지만 서도 그래도 지금이라도 붙어서 다행인듯

사실 이번 회차가 정말 쉽게 나왔기 때문에 운이 좋았다.



전공자의 입장에서 정보처리기사를 공부한다고 하면

(학교생활 열심히해서 전공과목에대한 이해도가 있다면)


1. 코딩, 알고리즘 -> 쉬움

2. DB -> 보통

3. 업무프로세스 -> 어려움

4. 신기술 동향 -> 어려움

5. 전산영어 -> 어려움





코딩 알고리즘의 문제를 받고나면 어이가 없을정도의 난이도로 나온다.

대부분이 괄호안의 조건문을 채우는 정도의 문제가 나오기 때문에

(알고리즘도 비슷하게 반복문이나 조건문의 빈칸채우기)

전공자라면, 이 과목에대한 공부비중은 낮추는게 좋을것이다.




DB 과목은 생각보다 범위가 넓으면서도 여태 경험해본바 나올 법한 문제들이 계속 순환되서 나오는듯하다.

특히 SQL작성하는 부분은 매 시험마다 나온거 같으니 꼭 수기로 SQL을 작성할 줄 알아야한다. 

(그렇다고 뷰, 트리거, 인덱스와 같은 생성 SQL은 나오지 않은듯한다.)

시나공에서 A~B등급 챕터는 꼭 다 숙지하고 가길 바란다.




업무프로세스는 답이없다. 

생전 처음보는 용어들이 나오는데 이부분은 그냥 오랫동안 암기를 해야한다.

보통 시험문제지 맨 마지막 문항에 업무프로세스 문제가 나오는데 페이지가 거의 2~3페이지를 차지할정도로

지문이 엄청나게 길다.

하지만 막상 이거풀어보면 꽁으로 주는 문제이기 때문에 엄청난 지문에 지레 겁먹지말고 찬찬히 시간을 들여서

읽어보고 풀길 바란다. (시험시간이 엄청 나게 남습니다.)




신기술 동향은 정보처리기사 공부를 시작하면서 아예 따로 빼놓고 수시로 암기해야하는 과목이다. 노트나 A4에 정리해서 등하교길이나 똥쌀때 등등,, 항상 손에 놓지말고 영어단어 암기 하듯이 달달달 외워야한다.




전산영어는 문제집 기출문제를 잘 봐둬야한다. DB, 업무프로세스, 신기술동향과목에서 영어지문으로 나온다. 전산 영어는 생각보다 점수 비중이 크지 않기 때문에 그점 감안해서 시험준비를 하면 좋을것이다.

























Posted by 루우지

1. JDBC를 이한 DB 접근 3단계


1) 연결하기 -> Connection 생성


2) 질문하기 -> PreparedStatement 생성 후 executeQuery()하기


3) 답변받기 -> ResultSet 이용


개인적으로 생각하는 db 접근 방법이다. 



우선 JDBC를 이용한 DB접근을 하기위해서는 JDBC DRIVER가  필요하다. Oracle, MySQL, MsSQL 등 대부분의 디비에서 JDBC 드라이버를 제공해주기 때문에 알맞는 드라이버를 설치해서 Eclipse에 추가하도록 하자.



public class TestMain { public static void main(String[] args) { String serverURL = "jdbc:mysql://localhost:3306/sys"; // 주소:포트/db명 String id = "root"; // 계정명 String pw = "1234"; // 비밀번호 try { Class.forName("com.mysql.jdbc.Driver"); Connection con = DriverManager.getConnection(serverURL, id, pw); String sql = "insert into emp(empno, ename, age, deptno, mgr) values(1, '오라클', 22, 0423, 05)"; PreparedStatement pstmt = con.prepareStatement(sql); pstmt.executeUpdate(); } catch (ClassNotFoundException e) { System.out.println("드라이버가 존재하지 않습니다"); } catch (SQLException e) { e.printStackTrace(); } } }


위의 소스는 Mysql에 접속하기위한 커넥션 객체를 생성하고 Insert 문을 실행시키는 소스이다.  여기서 눈여겨 봐야할 부분은


커넥션 생성 부분, SQL 생성후 질의하는 부분 정도로 나눠볼수 있다.


Class.forName("com.mysql.jdbc.Driver");

임포트시킨 mysql connecter.jar 파일안에 있는 드라이버를클래스를 동적으로 생성후


Connection con = DriverManager.getConnection(serverURL, id, pw);


드라이버 매니저 객채를 통해 커넥션을 만든다. 이때 mysqlURL과, 계정, 비밀번호 정보를 파라메터로 넘겨준다.


String sql = "insert into emp(empno, ename, age, deptno, mgr) values(1, '오라클', 22, 0423, 05)";


그후 수행할 SQL문을 sql 변수에 입력 후


PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.executeUpdate();


PrepareStement 객체를 sql문을 넣어 객체를 생성한다.

pstmt.executeUpdate() 메소드를 실행시켜 sql문을 실행한다.




2. Statement


1) Statement 

 - Statement객체는 매개변수없는 간단한 SQL문을 질의할때 사용된다. SQL문을 실행하고 결과값을 받는데 필요한 기본적인 메소드를 제공한다.


2) PreparedStatement  (Statement 상속)

 - StatementStatement 객체는 IN 메개변수를 가지거나 가지지 않은 프리컴파일된 SQL문을 실행하는데 사용되고, IN 매개변수들을 다루기 위한 메소드들이 있다.


3) CallableStatement (PreparedStatement 상속)

 - 데이터베이스 저장 프로시저의 호출을 실행하는데 사용되며, out 매개변수들을 다루기 위한  메소드들이 있따.





3. 쿼리에 따른 실행 메소드


1) execute()

      : SQL문이 여러개의 ResultSet객체나 여러개의 갱신카운트 또는 ResultSet객체들과 갱신 카운트들의 결합을 리턴하는 것이 가능할때 사용한다.


2) executeQuery()

     - 하나의 ResultSet을 만드는 SQL문에서 사용(executeQyery 메소드는 ResultSet 객체를 리턴한다.)

     - 주로 SELECT문을 이용하는 조회에서 사용됨.


3) executeUpdate()

     -  INSERT, UPDATE, DELETE 등 (DML), CREATE, DROP 등(DDL)문들을 실행하는데 사용

 


실행문을 위한 모든 메소드들은 하나가 오픈되어있다면, 호출된 Statement 객체의 현재 ResultSet을 닫아야한다.

이것은 Statement 객체를 다시 실행기전에 현재 ResultSet 객체의 어떠한 처리도 완결해야 할 필요가 있다는 것을 의미한다.

Posted by 루우지




신과함께(인과 연) 

2018

3.5점



쿠키 있음. 영화 끝나고 배우 소개 화면과 엔딩크레딧 중간에 나옴



기대가 컷던걸까 전편보다 못한 후속작이였다. 

마동석을 이용한 코믹적인 요소가 보이긴 했는데 캐릭터들의 과거 회상씬으로 인해 

현재와 과거를 과하게 들락날락한다. 


전편 같은경우에는 사람을 울리기라도 했지 

이번편은 캐릭터의 과거를 풀기위한 내용 전개 때문인지 임팩트가 없었다.


그래도 생각치 못한 반전들이 공개되어 놀라긴했지!





'취미 > 영화' 카테고리의 다른 글

신과 함께(인과 연) 쿠키 정보  (0) 2018.08.13
어벤져스:인피니티 워 + 쿠키정보  (0) 2018.04.26
Posted by 루우지

1. JNI 변수 타입


JNI 변수 타입은 Java의 변수를 C++/C 에서 사용 할수 있게끔 호환해주는 변수 타입이다. 

jni.h를 인클루드하면 사용이 가능한데 자세한 정보는 아래의 표를 보면 알 수 있다.



JAVA 

C++/C 

C++/C 배열 

boolean

jboolean 

jbooleanArray 

byte

jbyte 

jbytArray

char 

jchar 

jcharArray 

short 

jshort 

jshortArray 

int 

jint 

jintArray 

long

jlong 

jlongArray 

float 

jfloat 

jfloatArray 

void 

jvoid 

jvoidArray 

Object 

jobject 

jobjectArray 

String 

jstring 

jstringArray 


java의 기본 변수형은 c++/c언어에서는 j가 붙은 클래스로 제공된다. int -> jint로 객체를 선언해서 사용해주면 되고, 배열도 마찬가지로 j+자료형+Array 객체형태로 생성해서 사용하면 된다.



c++ 에서의 사용 예


void main() {     jstring str;     jint num;     jobject obj;     ... }




2. JNI 시그니처

JNI 시그니처를 사용하는 이유는 JAVA에서 생성한 클래스나 함수에 접근하기위해 C++/C에서 사용하는 구분자라고 보면 된다. 


시그니처 

Type 

byte 

char 

double 

float 

int 

long 

short 

void 

boolean 

L클래스_이름 

패키지 경로/ 클래스 이름 

[ type 

type[] 배열 


public class aa {
	public int testInt(int a) {return a;}
	public String testString(String a) {return a;}
}


위와같은 java 소스에서 aa클래스 안에는 int testint(int) 메서드와 String testString(String) 메서드가 있다.

c++에서 위의 메서드를 콜하기 위해서는 아래와 같은 문법으로 접근해야한다.



void main() {
	jclass cls = (*env)->GetObjectClass(env, obj);
	jmethodID testInt = (*env)->GetMethodID(env, cls, "testInt", "(I)I");
	jint jnum = (*env)->CallIntMethod(env, obj, testInt, num);

	jmethodID testString = (*env)->GetMethodID(env, cls, "testString", "(Ljava.lang.String;)Ljava.lang.String;");
	jstring jstr = (*env)->CallObjectMethod(env, obj, testString, str);
}


GetMethodID()를 이용하여 java함수를 콜할수 있는데 JvmEnv, jclass, "함수명", 시그니처가 매개변수로 들어간다. aa클래스를 담고있는 jclass와 함게 함수명 "testInt" 그리고 시그니처 (I)I 를 넣어줘야 위의 Java에서 생성한  int testInt(int)를 가져올 수 있다.

String 형 같은 경우에는 기본 변수타입이 아니기때문에 Object형식으로 접근해야한다. Ljava.lang.String;으로 시그니처를 입력해야하는데 주의할 점은 ; 세미클론을 빼먹을 경우 인식을 하지 못한다. 이점 유의해서 사용하길 바란다.


String형과같은 Object형을 함수에서 return시키거나 input시킬때에는 해당 클래스의 임포트 경로를 입력해주면된다. 간단하져?




Posted by 루우지