c언어 틀린것좀 알려주세요

한동수@Facebook의 이미지

#include

int main(){
float a;
scanf("%.2f",&a);
printf("%.2f", a * 2.54);
return 0;
}
간단한건데 제가 초보라 0.00으로만 출력이 되네요

wtwon의 이미지

scanf("%.2f", &a);에서
%.2f를 %f로 바꾸시면 동작합니다.

그런데 왜 scanf에서는 %.2f가 먹지 않을까요?

세벌의 이미지

man scanf

wtwon의 이미지

감사합니다:)

 의 이미지

어플리케이션 프로그래머의 관점:

그 질문은 뒤집어서 말씀하시는 게 더 낫겠군요. "scanf에서는 %.2f가 왜 먹어야 할까요?"
레퍼런스, 궁극적으로 C언어 표준을 살펴보면 scanf의 서식 지정자 포맷을 알 수 있습니다:

http://en.cppreference.com/w/c/io/fscanf

%.2f는 서식 지정자 포맷에 맞지 않습니다.

printf에서 %.2f가 먹혔으니 scanf에서도 먹힐 것이라고 지레짐작하는 것은 인간적인 생각이죠.
명세에 없는 명령어라고 해도 적절히 어림짐작해서 눈치껏 돌아가기를 기대하는 것도 인간적인 생각이고요.

머지않아 그런 인간적인 컴퓨터가 나올 수도 있겠지만, 최소한 아직까지는 컴퓨터에게 그런 기대를 가질 수는 없습니다.

표준 라이브러리 개발자의 관점:

사실 표준 라이브러리도 사람이 만드는 거죠.

언어 표준에서는 유효하지 않은 서식 지정자가 나올 경우 미정의 동작(undefined behavior)이 일어난다고 명시하고 있습니다.
즉 scanf가 %.2f를 만났을 때 어떤 일이 일어날 것인지는 라이브러리 개발자에게 재량권이 있는 것입니다.

뭐 아래와 같은 구현들을 생각해 볼 수 있겠죠.

1) 불친절한 구현
%.2f를 만났을 때 scanf가 즉시 반환하거나, 아무것도 못 본 것처럼 무시하고 지나갈 수 있습니다.
깊이 생각하지 않아도 되서 간편하죠.

2) 어설프게 친절한 구현
애초에 서식 지정자에 .이 들어갈 수 없기도 하고, 그것만 빼면 정상적인 서식 지정자가 되니까
%2f로 간주하고 실행할 수도 있겠죠. 2개 문자로 구성된 부동소수점 입력을 받게 되겠네요.

종종 이렇게 어설프게 친절한 구현이 프로그래머의 의도와 정반대로 동작해서 혼란을 낳는 경우가 있습니다.
그 책임은 애초에 미정의 동작을 유발한 어플리케이션 프로그래머에게 있습니다.

3) 진짜 친절한 구현

%.2f의 의미를 printf에서와 완전히 동일하게 해석해서, 부동소수점 입력을 받되 소수점 아래 두 자리까지만 입력받도록 구현할 수도 있겠죠.

4) 미친 구현
미정의 동작을 유발시킨 프로그래머를 징벌하기 위해, 소스 코드를 삭제하거나 목적 코드에 백도어를 심거나 rm -rf ~/를 실행할 수도 있습니다.

표준 위원회의 관점:

언어 표준도 사람이 제정하는 것입니다.

프로그래밍 언어에서 미정의 동작으로 규정된 부분은, 이후의 표준에서 동작을 명확히 정의함으로써 언어를 확장할 여지가 있습니다.

예컨대 위에서 "진짜 친절한 구현"이 일견 합리적이고, 많은 프로그래머들이 그런 동작을 기대한다는 사실이 알려진다면
그와 같은 동작을 반드시 하도록 표준이 개정될 가능성도 없지는 않습니다.

wtwon의 이미지

이렇게 레퍼런스를 인용해주시니.. 속시원(?)하네요!
표준라이브러리 개발자의 입장은 전혀 생각지 못했습니다.
레퍼런스 문서는 애용하려고 노력중이지만..허허.. 덕분에 또 배워갑니다!

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.