'전체 글'에 해당되는 글 60건

error C4703

language/debug 2016. 8. 7. 16:53
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

BTreeNode * RemoveLeftSubTree(BTreeNode * bt)

{

                  BTreeNode * delNode;

 

                  if(bt != NULL) {

                                   delNode = bt->left;

                                   bt->left = NULL;

                  }

                  return delNode;

}

 

BTreeNode * RemoveRightSubTree(BTreeNode * bt)

{

                  BTreeNode * delNode;

 

                  if(bt != NULL) {

                                   delNode = bt->right;

                                   bt->right = NULL;

                  }

                  return delNode;

}


error C4703: 초기화되지 않았을 수 있는 로컬 포인터 변수 'delNode'이(가) 사용되었습니다.

(error C4703: potentially uninitialized local pointer valibale 'delNode' was used)



위의 경우, 디버그-> 프로젝트 속성 -> 일반 -> C/C++ -> SDL 검사 속성을 '아니오'로 변경하면 해결된다.

(Debug -> [Project Name] Properties -> General -> C/C++ -> SDL Check)


혹은, 


위 error는 포인터 변수를 초기화해주지 않아서 발생하므로, 


                  BTreeNode * delNode NULL;



위와 같이 해당하는 코드에 null값을 대입해주면 문제가 해결된다.






'language > debug' 카테고리의 다른 글

runtime check failure #2  (0) 2016.07.18
_CRT_SECURE_NO_WARNINGS  (0) 2016.05.07
블로그 이미지

saylin

,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

main 함수의 마지막에 0을 return하는 이유


main 함수는 우리가 호출하는 함수가 아니라 운영체제에 의해서 자동적으로 호출되는 함수

따라서 return 값은 운영체제로 넘어가는데, 이 때 main 함수를 통해 반환받는 값을 통해 프로그램의 이상 유무를 판단하게 된다.


그리고, 0을 반환한다는 것은 정상적인 종료를 뜻한다.



증가, 감소 연산자


연산자        연산자의 의미


++a            값을 1 증가 후 연산을 진행(선 증가, 후 연산)

a++            연산을 진행한 후 값을 1 증가(선 연산, 후 증가)



논리 연산자


연산자        연산자의 의미


&&            and

||               or

!                not



비트 단위 연산자


연산자        연산자의 의미(비트 단위)


&              AND

|                OR

^              XOR

~              NOT


<<            왼쪽으로 이동

>>            오른쪽으로 이동


연산자의 우선순위와 결합성


우선순위


연산 순위

연산자

결합성

1

(), [], ->, .

2

sizeof, &, ++, ==, ~, !, *(간접 지정 연산자), +, -(단항 연산자)

3

*(곱셈 연산자), /, %

4

+, -(이항 연산자)

5

<<, >>

6

<, <=, >=, >

7

==, !=

8

&

9

^

10

|

11

&&

12

||

13

?:

14

=, +=, *=, /=, %=, &=, ^=, |=, <<=, >>=

15

,(콤마 연산자)

 

결합성

우선 순위가 같은 연산자가 둘 이상 있을 경우에 무엇을 먼저 연산하느냐를 결정짓는 것



C언어의 키워드


C99를 기준으로 표준화된 키워드들

auto

_Bool

break

case

char

_Complex

const

continue

default

restrict

do

double

else

enum

extern

float

for

goto

if

_Imaginary

inline

int

long

register

return

short

signed

sizeof

static

struct

switch

typedef

union

unsigned

void

volatile

while

 

 

 




정수와 실수의 표현 방식


정수의 표현 방식


int형 변수의 경우 보통은 4바이트 메모리 공간을 이용해서 데이터를 표현한다.

모든 정수의 가장 왼쪽에 있는 비트는 부호 비트(MSB: Most Significant Bit, 가장 중요한 비트)


음수를 표현할 때는 2의 보수 체계를 기억해야 한다.

