2017-03-14 15 views
2

내가 부호없는 INT 쓰기로 인쇄하는 기능을했다와 c를 숫자를 인쇄 :재귀 쓰기

ssize_t  putc_fdr(char c, int fd) 
{ 
    return (write(fd, &c, sizeof(char))); 
} 

ssize_t  putuint_fdr(uintmax_t i, int fd) 
{ 
     return (i != 0 ? putuint_fdr(i/10, fd) + putc_fdr(i % 10 + '0', fd) : 0); 
} 

하지만 기능은 아무것도 출력하지 않기 때문에 그것은 내가 = 0 작동하지 않습니다. ': 0'': putc_fdr('0', fd)'으로 바꾸면 i> 10 인 경우 재귀가 끝날 때마다 추가 '0'이 항상 인쇄되기 때문에 작동하지 않습니다. (논리.) 하지만 시작 i가 0 인 경우에만이 0을 인쇄하는 방법은 무엇입니까?

+1

'+'에 대한 피연산자 평가는 지정되지 않은 순서입니다. 귀하의 전화 번호는 역순으로 인쇄되기 때문에 올바르게 인쇄 될 것입니다. – StoryTeller

+0

= 0 인 경우 0으로 반환합니다. 왜냐하면 그렇게하기 위해 코드를 작성했기 때문입니다. 더 명확하게 표현하면 (i! = 0? X : Y) 항상 Y를 반환합니다. – NomeQueEuLembro

+0

[(++를 사용하는) 정의되지 않은 동작이 왜 발생합니까?] (http://stackoverflow.com/questions)/949433/why-are-these-constructs-undefined-behavior) – Olaf

답변

4

0으로 멈추지 말고 하나의 숫자에 도달하면 중지하십시오.

그리고 당신은 ?: 연산자를 죽겠다 및 함수 적은 반복과 기본 동작을 허용함으로써 순서 문제 (따라서 정확한 인쇄 순서를 보장)를 수정해야합니다 : 당신의 표현이 무엇

ssize_t  putuint_fdr(uintmax_t i, int fd) { 
     ssize_t ret1 = 0; 

     if(i/10 != 0) 
      ret1 = putuint_fdr(i/10, fd); 

     if (ret1 < 0) 
      return ret1; 

     ssize_t ret2 = putc_fdr(i % 10, fd); 

     if (ret2 < 0) 
      return ret2; 

     return ret1 + ret2; 
} 
+0

네, 감사합니다. 피연산자에 대한 실행 순서는 생각하지 않았습니다. – tfontain

1

이 고려를 :

(i != 0 ? putuint_fdr(i/10, fd) + putc_fdr(i % 10 + '0', fd) : 0); 

먼저 i != 0이 있는지 확인합니다. 그런 상태는 것에 해당하는 경우 :

  • 재귀 문 putuint_fdr(i/10, fd)

  • 전화 putc_fdr(i % 10 + '0', fd)

  • 합계 모두의 반환 값 자체를 호출하고 그것으로 아무것도 할 수 없습니다.

어느 순서로든 함수를 호출 할 수 있습니다. 경우

I =는 것입니다 0 :

정말 아무것도를하고 코드의 중간에 단지 숫자를하지 않습니다
  • return 0

. 0을 쓰는 함수를 호출해야합니다.

0

바이너리 +은 순서가 지정되지 않았으므로 피연산자를 평가하는 순서를 적용해야합니다. 대부분의 경우 개별 숫자 인쇄는 MSD를 먼저 인쇄하려는 것이므로 MSD를 설정할 때까지 인쇄 숫자를 연기합니다. 즉, 먼저 재귀 호출하고 재귀 호출에서 복귀하는 동안 인쇄하려고합니다.

현재 코드 구조를 유지하려면 쉼표 연산자 ,을 사용하여 두 번의 호출을 순서대로 지정할 수 있습니다. 딜레마를 해결하기 위해 입력이 한 자리 숫자 일 때이를 감지합니다.

ssize_t  putuint_fdr(uintmax_t i, int fd) 
{ 
    ssize_t ret = 0; 
    return (i/10 != 0 
      ? ret = putuint_fdr(i/10, fd), 
       ret + putc_fdr(i % 10 + '0', fd) 
      : putc_fdr(i + '0', fd)); 
} 

이 경우 write은 숫자 인쇄 도중 오류를 반환하지 않는다고 가정합니다. 추가 견고성을 추가하려면 해당 상황도 고려해야합니다.이 답변에 코멘트에서


, 당신은 질문 :

변수를 사용하지 않는하고 시퀀스 통화를 유지하는 방법은 없습니다? (ret ssize_t)

시퀀스 된 두 개의 함수 호출 결과를 추가하려면 일종의 변수가 필요합니다. 그러나 첫 번째 함수 호출의 결과를 매개 변수로 두 번째 함수 호출에 전달하여 할당을 숨길 수 있습니다.

ssize_t  putc_fdr(char c, int fd, ssize_t ret) 
{ 
    return ret + write(fd, &c, sizeof(char)); 
} 

ssize_t  putuint_fdr(uintmax_t i, int fd) 
{ 
    return putc_fdr(i%10 + '0', fd, 
        i/10 ? putuint_fdr(i/10, fd) : 0); 
} 
+0

변수를 사용하지 않고 시퀀스 된 전화를 유지할 방법이 없습니까? (ret ssize_t) – tfontain