2010-02-09 4 views
7

에 문자열을 복사? * s = * t가 먼저 완료되고 각각이 증가됩니까? 아니면 다른 방법으로?이 코드에 대한 혼란 스러워요 C

감사합니다.

편집 : 그리고 그것은 무엇 경우 :

while(*(s++) = *(t++)); 

while(++*s = ++*t); 
+1

조엘이 아직 5 살짜리 기사로 서 있을지 궁금합니다 ... 조엘에 대한 의견을 말합니까? – Hogan

+0

나는 모든 사람이 루프 조건 바로 뒤에 대신에 다음 줄에 세미콜론을 넣기 시작합니다. while 절에는 body에 대한 null 문으로 반복합니다. 나는 그것이 훨씬 더 명확하고 읽기 쉽다고 정말로 생각한다. –

답변

14
while (*s++ = *t++); 

precedence table 명확 ++*보다 더 높은 우선 순위를 가지고있다 볼 수 있습니다. 그러나 여기서는 ++이 사후 증가 연산자로 사용되므로 할당 식 뒤에 증가가 발생합니다. 따라서 *s = *t이 먼저 발생하면 s와 t가 증가합니다.

편집 :

while(*(s++) = *(t++)); 

상기와 동일합니다. 괄호를 사용하면보다 명확하게 나타납니다. 그러나 ++이 여전히 게시물 증가라는 것을 기억하십시오.

while(++*s = ++*t); 

다음의 단지 한 명의 작업자가있다. 따라서 *이 먼저 적용되고 ++이 적용되어 lvalue required 오류가 발생합니다. 다음의에

while(*++s = *++t); 

다시 단지 운영자, t. 따라서 증분이 먼저 복사 한 다음에 발생합니다. 그래서 우리는 t에서 s까지의 첫 번째 char의 복사본을 효과적으로 건너 뛰고 있습니다.

+0

"우선 순위"가 아니라 "우선 순위"가 아닌가? 그것은 영국계/미국인 일 수도 있기 때문에 편집하고 싶지 않습니다. –

2

증분은 후행 증가이다. 포스트는 변수가 증가 된 후에 오는 것이기 때문에뿐만 아니라 표현식이 평가 된 후에 오는 것이기 때문에 게시하십시오. 그래서 실행 순서는

*s = *t 

다음의 ++와 t ++

1

편집 :

@chrisgoyal 실행

주문 모호한 용어입니다. 여기에는 두 가지가 있습니다. 구문의 순서와 표현의 의미.

구문 상으로 연산자 ++가 먼저 적용됩니다. * 표시 (S)가 먼저 적용되면, 다음이 @Hogan는 말을하는 것과 같습니다 조엘의 샘플에서 다른 매우입니다

(*s)++ = (*t)++ 

.

연산자 ++의 의미는 표현식 뒤에 실행된다는 것입니다.

고기가 무엇인지 분명히하는 희망.


사실 s++t++ 먼저인가된다. 수정이 끝나면 이 실행되고이 실행 된 것을 잊지 마십시오. 기본적으로 연산자 ++이 모두 에 적용되고*s = *t이 실행됩니다.

+0

잘못 ... 후 오른쪽 후. 이전에 발생한 증가를 설명했습니다. – Hogan

+0

@Hogan 사후 수정 연산자는 ** 더 높은 우선 순위 **이므로 가장 먼저 적용됩니다. 수정 된 연산자의 * 의미 *는 표현식이 완료된 후에 적용됩니다. – AraK

+0

당신의 대답은 두 가지 다른 말을합니다 ... – chrisgoyal

4

당신 말이 맞습니다. * s = * t가 먼저 수행 된 다음 증가합니다.

0

In 포스트 증가 작업 변수가 먼저 사용 된 다음 해당 변수가 수정 된 후 사용됩니다. 에서

0

그래서 증가

++s // increment before using value 
s++ // increment after using value 

의 두 가지 형태가있다 그리고 이러한 결과는 역 참조 할 수 있습니다

*++s // or... 
*s++ 

이 실행하는 C의 최초의 시스템 중 하나에서 정말 잘했다 on, PDP-11은 레지스터를 증분하는 레지스터 간접 어드레싱 모드를가집니다.

*--s // or 
*s++ 

당신은 하나

*x++ = *y++; // or 
*--x = *--y; // or some combination 

을 할 수있는 그리고 당신이 한 경우, 전체 라인은 단일 명령에서 일어난 다음 작전은 하드웨어에서 사용할 수있었습니다. 그러나 // C99에 의해 주석이 도입 되었기 때문에 실제로 주석 구문을 사용할 수는 없습니다.

+0

C 컴파일러의 99 %를 사용하여'//'주석을 없앨 수 있습니다. 좋은 생각은 아니지만 누군가를 죽일 수 있을지는 의문입니다. –

+0

평소처럼, 당신 말이 맞아요. 전 완전히 동의하지만, PDP-11 C 컴파일러에서 일하지 않았을 것이라고 추측했습니다 ... – DigitalRoss

0

코드 : - 여분의 괄호 (이 경우) 아무 것도 변경하지 않는 두 번째 정확히 동일

while (*s = *t) { 
    ++s; 
    ++t; 
} 

: (while *s++ = *t++);은 거의 비슷하다. parens가 무엇이든을하기를 위해, 그들은 같이이어야했다 : while ((*s)++ = (*t)++);. 이것은 세 번째 예제 (아래 단락에서 설명)와 거의 동일합니다.

마지막 예 : while(++*s = ++*t);은 완전히 다릅니다. 역 참조 (*)가 피연산자에 더 가깝기 때문에 피연산자를 역 참조하고 역 참조의 결과를 증가시킵니다. 즉, 포인터 자체를 증가시키는 대신 포인터가 AT를 가리키는 점을 증가시킵니다. 결과적으로 첫 번째 문자를 복사 한 다음 해당 문자를 증가시킨 다음 해당 문자가 0이 아니 었는지 확인하고 0이 될 때까지 계속합니다. 결과는 소스와 대상이 모두 빈 문자열이 될 것입니다 (두 문자열의 첫 문자가 이제는 0이되어 문자열을 종료하는 데 사용됩니다).