2의 보수: 1의 보수를 취한 후, 1을 더한 것.


ex)

5+(-5)의 연산을 진행하는 경우, 


-5는 실질적으로 5의 (2의 보수)가 취해진 값이므로 

더하면 모든 비트의 값은 0이 되고 올림 수(carry)는 버려진다.


실수의 표현 방식


적은 비트 수를 가지고 넓은 범위의 실수를 표현하기 위해서 



위 식을 미리 정의해놓고, 메모리에 할당된 데이터의 일부 비트는 m의 값을 정하고, 일부 비트는 e의 값을 정하는데 사용한다.

이 경우, 넓은 범위의 실수를 표현할 수 있다는 장점이 있지만, 오차가 발생하게 된다.


이러한 오차를 부동소수점 오차라고 한다.

따라서, 컴퓨터는 실수를 근사치만 표현한다.


ex)

위 식으로 0을 표현하는 것은 불가능하다.



기본 자료형 종류와 데이터의 표현 범위


자료형

할당되는 메모리 크기

정수형

char

1바이트

short (short int)

2바이트

int

4바이트

long (long int)

4바이트

실수형

float

4바이트

double

8바이트

long double

8바이트 혹은 그 이상

 

컴퓨터 내부적으로 int형 데이터를 가장 빠르게 연산한다.


실수 자료형의 정밀도


자료형

정밀도

float

소수 이하 6자리

double

소수 이하 15자리

long double

double과 같거나 크다


float의 정밀도는 낮으므로 double형을 선호



unsigned +자료형


기본 자료형 앞에 unsigned를 붙이면 첫 번째 비트인 MSB 또한 데이터 비트로 사용하여 데이터 표현 범위가 2배로 넓어진다.



상수


이름이 없는 상수: 리터럴(literal) 상수


int val = 30 + 40;


위 연산을 진행하기 위해서 30, 40은 메모리 상에 이름이 없는 상수로 저장된 후 연산이 진행된다. 

이 30, 40을 리터럴 상수라고 한다.


리터럴 상수의 자료형


리터럴 상수 또한 자료형이 있고, 사용자가 자료형을 지정하지 않을 경우 자동으로 자료형이 결정된다.


접미사

자료형

사용 예

u or U

unsigned int

304U

l or L

long

304L

ul or UL

unsigned long

304UL

f or F

float

3.15F

l or L

long double

3.15L



이름이 있는 상수: 심볼릭(symbolic) 상수


const 키워드 혹은 매크로를 사용해서 정의 (이 때, 상수 이름은 가급적 대문자로 정의)



자료형의 변환


자동 형 변환(묵시적 형 변환)


대입 연산 시 발생하는 자동 형 변환


값의 표현 범위가 좁은 데이터를 표현 범위가 넓은 데이터로 변환 시에는 아무런 문제가 발생하지 않는다.

값의 표현 범위가 넓은 데이터를 표현 범위가 좁은 데이터로 변환 시, 데이터의 손실이 발생(소수부의 손실, 상위 비트의 손실)


정수의 승격(integral promotion)


char, short와 같은 정수형 데이터 연산은 일단 int형 데이터로 자동 형 변환된 이후 연산이 이루어지고, 

int형 데이터는 형 변환 과정을 거치지 않기 때문에 int형 연산이 빠르다.


int형 연산만 지원하는 것은 정수형 연산을 단일화해서 성능을 향상시키기 위함이다.


산술 연산 과정에서의 형 변환


산술 연산 과정에서 일어나느 형 변환은 데이터의 손실이 최소화되는 방향으로 진행된다.


ex)

double e1 = 5.5 + 7;

double형 데이터로 변환된 후에 연산이 이루어진다.


강제 형 변환(명시적 형 변환)


변수 앞에 (자료형의 이름)


ex)

float f = (float)a / b;



다양한 종류의 특수 문자


특수 문자

의미

\a

경고음 소리 발생

\b

백스페이스

\f

폼 피드(form feed)

\n

개행

\r

캐리지 리턴(carriage return)

\t

수평 탭

\v

수직 탭

\\

백슬래시

\'

작은 따옴표

\"

큰 따옴표



서식 문자의 종류와 그 의미


서식 문자

문자열의 출력 양식을 정의하는 문자


서식 문자

출력 형태

%c

단일 문자

%d

부호 있는 10진 정수

%i

부호 있는 10진 정수, %d와 동일

%f

부호 있는 10진 실수

%s

문자열

%o

부호 없는 8진 정수

%u

부호 없는 10진 정수

%x

부호 없는 16진 정수, 소문자 사용

%X

부호 없는 16진 정수, 대문자 사용

%e

e 표기법에 의한 실수

%E

E 표기법에 의한 실수

%g

값에 따라서 %f, %e 둘 중 하나를 선택

%G

값에 따라서 %f, %E 둘 중 하나를 선택

%%

% 기호 출력


서식 문자

출력 형태

%8d

필드 폭을 8칸 확보하고 오른쪽 정렬해서 출력

%-8d

필드 폭을 8칸 확보하고 왼쪽 정렬해서 출력

%+8d

필드 폭을 8칸 확보하고 오른쪽 정렬한 상태에서 양수는 +, 음수는 -를 붙여서 출력


실수형 데이터를 입력받을 때


서식 문자

사용

%f

소수점 6자리 이하인 경우

%le

소수점 6자리를 넘는 경우



while문, do~while문의 차이점


while문은 반복의 조건 검사를 앞에서 실행하므로 조건이 만족되지 않으면 한번도 실행하지 않지만, 

do~while문은 반복의 조건 검사를 뒤에서 하므로 반드시 한번의 루프는 실행하게 되어 있다. 



for문의 기본 원리와 의미


for ( 초기문 ; 조건문 ; 증감문 )


첫번째 루프에서는 증감문을 실행하지 않는다.

그리고 루프 실행 이후 실행 여부 결정을 위한 조건문 검사 전에 증감문을 실행한다.


초기문, 조건문, 증감문을 반드시 다 채울 필요는 없고 필요한 것만 채워도 된다.

조건문을 비워두는 경우, 무한 루프를 형성할 수 있다.



조건 연산자(삼항 연산자)


조건 ? A : B


조건이 true인 경우, A를 반환

조건이 false인 경우, B를 반환


ex)

x=(y<0)? 10:20

(y<0)이 true이면 10이 반환되여 x에 대입

(y<0)이 false이면 20이 반환되여 x에 대입



루프의 생략과 탈출: continue, break


break

반복문을 탈출할 때 사용하는 키워드


continue

돌던 루프의 남아 있는 부분을 그냥 건너뛰고 새로운 루프를 돌게하도록 하는 키워드



switch에 의한 선택 실행


switch(n) 

n은 int, char 형 정수

switch문의 case문에 해당하는 조건이 없는 경우 default문을 실행

case문의 끝에는 break문이 포함된다.

switch문에서는 비교문이 올 수 없다.



goto 키워드


이동할 위치를 표시한 레이블(label)로 보내는 키워드


goto xyz;

...

xyz:

...



변수의 범위(scope)


지역 변수(local variable or automatic variable)


중괄호(지역) 내에 선언된 변수는 모두 지역 변수

중괄호를 벗어나면 선언된 지역 변수는 소멸된다.


지역 변수는 외부에 선언된 동일한 이름의 변수를 가릴 수 있다.

지역 내에서는 지역 변수가 전역 변수보다 우선시된다.


모든 (함수의) 매개 변수는 지역 변수다.

지역을 벗어나면 소멸된다하여 지역 변수를 다른 표현으로 자동 변수라고도 한다. 

원칙적으로 지역 변수 선언 시, auto 키워드를 붙여야하지만, 생략이 가능하다.


