Что делает оператор запятой?

@roens - это правильно. Это влияет на всех пользователей Anaconda, с ошибкой ниже curl: (77) error setting certificate verify locations: CAfile: /etc/pki/tls/certs/ca-bundle.crt CApath: none

. Обходной путь заключается в использовании зависания системы по умолчанию и избегании возиться с добавленной переменной Anaconda PATH. Вы можете либо

  1. Переименовать двоичный файл curl Anaconda :) mv /path/to/anaconda/bin/curl /path/to/anaconda/bin/curl_anaconda
  2. ИЛИ удалить Anaconda curl conda remove curl

$ which curl /usr/bin/curl

[0] Anaconda Ubuntu curl Github issue https://github.com/conda/conda-recipes/issues/352

145
задан Lundin 22 May 2017 в 07:00
поделиться

6 ответов

Выражение:

(expression1,  expression2)

Первый expression1 оценен, тогда expression2 оценен, и значение expression2 возвращается для целого выражения.

116
ответ дан lillq 22 May 2017 в 07:00
поделиться

Я видел, использовал больше всего в 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);
}
109
ответ дан phuclv 22 May 2017 в 07:00
поделиться

Оператор запятой комбинирует эти два выражения любая сторона его в один, оценивая их обоих в слева направо порядке. Значение правой стороны возвращается как значение целого выражения. (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 с или int с, мы сделали это:

*((short *)ptr)++ = short_value;
*((int *)ptr)++ = int_value;

Позже мы читаем, что это не было действительно допустимым C, потому что (short *)ptr больше не l-значение и не может быть увеличено, хотя наш компилятор в то время не возражал. Для фиксации этого мы разделяем выражение в два:

*(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 Код, Завершенный отговаривание от ровного использования операторов запятой в for цикл: для удобочитаемости и пригодности для обслуживания, циклом должны управлять только одна переменная и выражения в for, сама строка должна только содержать управляющий код цикла, не другие дополнительные биты обслуживания цикла или инициализации.

28
ответ дан Luis 22 May 2017 в 07:00
поделиться

Это вызывает оценку нескольких операторов, но использует только последний в качестве получающегося значения (rvalue, я думаю).

Так...

int f() { return 7; }
int g() { return 8; }

int x = (printf("assigning x"), f(), g() );

должен привести к x, устанавливаемому на 8.

8
ответ дан Ben Collins 22 May 2017 в 07:00
поделиться

Так же более ранние ответы указали, что это оценивает все операторы, но использует последний как значение выражения. Лично я только нашел его полезным в выражениях цикла:

for (tmp=0, i = MAX; i > 0; i--)
3
ответ дан DGentry 22 May 2017 в 07:00
поделиться
  • 1
    @kevingreen: необходимо было бы перезаписать целевой объект Ant и сделать это " manually". нет никакой автоматической функции для создания " fat" банка – a_horse_with_no_name 10 April 2012 в 17:16

Единственное место я видел, что он полезен, - когда Вы пишете броский цикл, где Вы хотите сделать несколько вещей в одном из выражений (вероятно, 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 и цикле будут более очевидными. (И я инициализировал бы i1 и i2, встроенный вместо того, чтобы объявить и затем инициализировать.... и тому подобное.)

2
ответ дан Owen 22 May 2017 в 07:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: