697

C에서 사용하는 것의 차이점은 무엇입니까?++ii++, 그리고 어떤 것의 증분 블록에서 사용되어야하는지for고리?


20 답변


878

  • ++i~의 값을 증가시킵니다.i, 증가 된 값을 리턴하십시오.

     i = 1;
     j = ++i;
     (i is 2, j is 2)
    
  • i++~의 값을 증가시킵니다.i, 원래 값을 반환합니다.i증분되기 전에 개최됩니다.

     i = 1;
     j = i++;
     (i is 2, j is 1)
    

를 위해for루프, 작동합니다.++i아마도 그것이 일반적으로 사용되는 이유 일 것입니다.K & R.

어떤 경우이든 가이드 라인 "prefer++i위에i++"너는 잘못하지 않을 것이다.

효율성에 대한 몇 가지 의견이 있습니다.++ii++. 모든 학생 프로젝트가 아닌 컴파일러에서는 성능 차이가 발생하지 않습니다. 동일한 코드가 생성 된 코드를 통해 확인할 수 있습니다.

효율성 질문은 흥미 롭습니다 ... 여기에 대한 대답은 내 시도입니다.C ++에서 +++와 +++ 사이에 성능 차이가 있습니까?

같이친구에게메모, 그것은 C + + 개체에 대한 다른 이후,operator++()함수이고 컴파일러는 중간 값을 보유하기 위해 임시 객체 생성을 최적화하는 것을 알 수 없습니다.


  • 루프가 종료 상태에 도달하면 루프가 다시 실행됩니다. 예를 들어,for(int i=0; i<10; i++){ print i; }이것이 다른 것보다for(int i=0; i<10; ++i){ print i; }내 이해는 일부 언어는 당신이 사용하는 것에 따라 다른 결과를 줄 것입니다. - jonnyflash
  • jonnyflash, i와 print의 증가가 다른 명령문에 있기 때문에 둘 다 동일하게 작동합니다. 이것은 C 스타일의 ++를 지원하는 모든 언어의 경우입니다. ++ i와 i ++의 유일한 차이는 동일한 명령문에서 연산의 값을 사용할 때입니다. - Mark Harrison
  • 대부분의 경우 동일한 코드를 생성하기 때문에i++operand-operator "형식이므로"operand-operator-value "라는 할당이 필요합니다. 즉, 대상 피연산자는 대입 문과 마찬가지로 표현식의 왼쪽에 있습니다. - David R Tribble
  • @ARUNi++값을 증가시키고 값으로 eval을 의미합니다.사전의증분. 그것은 증가가 일어날 때가 아니라 평가 결과 자체입니다. 사전 증가 평가 결과는 증가 이후이며, 증가 후 평가 결과는 증가 앞에 있지만, 평가 결과가 생성되기 전에 증가가 발생하더라도 상관 없습니다유효한.실제 예제보기많은 것을 보여줍니다. - WhozCraig
  • @sam 왜냐하면 일반적인 for 루프에서는 ++ i 부분에 부작용 (예 : 할당)이 없기 때문입니다. - Mark Harrison

146

나는 ++라고합니다.게시물 증가이므로++ i불렀다.사전 증가.

i++

i++증가하기 때문에 게시물 증가분입니다.i작업이 끝난 후 값이 1 씩 증가합니다.

다음 예제를 보자 :

int i = 1, j;
j = i++;

여기의 가치j = 1그러나i = 2. 여기의 가치i에 배정됩니다.j우선i증분됩니다.

++i

++i증가하기 때문에 사전 증가i작업 전에 값을 1 씩 증가시킵니다. 그 뜻은j = i;~ 후에 실행됩니다.i++.

다음 예제를 보자 :

int i = 1, j;
j = ++i;

여기의 가치j = 2그러나i = 2. 여기의 가치i에 배정됩니다.ji증분i. 비슷하게++i전에 실행됩니다.j=i;.

귀하의 질문에for 루프의 증분 블록에서 사용해야합니까?대답은, 당신이 사용할 수있는 하나 .. 상관 없어. 그것은 for 루프와 동일한 no를 실행합니다. 시대의.

for(i=0; i<5; i++)
   printf("%d ",i);

for(i=0; i<5; ++i)
   printf("%d ",i);

두 루프 모두 동일한 출력을 생성합니다. 즉0 1 2 3 4.

당신이 그것을 사용하고있는 곳에서만 중요합니다.

for(i = 0; i<5;)
    printf("%d ",++i);

이 경우 출력은1 2 3 4 5.


  • 접두어와 수정 후 변수를 초기화하면 이해하는 데 도움이됩니다. 감사. - Abdul Alim Shakir

32

제발 빨리 "효율성"(속도, 정말로)에 대해 걱정하지 마십시오. 우리는 요즘 컴파일러를 가지고 이런 일들을 처리합니다. 어느 것이 든 사용하기에 합당한 것을 사용하십시오.


  • 나는 희망한다.(inc | dec) 이전에 이전 값이 실제로 필요하지 않는 한 접두사 (inc | dec) rement를 사용합니다. 그러나 소수의 사람이하는 일이지만 예상되는 교재의 어지러운 부분이 사용되어 후위 사용자의화물 컬트를 만듭니다. 무엇인지 알지 못한다.&..!! - underscore_d

27

++i값을 증가시키고 리턴합니다.

i++값을 반환 한 다음 값을 증가시킵니다.

그것은 미묘한 차이입니다.

for 루프의 경우 다음을 사용하십시오.++i약간 더 빨라서.i++방금 버려진 여분의 복사본을 만듭니다.


  • 나는 그것이 적어도 정수에 차이를 만드는 어떤 컴파일러에 대해서도 알지 못한다. - blabla999
  • 그것은빠르지 않다. 값은 무시되고 (부작용 만 효과적 임) 컴파일러는 정확히 동일한 코드를 생성 할 수 있습니다. - wildplasser

20

i ++ : -이 시나리오에서는 먼저 값이 할당 된 다음 증분이 발생합니다.

++ i : -이 시나리오에서는 먼저 증분이 수행 된 후 값이 할당됩니다

