что именно составляет условное утверждение в Цели С? - PullRequest
2 голосов
/ 13 июля 2011

Я читал книгу Learn Objective C на Mac, , и я искал этот фрагмент кода:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    NSFileManager *manager;
    manager = [NSFileManager defaultManager];

    NSString *home;
    home = [@"~" stringByExpandingTildeInPath];

    NSDirectoryEnumerator *direnum;
    direnum = [manager enumeratorAtPath: home];

    NSMutableArray *files;
    files = [NSMutableArray arrayWithCapacity: 42];

    // “Slow” enumeration
    NSString *filename;
    while ( filename = [direnum nextObject] )
    {
            if ([[filename pathExtension] isEqualTo: @”jpg”])
            {
                    [files addObject: filename];
            } // end if
    } // end while


    NSEnumerator *filenum;
    filenum = [files objectEnumerator];

    while ( filename = [filenum nextObject] )
    {
            NSLog(@”%@”, filename);
    }

[pool drain];
return 0;
} // main

что выделилось для меня было while ( filename = [filenum nextObject] ), и я подумал: «Как это на самом деле условное утверждение?» Я полагаю, что вызов [filenum nextObject] является строкой NSS с именем файла или nil , но как мы можем выполнить filename =, пока мы оцениваем это? Можете ли вы указать мне правильную документацию, которая более четко объясняет, что здесь возможно?

Ответы [ 5 ]

3 голосов
/ 13 июля 2011

Это на самом деле особенность C. Оператор while принимает выражение наподобие оператора if, а присваивание является допустимым выражением.В этом файле грамматики C вы можете видеть следующее:

IF '(' expression ')' statement

, а также

WHILE '(' expression ')' statement

Пока результат выражения не равен нулю,условие будет верным.Значение nil равно 0 и приведет к сбою условия.Как только перечислитель завершится, nextObject вернет nil и условие не выполнится.Тем не менее, при выполнении задания в качестве условного выражения рекомендуется заключать его в скобки, чтобы указать свои намерения.

while ( (filename = [direnum nextObject]) )
2 голосов
/ 13 июля 2011

while ( filename = [filenum nextObject] )

Этот оператор сложен и выполняет несколько операций.

  1. [filenum nextObject] метод вызывается и возвращает NSString
  2. filename = присваивается адрес строки NSSt
  3. значение filename оценивается как условие для while ( ... ) работа

Как вы указали, если возвращаемое значение равно nil, тогда имя файла равно nil, и условие оценивается как ложное, иначе имя файла не равно нулю, а условие оценивается как истинное.

Многим программистам не нравится этот синтаксис. Это кратко и может быть трудно поддерживать. Компиляторы сгенерируют предупреждение, чтобы обозначить общую синтаксическую ошибку, когда разработчик действительно намерен сравнить два значения,

while ( filename == [filenum nextObject] )

Было бы чище написать исходное утверждение как

while ( (filename = [filenum nextObject]) != nil )

Этот оператор будет вести себя так же, как и оригинал, но устраняет неоднозначность присваивания и условных операций.

2 голосов
/ 13 июля 2011

Это условный оператор, поскольку каждое присваивание имеет значение, которое является значением справа, назначенным переменной слева. В этом случае конечное значение оказывается либо действительным NSString объектом, либо nil. Пока nil представляет «ничто», условие интерпретируется как ложное, в противном случае оно истинно.

1 голос
/ 13 июля 2011

Вы подняли хороший вопрос.Рассмотрим код

while ( obj = [enumerator nextObject] ) {
    printf( "%s\n", [[obj description] cString] );
}

Причина, по которой работает while ( obj = [array objectEnumerator] ), заключается в том, что objectEnumerator возвращает nil для последнего объекта.Поскольку в C nil обычно 0, это то же самое, что и false.( ( obj = [array objectEnumerator] ) != nil ) может быть предпочтительнее

Источник: Нажмите на эту ссылку !

В вашем случае, ((filename = [direnum nextObject]) ) - это еще один способ избежать ошибок компиляции.

0 голосов
/ 13 июля 2011

Выражение

(file = [filenum nextObject])

Будет выполняться каждый раз в цикле.После того, как оно выполнено, оно вычисляется как логическое условие для оператора if

Это то же самое, что и нормальный оператор, такой как

x = 13 * 4;

Все справа от равенства выполняется, а затемон присваивается переменной х.

...