전역 변수(global variable)


함수의 외부에 선언되고 프로그램 어디에서나 접근이 가능한 변수

선언과 동시에 한번만 초기화되고, 값을 초기화하지 않는 경우 0으로 초기화된다.

프로그램 시작 시 메모리에 로드되고, 프로그램이 종료될 때까지 계속 존재한다.


전역 변수의 수가 많아지면 프로그램은 복잡해질 수 있다. (스파게티 코드, spaghetti code)

따라서, 전역 변수가 반드시 필요할 때만 선언하는 것이 좋다.


static 변수


함수 내 선언된 static 변수는 그 특성이 전역 변수와 비슷하다.

선언된 지역 내에서만 접근 가능하고, 전역 변수와 마찬가지로 프로그램이 종료될 때까지 계속 존재한다.

프로그램이 실행되는 동안에 계속해서 유지되어야 하는 변수가 있다면 static 변수의 선언을 고려하는 것이 좋다.


register 변수


register는 CPU의 접근이 가장 빠른 메모리 공간이다.

CPU의 레지스터는 크기가 제한되어 있는 공간이라 상황에 따라 이러한 요청은 무시될 수 있다.


생성과 소멸이 빈번한 변수를 register 변수로 선언하면 성능 향상을 기대할 수 있다.

컴파일러가 코드 최적화를 수행하는 과정에서 자동으로 register 변수로 선언될 수도 있다.



가변 인자 함수


전달 인자의 개수가 다양한 함수.

C 언어에는 가변 인자 함수의 선언에 대한 문법적 요소가 있다.


ex)

printf, scanf







블로그 이미지

saylin

,

typedef

language/C|C++ 2016. 8. 6. 18:23
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

typedef 


이미 존재하는 자료형에 새로운 이름을 붙이기 위한 용도로 사용되는 키워드


ex)

typedef int INT;


int에 새로운 이름인 INT를 붙여준다.





'language > C|C++' 카테고리의 다른 글

포인터 배열과 문자열 배열  (0) 2016.08.08
C언어 정리 2  (0) 2016.08.08
FILE* fopen  (0) 2016.07.26
문자와 문자열 처리 함수  (0) 2016.07.25
데이터 상수화, 포인터 상수화  (0) 2016.07.21
블로그 이미지

saylin

,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

당신은 오랜 기간 동안 어머니로부터의 잔소리, TV 혹은 자기 계발 서적 등에서 떠드는 진부한 소리에 세뇌된 끝에 오늘부터 성실히 살기로 결심했다. 그 첫 번째 단계로, 주간 달력을 구매해서 매일 할 일을 달력에 적고 그대로 수행하기로 결정했다. 다음의 예처럼 말이다.

하지만 달력을 사러 나가려는 순간, 당신은 모든 것이 귀찮아졌다. 대신, 집에 굴러다니는 빈 노트에 펜으로 주간 달력을 그려서 대체하기로 결정했다. 그러자 또 다른 문제가 발생했는데 바로 당신이 각 요일이 며칠에 해당하는지 생각하기가 귀찮다는 것이다. 당신은 휴대폰으로 오늘이 몇 월 며칠이며, 무슨 요일인지 알았다. 천만 다행으로 당신을 귀찮게 하지 않는 점은 올해는 윤년이 아니라는 것이다. 이제 컴퓨터 프로그램을 작성하여 주간 달력에 들어갈 숫자들을 완성하라.

첫 줄에는 테스트 케이스의 수 T가 주어진다.

각 테스트 케이스마다 한 줄에 오늘이 몇 월 며칠이며, 무슨 요일인지를 나타내는 2개의 숫자 m,d와 하나의 문자열 s가 하나의 공백을 사이에 두고 입력으로 주어진다. 입력으로 주어지는 m과 d는 달력에 있을 수 있는 날짜이며, 2월 29일인 경우는 없다. 요일을 나타내는 s는 Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday 중 하나이다.

