뭐라고합니까 ,
연산자는 C에서 무엇입니까?
뭐라고합니까 ,
연산자는 C에서 무엇입니까?
답변:
표현식:
(expression1, expression2)
먼저 expression1을 평가 한 다음 expression2를 평가하고 전체 표현식에 대해 expression2의 값을 리턴합니다.
i
5, 4, 3, 2 또는 1의 값을 가지지 않습니다 . 단순히 0입니다. 표현식에 부작용이 없으면 실제로는 쓸모가 없습니다.
i = b, c;
(i = b), c
할당 =
이 쉼표 연산자보다 우선 순위가 높기 때문에 이는 동등합니다 ,
. 쉼표 연산자는 우선 순위가 가장 낮습니다.
expression1, expression2;
첫 번째 expression1
는 아마도 그 부작용 (예 : 함수 호출)에 대해 expression2
평가 된 후, 시퀀스 포인트가 있고, 평가되고 값이 반환됩니다.
while
루프 에서 가장 많이 사용되는 것을 보았습니다 .
string s;
while(read_string(s), s.len() > 5)
{
//do something
}
작업을 수행 한 다음 부작용을 기반으로 테스트를 수행합니다. 다른 방법은 다음과 같이하는 것입니다.
string s;
read_string(s);
while(s.len() > 5)
{
//do something
read_string(s);
}
while (read_string(s) && s.len() > 5)
. read_string
반환 값이 없거나 의미있는 값 이 없으면 분명히 작동 하지 않습니다. (편집 : 죄송합니다,이 게시물이 몇 살인지는 눈치 채지 못했습니다.)
while (1)
하는 것을 두려워하지 마십시오 break;
. 코드의 브레이크 아웃 부분을 while 테스트 또는 do-while 테스트로 강제 실행하는 것은 종종 에너지 낭비이며 코드를 이해하기 어렵게 만듭니다.
while(1)
와 break
;
콤마 연산자 왼쪽 피연산자를 평가하게는, 그 결과를 폐기하고 오른쪽 피연산자를 평가하고 그 결과가 될 것이다. 관용적 (A)에 사용되는 변수를 초기화 할 때 링크에서 언급 된 사용은 for
루프 및 그 다음의 예이다 :
void rev(char *s, size_t len)
{
char *first;
for ( first = s, s += len - 1; s >= first; --s)
/*^^^^^^^^^^^^^^^^^^^^^^^*/
putchar(*s);
}
그렇지 않으면하지 많습니다 위대한 의 사용 쉼표 연산자는 그것을 읽고 유지하기 어려운 코드를 생성 할 수 남용이 용이하지만,.
로부터 초안 C99 표준에 다음과 같이 문법은 다음과 같습니다
expression:
assignment-expression
expression , assignment-expression
단락 2 는 다음 과 같이 말합니다.
쉼표 연산자 의 왼쪽 피연산자는 void 표현식으로 평가됩니다. 평가 후 시퀀스 포인트가 있습니다. 그런 다음 올바른 피연산자가 평가됩니다. 결과 유형과 값이 있습니다. 97) 쉼표 연산자의 결과를 수정하거나 다음 시퀀스 포인트 이후에 액세스하려고하면 동작이 정의되지 않습니다.
각주 97의 말 :
쉼표 연산자는 lvalue를 생성 하지 않습니다 .
이는 쉼표 연산자 의 결과에 할당 할 수 없음을 의미합니다 .
쉼표 연산자가 우선 순위 가 가장 낮 으므로 사용 ()
이 큰 차이를 만들 수있는 경우가 있습니다. 예를 들면 다음과 같습니다.
#include <stdio.h>
int main()
{
int x, y ;
x = 1, 2 ;
y = (3,4) ;
printf( "%d %d\n", x, y ) ;
}
다음과 같은 출력이 나타납니다.
1 4
쉼표 연산자는 두 표현식을 한쪽으로 결합하여 왼쪽에서 오른쪽 순서로 평가합니다. 오른쪽의 값은 전체 표현식의 값으로 반환됩니다.
(expr1, expr2)
비슷 { expr1; expr2; }
하지만 당신의 결과를 사용할 수있는 expr2
함수 호출 또는 할당에.
다음 for
과 같이 여러 변수를 초기화하거나 유지하기 위해 종종 루프에서 볼 수 있습니다 .
for (low = 0, high = MAXSIZE; low < high; low = newlow, high = newhigh)
{
/* do something with low and high and put new values
in newlow and newhigh */
}
이와는 별도로, 나는 항상 매크로에서 함께 진행해야하는 두 가지 작업을 마무리 할 때 다른 경우에는 "분노한"경우에만 사용했습니다. 우리는 네트워크에서 전송하기 위해 다양한 이진 값을 바이트 버퍼에 복사하는 코드가 있었고 포인터는 다음과 같은 위치에 유지되었습니다.
unsigned char outbuff[BUFFSIZE];
unsigned char *ptr = outbuff;
*ptr++ = first_byte_value;
*ptr++ = second_byte_value;
send_buff(outbuff, (int)(ptr - outbuff));
값이 short
s 또는 int
s 인 경우 다음을 수행했습니다.
*((short *)ptr)++ = short_value;
*((int *)ptr)++ = int_value;
나중에 우리 (short *)ptr
는 컴파일러가 신경 쓰지 않았지만 더 이상 l 값이 아니고 증가 할 수 없기 때문에 이것이 실제로 유효한 C가 아니라는 것을 읽었습니다 . 이 문제를 해결하기 위해 표현식을 두 가지로 나눕니다.
*(short *)ptr = short_value;
ptr += sizeof(short);
그러나이 접근법은 항상 두 진술을 모두 기억하는 모든 개발자에게 의존했습니다. 출력 포인터, 값 및 값 유형을 전달할 수있는 함수가 필요했습니다. 이것은 템플릿이있는 C ++이 아닌 C이므로 함수는 임의의 유형을 취할 수 없으므로 매크로를 설정했습니다.
#define ASSIGN_INCR(p, val, type) ((*((type) *)(p) = (val)), (p) += sizeof(type))
쉼표 연산자를 사용하여 원하는대로 표현식이나 명령문으로 사용할 수있었습니다.
if (need_to_output_short)
ASSIGN_INCR(ptr, short_value, short);
latest_pos = ASSIGN_INCR(ptr, int_value, int);
send_buff(outbuff, (int)(ASSIGN_INCR(ptr, last_value, int) - outbuff));
나는이 예제 중 어느 것이 좋은 스타일인지 제안하지 않습니다! 실제로 Steve McConnell의 Code Complete 는 for
루프 에서 쉼표 연산자를 사용하는 것에 대해서도 조언 하는 것을 기억 합니다. 가독성 및 유지 관리 성을 위해 루프는 하나의 변수로만 제어되어야하며 for
행 자체 의 표현식 에는 루프 제어 코드 만 포함되어야합니다. 다른 여분의 초기화 또는 루프 유지 보수가 아닙니다.
내가 유용하다고 생각한 유일한 장소는 표현식 중 하나 (아마도 init 표현식 또는 루프 표현식)에서 여러 가지 작업을 수행하려는 펑키 루프를 작성할 때입니다.
bool arraysAreMirrored(int a1[], int a2[], size_t size)
{
size_t i1, i2;
for(i1 = 0, i2 = size - 1; i1 < size; i1++, i2--)
{
if(a1[i1] != a2[i2])
{
return false;
}
}
return true;
}
구문 오류가 있거나 엄격한 C가 아닌 것을 혼합 한 경우 용서하십시오. 나는 연산자가 좋은 형식이라고 주장하지는 않지만 그것을 사용할 수 있습니다. 위의 경우 아마도 while
루프를 대신 사용하므로 init 및 loop의 여러 표현식이 더 분명합니다. (그리고 선언하고 초기화하는 대신 i1 및 i2 인라인을 초기화했습니다 .... blah blah blah.)
나는 이것이 @Rajesh와 @JeffMercado의 질문을 해결하기 위해 단순히 이것을 부활시키고 있습니다. 이것이 최고의 검색 엔진 히트 중 하나이기 때문에 매우 중요하다고 생각합니다.
예를 들어 다음 코드 스 니펫을 사용하십시오.
int i = (5,4,3,2,1);
int j;
j = 5,4,3,2,1;
printf("%d %d\n", i , j);
인쇄합니다
1 5
이 i
사례는 대부분의 답변에서 설명한대로 처리됩니다. 모든 표현식은 왼쪽에서 오른쪽 순서로 평가되지만 마지막 표현식 만에 지정됩니다 i
. (
식 ) is
1` 의 결과 .
j
보낸 경우에는 다른 우선 순위 규칙을 따르는 ,
최저 연산자 우선 순위를 갖는다. 이러한 규칙으로 인해 컴파일러는 assignment-expression, constant, constant ...를 보게 됩니다 . 식은 다시 순서로 왼쪽에서 오른쪽 및 그 부작용이 항상 표시 따라서 평가되고 j
있다 5
의 결과 j = 5
.
간혹 int j = 5,4,3,2,1;
언어 사양에서 허용되지 않습니다. 초기화는 기대 할당 표현 직접적인 있도록 ,
운영자가 허용되지 않습니다.
도움이 되었기를 바랍니다.