otlock
149
2018-11-11 15:08:54
8
2437

C언어 부족한게 있어서 처음부터 다시시작하는데 좀 이상하네요.


#include <stdio.h>


int main(void) {


float num;

int i_part;

float f_part;


printf("실수를 입력하세요 : ");

scanf("%f", &num);


i_part = num;


f_part = num - i_part;


printf("%f의 정수부는 %d이고, 실수부는 %f 입니다.\n", num, i_part, f_part);


return 0;

}


정수형과 실수형을 구분하는 내용인데

애조에 int형이랑 float의 자료구조형 자체가 다른데 = 을 넣는다는게 데이터 손실로 안좋은 코딩아닌가요?

또 비주얼 스튜디오에선 scanf가 안전하지 않아서 scanf_s권장하는데 왜그런지 알고 싶습니다.

0
  • 댓글 8

  • 니플
    2018-11-11 15:31:51 작성 2018-11-11 15:32:23 수정됨

    안 좋은 코드는 아닙니다

    이를 형변환이라고 합니다


    정수 -> 실수같이

    넓은 자료형으로 변환되는 경우도 있고


    반대로

    실수 -> 정수 처럼

    졻은 자료형으로 변환되는 경우가 있습니다


    이 변환 과정은

    타입이 다른 변수(상수)끼리 계산에서 많이 사용합니다


    이를 자동 형변환이라고 합니다

  • 까망까망
    2018-11-11 15:35:40

    1. 일부러 실수부 손실시켜서 정수부만 남기는 묵시적 형변환의 한 예네요. 좋은 코드는 물론 아니지만 예제니까 뭐... OK 아닐까요? 실제로 처음 C언어 시작할 때 헷갈리는 부분이 데이터 타입이고...

    이런 형변환을 일부러 써서 반올림을 구현하는 코드가 있습니다.

    int res = d + 0.5; // double d = 1.2... -> 1  // double d = 1.7... -> 2


    2. scanf 보안은 프로그래머가 허용하지 않은 메모리 영역을 침범할 수 있기 때문에 발생합니다. 예를 들어 %s를 출력하는데 c[10]으로 해놓고 20자를 입력한다던지... 이런 보안 취약점을 버퍼 오버플로우라고 하는데, 아래 링크가 설명이 잘 되어 있으니 한 번 읽어보세요.

    http://kaspyx.tistory.com/2

  • otlock
    149
    2018-11-11 17:36:58 작성 2018-11-11 17:37:54 수정됨

    형변환을 해줘야 되는거 아닌가요?

    바로 정수값에 대입이 되나요? 불안정할거 같은데 제가 잘못알고 있는건가요

    c언어는 자동 형변환이 안되는걸로 알고 있는데 말이죠.

  • 까망까망
    2018-11-11 18:14:35

    When a finite value of real floating type is converted to an integer type other than _Bool, the fractional part is discarded (i.e., the value is truncated toward zero). 

    ...라고 표준에 적혀 있네요.

  • Gibson USA
    714
    2018-11-11 18:20:01 작성 2018-11-11 18:23:23 수정됨

    잘못알고 계신 건 아니고

    잘 기억해보시면 C언어 시간에 업/다운 캐스팅에 대해 배우고 넘어가는 걸 기억해내실 껍니다.


    그런 캐스팅의 방법이 최근에 생겼다든지 그것을 C언어 그룹이 모르고 있었던 것은 아니지만

    얼마 전까지는 C99를 마지막으로 C의 스펙의 버전업이 조금은 정체국면에 놓여있었는데


    그 당시 까지는 묵시적 형변환의 부정적인 가능성을 이유로 허용치 않았던 분위기가 대세였고

    그렇다 보니 현시점에선 조금 오래된 VS나 다른 IDE, 컴파일러들은

    묵시적인 형변환을 허용하지 않았던 것이죠.

  • Gibson USA
    714
    2018-11-11 18:31:25

    조금 덧붙이면 보통 배열을 선언할 때 사이즈를 정해놓고 그 사이즈 만큼만 활용하는 게 

    통상적인 배열의 활용법인데


    C99 스펙을 보시면 아시겠지만 이미 그 시절에 가변 길이 배열을 지원하고 있었습니다.


    하지만 지금도 여전히 거의 모든 C 강의들은 별 달라진 게 없죠.


    물론 어떤 편의성을 넘어선 정교한 원리상 허용하지 않는다든지 일부러 수동으로 조작하는 것이라면

    당연히 안쓰는 게 맞긴한데 그것이 있는지도 모르는 C 개발자들도 적지 않다는 겁니다.


    그래서 언어는 매번 업댓되는 스펙을 좀 살펴둬야 할 필요가 있죠.

  • otlock
    149
    2018-11-11 21:00:03

    그렇다면 C11이상의 버전은 형변환에 주의를 주지 않아도 되는거군요.


    전 평범한 대학생인지라 버전업에 대한 정보를 많이 알지 못합니다.

    그저 C언어가 계속 업데이트가 되고 있다는 정보만 알고 있습니다. (gets나 방금안 scanf_s)


    이렇게까지 깊을줄은 몰랐네요. 알려주셔서 감사합니다.


    그렇다면 어셈계열 C로 넘어가거나 C++가 관여하지 않는 C (stdlib.h가 없는)

    임베디드는 형변환에 주의해야되는건가요?

  • Gibson USA
    714
    2018-11-12 01:12:20

    Java든 C든 캐스팅은 항상 주의해야 합니다.


    어떤 시스템의 전반적인 상황과 개발팀의 업무적인 룰 등에 따라 달라지는 것이지만

    기본적으론 묵시적 캐스팅 따위는 편히 써도 되는 상황을 분별해서 써야 하는 거죠.

  • 로그인을 하시면 댓글을 등록할 수 있습니다.