각 테스트 케이스마다 한 줄씩 그 주의 주간 달력에 쓰여야 할 숫자 7개를 하나의 공백을 사이에 두고 일월화수목금토 순으로 출력한다.



#include <iostream>

#include <cstring>

using namespace std;

 

#define START 1

#define END 7

 

char *WEEK[8] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

 

void End_MONTH(int x, int *y, int *z, int a);

void Calculate_INDEX(char* x, int *y);

 

int main() {

 

    int T, END_MON, MON, MON_BEFORE, THIS_DAY, DAYS,INDEX= 0;

    int WEEKDAY[8]={NULL};

    char DAY_CHAR[10]={NULL};

 

    cin>>T;

 

    while(T--){

        cin>>MON>>DAYS>>DAY_CHAR;

 

        End_MONTH(MON, &END_MON, &MON_BEFORE, DAYS);

        Calculate_INDEX(DAY_CHAR, &INDEX);

 

        // 인덱스를 기준으로 배열의 왼쪽을 채움

        THIS_DAY= DAYS;

        for(int i= INDEX; i>= START; i--) {

            WEEKDAY[i-1]= THIS_DAY;

            THIS_DAY--;

            if(THIS_DAY <1) THIS_DAY= MON_BEFORE;

        }

 

        // 인덱스를 기준으로 배열의 오른쪽을 채움

        THIS_DAY= DAYS;

        for(int i= INDEX; i<= END; i++) {

            WEEKDAY[i-1]= THIS_DAY;

            THIS_DAY++;

            if(THIS_DAY >END_MON) THIS_DAY= START;

        }

 

        for(int i= 0; i<6; i++) {

            cout<<WEEKDAY[i]<<" ";

        }

        cout<<WEEKDAY[6]<<endl;

    }

 

    system("pause");

}

 

// 현재 , 지난 월의 마지막 일수를 계산해서 저장

// 다음 달의 경우, 1일부터 시작하므로 변수에 저장하지 않음

void End_MONTH(int x, int *y, int *z, int a) {

 

    // 일수가 31일인

    if(x == 1 || x == 3 || x == 5 || x == 7 || x == 8 || x == 10 || x == 12) {

 

        // 예외값 처리

        if(a <1 || a> 31) exit(1);

 

        //8월과 1월의 경우, 지난 달의 일수는 31

        if(x == 8 || x == 1) {

            *y= 31; *z= 31;

            return;

        }

 

        // 3월의 경우, 지난 달의 일수는 28

        if(x == 3) {

            *y= 31; *z= 28;

        }

 

        *y= 31; *z= 30;

        return;

    }

 

    // 일수가 28일인 2

    else if(x == 2) {

        if(a <1 || a> 28) exit(1);

        *y= 28; *z= 31;

        return;

    }

 

    // 일수가 30일인

    else {

        if(a <1 || a> 30) exit(1);

        *y= 30; *z= 31;

        return;

    }

}

 

// 입력받은 문자열이 주의 번째 일수에 위치하는지 인덱스 계산

void Calculate_INDEX(char* x, int *y) {

 

    int k= 0;

 

    for(int i=0; i<END; i++) {

        k =strcmp(x, WEEK[i]);

        if(k== 0) {

            *y= i+1;

            return;

        }

    }

    if(*y ==0)

        exit(1);

}



출력 결과만 보면 문제가 없는 것처럼 보이나, 답안 제출 시 오답 판정된다.


디버깅이 끝나면 해당 부분을 고쳐 수정할 계획이다.





'language > 알고리즘' 카테고리의 다른 글

MISPELL  (0) 2016.07.19
XOR 연산자를 이용한 Swap  (0) 2016.07.18
ENDIANS  (0) 2016.07.18
알고리즘: 효율, 분석 그리고 차수  (0) 2016.07.10
블로그 이미지

saylin

,