아래는 이미지 시각화이며 여기에는 멋진 실용 비디오 (http://www.youtube.com/watch?v=lrtcfgbUXm4) 같은 것을 보여줍니다.

enter image description here


19

이유++i 양철통~보다 약간 빠름i++그것입니다.i++증가하기 전에 i 값의 로컬 사본을 요구할 수 있습니다.++i결코하지 않습니다. 경우에 따라 가능한 경우 일부 컴파일러가이를 최적화합니다 ...하지만 항상 가능한 것은 아니며 모든 컴파일러가이를 수행하는 것은 아닙니다.

나는 컴파일러 최적화에 너무 의존하지 않으려 고 Ryan Fox의 조언을 따르겠습니다 : 둘 다 사용할 수있을 때,++i.


  • -1 C ++에 대한 C의 답. 더 이상의 " 로컬 사본 "이 없습니다. 가치의i문을 쓸 때 값이 1보다 큽니다.1;. - R..
  • @R .. 이유를 설명하거나 소스를 연결하십시오. - Teejay
  • @R .. 이유를 설명해주세요. - PerelMan
  • @MarwanB :이 질문은 실제로 FAQ이며 스택 오버플로를 사용하는 방법이 아닌 다른 질문에 대한 거의 10 년 된 답변에 대한 자세한 답변을 묻습니다. 상세한 답변을 원할 경우 새로운 질문을 올리십시오 (아마도이 답변 / 코멘트를 인용 할 수 있음). 그러나이 질문에 이미 답변 해 놓은 많은 질문 중 하나의 중복으로 닫힐 가능성이 높습니다. - R..

11

둘 중 하나를 사용하여 얻은 결과는 동일합니다. 즉, 루프는 두 인스턴스에서 똑같은 작업을 수행합니다.

효율면에서 i ++ ++ i를 선택할 때 벌금이 부과 될 수 있습니다. 언어 사양 측면에서 사후 증가 연산자를 사용하면 연산자가 작동하는 값의 추가 복사본을 만들어야합니다. 이것은 추가 작업의 원천이 될 수 있습니다.

그러나 이전 논리에 대한 두 가지 주요 문제점을 고려해야합니다.

  1. 최신 컴파일러는 훌륭합니다. 좋은 컴파일러는 for 루프에서 정수 증가분을보고 있다는 것을 깨닫기에 충분히 똑똑하고 두 방법 모두를 동일한 효율적인 코드로 최적화합니다. 사전 증가보다 후 증가를 사용하면 실제로 프로그램의 실행 시간이 더 느려지므로무서운컴파일러.

  2. 운영 시간 복잡성의 측면에서 볼 때 두 가지 방법 (사본이 실제로 수행 되더라도)은 동일합니다. 루프 내부에서 수행되는 명령어의 수는 증가 연산의 연산 수를 크게 좌우해야합니다. 따라서 상당한 크기의 루프에서 증가 메서드의 페널티는 루프 본문 실행으로 인해 크게 어둡습니다. 즉, 증가가 아닌 루프에서 코드를 최적화하는 것에 대해 걱정하지 않는 것이 좋습니다.

제 의견으로는 전체적인 이슈는 단순히 스타일 선호에 달려 있습니다. 사전 증가가 더 읽기 쉽다고 생각되면 사용하십시오. 개인적으로, 나는 후반 평가를 선호하지만 그것은 아마도 내가 최적화에 대해 알기 전에 내가 배웠던 것이었기 때문일 것이다.

이는 조숙 한 최적화의 전형적인 예이며 이와 같은 문제는 설계상의 심각한 문제에서 우리를 혼란스럽게 할 가능성이 있습니다. 그러나 "모범 사례"에 사용이나 합의가 일치하지 않기 때문에 여전히 질문하는 것이 좋습니다.


8

둘 다 번호를 증가시킵니다. ++ i는 i = i + 1과 동일합니다.

나는 ++와 ++가 매우 유사하지만 똑같은 것은 아닙니다. 둘 다 숫자를 증가 시키지만 +++는 현재 표현식이 평가되기 전에 숫자를 증가시키는 반면, i ++은 표현식이 평가 된 후에 숫자를 증가시킵니다.

예 :

int i = 1;
int x = i++; //x is 1, i is 2
int y = ++i; //y is 3, i is 3


4

++ i는 사전 증분이고 다른 하나는 사후 증분입니다.

i ++ : 요소를 가져 와서 증가시킵니다.

++ i : i를 증가시킨 다음 요소를 반환합니다.

예:

int i = 0;
printf("i: %d\n", i);
printf("i++: %d\n", i++);
printf("++i: %d\n", ++i);

산출:

i: 0
i++: 0
++i: 2


4

++ i (접두사 연산) : 값을 증가시킨 다음 할당합니다.

(예 :) : int i = 5, int b = ++ i

이 경우 6이 먼저 b에 할당 된 다음 7로 증가합니다.

i ++ (Postfix 작업) : 값을 할당 한 다음 증분합니다.

(예 :) : int i = 5, int b = i ++

이 경우 5가 먼저 b에 할당 된 다음 6으로 증가합니다.

Incase of for loop : i ++은 주로 for 루프를 시작하기 전에 i의 시작 값을 사용하기 때문에 주로 사용됩니다. 그러나 프로그램 논리에 따라 다를 수 있습니다.


3

나는 의미론의 차이를 이해한다고 가정한다. (솔직히 왜 사람들은 '연산자 X가 의미하는 바는 무엇인가'라는 질문에 읽기보다 스택 오버플로에 대한 질문을하고, 당신도 알다시피, 책이나 웹 튜토리얼이나 뭐.

그러나 어쨌든, 어느 것이 사용되는지에 관해서는 성능에 관한 질문을 무시합니다. C ++에서도 중요하지는 않습니다. 결정할 때 사용해야하는 원칙입니다. 사용할 것이다 :

코드에서 무엇을 의미하는지 말해보세요.

계산서에 증분 전 값이 필요하지 않으면 해당 형식의 연산자를 사용하지 마십시오. 사소한 문제지만, 스타일 가이드로 작업하지 않는 한 다른 버전 (뼈 모양의 스타일 가이드라고도 함)에 찬성하여 당신이하려고하는 것을 가장 정확하게 표현하는 형식.

QED, 사전 증가 버전 사용 :

for (int i = 0; i != X; ++i) ...


3

차이점은 아래의 간단한 C ++ 코드에서 이해할 수 있습니다.

int i, j, k, l;
i = 1; //initialize int i with 1
j = i+1; //add 1 with i and set that as the value of j. i is still 1
k = i++; //k gets the current value of i, after that i is incremented. So here i is 2, but k is 1
l = ++i; // i is incremented first and then returned. So the value of i is 3 and so does l.
cout << i << ' ' << j << ' ' << k << ' '<< l << endl;
return 0;


3

주요 차이점은

  • 나는 ++ 포스트 (증분 후) 및
  • ++ i Pre (증가 전)

    • 게시물 ifi =1루프가 증가한다.1,2,3,4,n
    • 사전 ifi =1루프가 증가한다.2,3,4,5,n


2

곧 : ++ i와 i ++는 함수에 쓰지 않는 한 동일하게 작동합니다. 함수 (i ++) 나 함수 (++ i)와 같은 것을 사용하면 그 차이를 볼 수 있습니다.

함수 (++ i)는 i를 1 씩 증가시킨 다음이 값을 새로운 값으로 함수에 넣습니다.

함수 (i ++)는 i를 1 씩 증가시킨 후 처음으로 함수를 넣는다 고 말합니다.

int i=4;
printf("%d\n",pow(++i,2));//it prints 25 and i is 5 now
i=4;
printf("%d",pow(i++,2));//it prints 16 i is 5 now


  • 차이점은 실제로 함수 호출과 관련이 없습니다 (함수 호출을 작성하지 않고도 그 차이를 발견 할 수 있습니다). 차이점은 무엇입니까?int j = ++i;int k = i++;함수 호출이없는 경우에도 마찬가지입니다. - Jonathan Leffler

2

Pre-crement는 동일한 라인에서 증분을 의미합니다. 후행 증가는 행이 실행 된 후 증분을 의미합니다.

int j=0;
System.out.println(j); //0
System.out.println(j++); //0. post-increment. It means after this line executes j increments.

int k=0;
System.out.println(k); //0
System.out.println(++k); //1. pre increment. It means it increments first and then the line executes

그것이 OR, AND 연산자와 함께 제공되면 더욱 흥미로워집니다.

int m=0;
if((m == 0 || m++ == 0) && (m++ == 1)) { //false
/* in OR condition if first line is already true then compiler doesn't check the rest. It is technique of compiler optimization */
System.out.println("post-increment "+m);
}

int n=0;
if((n == 0 || n++ == 0) && (++n == 1)) { //true
System.out.println("pre-increment "+n); //1
}

배열

        System.out.println("In Array");
        int[] a = { 55, 11, 15, 20, 25 } ;
        int ii, jj, kk = 1, mm;
        ii = ++a[1]; // ii = 12. a[1] = a[1] + 1
        System.out.println(a[1]); //12

        jj = a[1]++; //12
        System.out.println(a[1]); //a[1] = 13

        mm = a[1];//13
        System.out.printf ( "\n%d %d %d\n", ii, jj, mm ) ; //12, 12, 13

        for (int val: a) {
            System.out.print(" " +val); //55, 13, 15, 20, 25
        }

포인터 변수의 C ++ 포스트 / 사전 증가

#include <iostream>
using namespace std;

int main() {

    int x=10;
    int* p = &x;

    std::cout<<"address = "<<p<<"\n"; //prints address of x
    std::cout<<"address = "<<p<<"\n"; //prints (address of x) + sizeof(int)
    std::cout<<"address = "<<&x<<"\n"; //prints address of x

    std::cout<<"address = "<<++&x<<"\n"; //error. reference can't re-assign because it is fixed (immutable)
}


2

다음 C 코드 조각은 사전 및 사후 증가 연산자와 감소 연산자의 차이점을 보여줍니다.

int i; int j;

// 연산자를 증가시킵니다.

i = 1;

j = ++ i; // i는 2, j는 2입니다.

j = i ++; // 나는 지금 3, j는 2이다.


2

나는 ++와 ++ i

이 작은 코드는 이미 게시 된 답변과 다른 각도의 차이를 시각화하는 데 도움이 될 수 있습니다.

int i = 10, j = 10;

  printf ("i is %i \n", i);
  printf ("i++ is %i \n", i++);
  printf ("i is %i \n\n", i);

  printf ("j is %i \n", j);
  printf ("++j is %i \n", ++j);
  printf ("j is %i \n", j);

결과는 다음과 같습니다.

//Remember that the values are i = 10, and j = 10

i is 10 
i++ is 10     //Assigns (print out), then increments
i is 11 

j is 10 
++j is 11    //Increments, then assigns (print out)
j is 11 

전후 상황에주의하십시오.

for 루프

어떤 루프가 for 루프의 증가 블록에서 사용되어야하는지에 관해서는, 나는 우리가 결정을 내리기 위해 할 수있는 최선의 방법이 좋은 예라고 생각한다 :

int i, j;

For (i = 0; i <= 3; i++)
    printf (" > iteration #%i", i);

printf ("\n");

for (j = 0; j <= 3; ++j)
    printf (" > iteration #%i", j);

결과는 다음과 같습니다.

> iteration #0 > iteration #1 > iteration #2 > iteration #3
> iteration #0 > iteration #1 > iteration #2 > iteration #3 

나는 너를 모른다. 적어도 for 루프에서는 사용법에 어떤 변화도 없다.


-1

당신은 그것의 내부 변환을 생각할 수 있습니다.여러 문장;

// case 1 :

i++;

/* you can think as,
 * i;
 * i= i+1;
 */

// case 2

++i;

/* you can think as,
 * i = i+i;
 * i;
 */


-3

a = i ++는 a가 전류 i 값을 포함한다는 것을 의미합니다. a = ++ i는 증가 된 i 값을 포함하는 것을 의미합니다.


  • 이 대답은 정확하지 않습니다.a = i++;에 저장된 값을 의미합니다.a의 가치가 될 것이다.i증가하지 않고 ' 증가하지 않고 ' 그 의미i증가하지 않습니다. 이것은 완전히 잘못되었습니다.i가 증가하지만 표현식의 값은 증가하기 전의 값입니다. - Jonathan Leffler

-5

차이점을 이해하는 예제가 있습니다.

int i=10;
printf("%d %d",i++,++i);

산출:10 12/11 11(인수에 대한 평가 순서에 따라printf함수, 컴파일러 및 아키텍처에 따라 다름)

설명:i++->i인쇄 된 다음 증가합니다. (인쇄 10,하지만i11)++i->i값이 증가하고 값이 인쇄됩니다. (인쇄물 12,i또한 12)


  • 사이에 시퀀스 포인트가 없으므로 정의되지 않은 동작이 발생합니다.i++++i - M.M
  • @ Lundin은 정확하다. LHS, 쉼표의 RHS는 그들 사이의 시퀀스 포인트를 가지고 있지만 2 개의 표현식은 서로 순서가 정해지지 않았다. - Antti Haapala

연결된 질문


관련된 질문

최근 질문