11번가 아마존 구매시 머니백 DZH9010 추천코드
c,c++,c# and algorithm
2021년 11월 3일 수요일
2016년 12월 9일 금요일
void** (double void pointer) 고찰
많은 API 에서 void ** 가 쓰인다.
이 void **를 한번 분석해보자
1. 다차원 포인터
int * * pI
int * * pI 포인터 변수이다
char* 자체를 void*로 바꿔서 생각해 보자.
void** 는 void* 의 포인터 이므로 유연하게 모든 포인터를 void*로 받을수 있다.
이 void **를 한번 분석해보자
1. 다차원 포인터
int * * pI
int * * pI 포인터 변수이다
int * * pI int* 의 주소를 담는 (int**) 형의 타입이다.
2. void 포인터
보이드 포인터 타입은 모든 포인터를 대입할수 있다.
(malloc 는 void*를 리턴한다.)
단 역참조와 정수와의 주소 offset 연산이 불가능하며 같은 void 포인터 타입과 비교연산(==)가 가능하다
(malloc 는 void*를 리턴한다.)
단 역참조와 정수와의 주소 offset 연산이 불가능하며 같은 void 포인터 타입과 비교연산(==)가 가능하다
void * vP;
int * nP;
....
*nP <--- O 가능 int포인터로써 역참조가 가능하다.
*vP <--- X 불가능 대체 무슨타입으로 역참조를 해야한단 말인가? 컴파일러는 판단할수 없다.
*nP 는 직접적으로int의 정수에 접근이 가능하지만
위의 두 포인터 변수의 차이는 void는 형을 알수없음으로 역참조를 할수 없는데 있다.
3.void **
앞에 두 개념을 숙지하고 아래의 개념을 다시 한번 생각해보았다.
앞에 두 개념을 숙지하고 아래의 개념을 다시 한번 생각해보았다.
왜 void**를 쓰는가?
char* 자체를 void*로 바꿔서 생각해 보자.
void** 는 void* 의 포인터 이므로 유연하게 모든 포인터를 void*로 받을수 있다.
const char* funcMsg = "hello World";
void func(void **something)
{
*something= (void *)funcMsg;
}
char * msg;
func((void**)&msg);
printf(msg);
2016년 8월 9일 화요일
KMP 알고리즘
문자열이 아닌 바이너리 모드에서 기존 STL의 문자열 탐색 라이브리는 정상 작동되지
않는다.
1.기본 개요
위 그림의 문자열 비교 처럼 문자열이 일치하지 않을때, 이미 비교한 부분의 정보를 가지고 불필요한 비교를 피하는것이 KMP알고리즘의 원리의 전부이다.
이 알고리즘을 적용하려면 패턴이 어디까지 일치하였을때, 얼마만큼 패턴을 스킵해야 할지 계산할 필요가 있다.
일치 텍스트와 패턴을 비교하지 않고 미리 패턴의 접두사와 접미사를 이용해 패턴의 접두 접미 일치표를 만들어놓고 실제 텍스트와 패턴 비교시 사용하는것이 접두 접미 일치표이다
패턴 ababaca
텍스트 bacbababaabacbab
아래의 코드를 첨부한다
#include
#include
#include "Kmp_Header.h"
KmpSearch::~KmpSearch()
{
if (!m_pMatchTable)
free(m_pMatchTable);
}
int KmpSearch::SearchKmp(Byte* text, Byte* pattern, int textLen, int patternLen)
{
m_textLen = textLen;
m_patternLen = patternLen;
m_text = text;
m_pattern = pattern;
PrefixPI();
Matching();
return 1;
}
int KmpSearch::PrefixPI()
{
m_pMatchTable = (int*)malloc(sizeof(int)*m_patternLen);
int i = 1; //접미사
int j = 0; //접두사
m_pMatchTable[0] = 0;
while (i < m_patternLen)
{
if (m_text[i] == m_pattern[j])
{
m_pMatchTable[i] = j;
i++;
j++;
}
else if (j > 0)
{
j = m_pMatchTable[j - 1];
}
else
{
m_pMatchTable[i] = 0;
i++;
}
}//while
return 1;
}
int KmpSearch::Matching()
{
int i = 0; //text index
int j = 0; //pattern index
while (i < m_textLen)
{
if (m_text[i] == m_pattern[j])
{
if (j + 1 == m_patternLen)
return i - j;
i++;
j++;
}
else if (j>0) //i는 고정 전 j값으로 비교 다르기 전까지 접두사 비교 일치
{
j = m_pMatchTable[j-1];
}
else
{
i++;
}
}
return -1;
}
사용 방법
PrefixPI((unsigned char*)pattern, _mbstrlen(pattern));
int result = Matching((unsigned char*)text, _mbstrlen(text), (unsigned char*)pattern, _mbstrlen(pattern));
-참고 서적-
1. 다양한 예제로 배우는 알고리즘
http://book.naver.com/bookdb/book_detail.nhn?bid=7430898 2. Introduction to Algorithms.
2016년 6월 2일 목요일
const iterator 를 리턴하는 stl 자료구조에서 const를 푸는법
map 류의 힙형 자료구조는 정렬된 상태를 유지하기에 iterator가 const값만을 리턴한다
따라서 부득이하게 iteraotr 값을 바꿔야할 경우
템플릿 함수를 하나 만들고 아래처럼 활용한다.
따라서 부득이하게 iteraotr 값을 바꿔야할 경우
템플릿 함수를 하나 만들고 아래처럼 활용한다.
template T & unconst(const T & x)
{
return const_cast(x);
};
multimap myMap;
multimap::iteraotr it;
.
.
.
unconst(*it);
2015년 1월 28일 수요일
user defined conversion ,void pointer ,Smart Pointer에서의 쓰임
출처 : http://www.informit.com/articles/article.aspx?p=31529&seqNum=7함수 인자에서 형변환과 유저 타입 형변환 연산자가 어떻게 작용하는지 설명하는 좋은 글이라 생각한다something* 타입 형변환을 SmartPtr 포인터에 operator something* 타입으로 정의 선언 해 놓으면그 함수를 fun(sp)시 그 연산자 호출 된다 암시적 형변환을 통해 (something*)으로의 형변환 연산자를 찾게되고 다시포인터 타입임으로 암시적으로 void* 로 변환된다..7.7 Implicit Conversion to Raw Pointer Types
Consider this code:void Fun(Something* p); ... SmartPtr<Something> sp(new Something); Fun(sp); // OK or error?Should this code compile or not? Following the “maximum compatibility” line of thought, the answer is yes.Technically, it is very simple to render the previous code compilable by introducing a user-defined conversion:template <class T> class SmartPtr { public: operator T*() // user-defined conversion to T* { return pointee_; } ... };However, this is not the end of the story.User-defined conversions in C++ have an interesting history. Back in the 1980s, when user-defined conversions were introduced, most programmers considered them a great invention. User-defined conversions promised a more unified type system, expressive semantics, and the ability to define new types that were indistinguishable from built-in ones. With time, however, user-defined conversions revealed themselves as awkward and potentially dangerous. They might become dangerous especially when they expose handles to internal data (Meyers 1998a, Item 29), which is precisely the case with theoperator T* in the previous code. That's why you should think carefully before allowing automatic conversions for the smart pointers you design.One potential danger comes inherently from giving the user unattended access to the raw pointer that the smart pointer wraps. Passing the raw pointer around defeats the inner workings of the smart pointer. Once unleashed from the confines of its wrapper, the raw pointer can easily become a threat to program sanity again, just as it was before smart pointers were introduced.Another danger is that user-defined conversions pop up unexpectedly, even when you don't need them. Consider the following code:SmartPtr<Something> sp; ... // A gross semantic error // However, it goes undetected at compile time delete sp;The compiler matches operator delete with the user-defined conversion to T*. At runtime, operator T*is called, and delete is applied to its result. This is certainly not what you want to do to a smart pointer, because it is supposed to manage ownership itself. An extra unwitting delete call throws out the window all the careful ownership management that the smart pointer performs under the covers.There are quite a few ways to prevent the delete call from compiling. Some of them are very ingenious (Meyers 1996). One that's very effective and easy to implement is to make the call to deleteintentionally ambiguous. You can achieve this by providing two automatic conversions to types that are susceptible to a call to delete. One type is T* itself, and the other can be void*.template <class T> class SmartPtr { public: operator T*() // User-defined conversion to T* { return pointee_; } operator void*() // Added conversion to void* { return pointee_; } ... };A call to delete against such a smart pointer object is ambiguous. The compiler cannot decide which conversion to apply, and the trick above exploits this indecision to good advantage.Don't forget that disabling the delete operator was only a part of the issue. Whether to provide an automatic conversion to a raw pointer remains an important decision in implementing a smart pointer. It's too dangerous just to let it in, yet too convenient to rule it out. The final SmartPtr implementation will give you a choice about that.However, forbidding implicit conversion does not necessarily eliminate all access to the raw pointer; it is often necessary to gain such access. Therefore, all smart pointers do provide explicit access to their wrapped pointer via a call to a function:void Fun(Something* p); ... SmartPtr<Something> sp; Fun(GetImpl(sp)); // OK, explicit conversion always allowedIt's not a matter of whether you can get to the wrapped pointer; it's how easy it is. This may seem like a minor difference, but it's actually very important. An implicit conversion happens without the programmer or the maintainer noticing or even knowing it. An explicit conversion—as is the call to GetImpl—passes through the mind, the understanding, and the fingers of the programmer and remains written in the code for everybody to see it.Implicit conversion from the smart pointer type to the raw pointer type is desirable, but sometimes dangerous. SmartPtr provides this implicit conversion as a choice. The default is on the safe side—no implicit conversions. Explicit access is always available through the GetImpl function.
2015년 1월 27일 화요일
c++ static 함수의 접근 범위
class foo {
public:
int a;
// static member function "get_a" ...
static int get_a(foo *f) {
// ... accesses public non-static data member "a"
return f->a;
}
};
위의 예제와 같이 static 함수가 클래스의 멤버로 속해 있다면 객체를 받아와서
객체의 논스테틱 멤버에 접근이 가능하다
class foo {
public:
int a;
// static member function "get_a" ...
};
static int get_a(foo *f) {
// ... accesses public non-static data member "a"
return f->a;
}
단 아래의 경우는 스태틱 함수가 클래스의 멤버가 아니므로 객체의 인스턴스를 받아온다 하더라도
NonStatic 멤버에 접근할수 없다
출처:
http://stackoverflow.com/questions/1871379/c-static-member-functions-and-their-scope
MFC 에서의 클래스위자드에서는 ON_MESSAGE는 자동화 해주지 않는다..
Note |
---|
ClassWizard does not support entering ON_MESSAGE handler routines from the ClassWizard user interface: you must manually enter them from the Visual C++ editor. Once entered, ClassWizard will parse these entries and allow you to browse them just like any other message-map entries.
MSDN 발췌: POSEMESSAGE SENDMESSAGE 를 처리하는 루틴은
클래스 위자드에서 지원하지 않는다.
따라서 수동으로 추가하여야 한다
|
c++ 디폴트 생성자와 함수 선언
class MyClass
{
//...
//...
};
main()
{
MyClass my();//문제가 될 소지가 있다 c++ 컴파일러 파서에서는 함수의 선언인지
//디폴트 생성자인지 처리해야하는 모호함의 문제가 있다
//컴파일러에 따라 경고,혹은 error 처리 된다
}
2015년 1월 6일 화요일
윈도우 8.1 IDE 로 설치후 AHCI 로 바꾸는 방법
출처:
http://pricklytech.wordpress.com/2014/02/04/windows-8-1-enabling-ahci-after-installing-windows/
1. 시작 버튼에 마우스 오른쪽 클릭후 메뉴에 관리자 권한으로 명령 프롬프트를 실행한다
2. bcdedit /set {current} safeboot minimal 라고 입력 한다
3. 후에 재부팅 하고 부팅 전 바이오스에 들어가(일반적으로 DEL,F9,F8 버튼을 누르면 들어간다) IDE 모드를 AHCI로 변경한다
4. 윈도가 안전모드로 부팅되면 마찬가지로 관리자 권한 명령 프롬프트를 실행한다
5. bcdedit /deletevalue {current} safeboot 를 입력후 재부팅 한다
http://pricklytech.wordpress.com/2014/02/04/windows-8-1-enabling-ahci-after-installing-windows/
1. 시작 버튼에 마우스 오른쪽 클릭후 메뉴에 관리자 권한으로 명령 프롬프트를 실행한다
2. bcdedit /set {current} safeboot minimal 라고 입력 한다
3. 후에 재부팅 하고 부팅 전 바이오스에 들어가(일반적으로 DEL,F9,F8 버튼을 누르면 들어간다) IDE 모드를 AHCI로 변경한다
4. 윈도가 안전모드로 부팅되면 마찬가지로 관리자 권한 명령 프롬프트를 실행한다
5. bcdedit /deletevalue {current} safeboot 를 입력후 재부팅 한다
2014년 12월 23일 화요일
매개변수에서 const 위치
1. const 가 * 의 왼쪽에 위치 시 포인터가 가르키는 대상이 상수.. char const * a
a[0]='a' 불가
2. const 가 * 의 오른쪽에 위치 시 포인터 변수가 상수 char * const a
a = "abcd " 불가
타입명과 const 위치는 바뀌어도 뜻은 똑같다.
void fun (const char *a)
void fun (char const *a)
a[0]='a' 불가
2. const 가 * 의 오른쪽에 위치 시 포인터 변수가 상수 char * const a
a = "abcd " 불가
타입명과 const 위치는 바뀌어도 뜻은 똑같다.
void fun (const char *a)
void fun (char const *a)
피드 구독하기:
글 (Atom)