LINUX.ORG.RU

Проверка большого числа условий на си

 


2

2

Сейчас я пишу такой код:

	if( phonebookEntry->index < 0 && phonebookEntry->telNo && !phonebookEntry->name ){
		//только телефон
	}else if( phonebookEntry->index < 0 && phonebookEntry->telNo && phonebookEntry->name ){
		//телефон и имя
	}else if( phonebookEntry->index >= 0 && !phonebookEntry->telNo && !phonebookEntry->name ){
		//только индекс
	}else if( phonebookEntry->index >= 0 && phonebookEntry->telNo && !phonebookEntry->name ){
		//индекс и телефон
	}else if( phonebookEntry->index >= 0 && phonebookEntry->telNo && phonebookEntry->name ){
		//индекс, телефон и имя
	}else{
		//недопустимое сочетание
	}

И я заметил, что в каждом условном операторе сразу проверяется случая и подумал, а что если поступить вот так:

	unsigned int condition = 0;
	
	if( phonebookEntry->index >= 0 ) condition |= 1;
	if( phonebookEntry->telNo      ) condition |= 1 << 1;
	if( phonebookEntry->name       ) condition |= 1 << 2;

И дальше переменную condition запихнуть в switch или вообще использовать в качестве индекса в массиве указателей? Мой случай ещё пограничный, но если добавить ещё один параметр, то вариантов уже будет 16! Короче, степень двойки. Я один такой упоротый или такое где-нибудь применяется?

★★★
Ответ на: комментарий от bugfixer

Приводил выше. Лучше вы при всём желании не сделаете

Ещё было бы интересно посмотреть результат оптимизации компилятора, который используется для микропроцессоров.

anonymous
()
Ответ на: комментарий от anonymous
Оптимизация для

        }else if( phonebookEntry->index >= 0 && phonebookEntry->telNo && !phonebookEntry->name ){
                //индекс и телефон
        }else if( phonebookEntry->index >= 0 && phonebookEntry->telNo && phonebookEntry->name ){
                //индекс, телефон и имя


if( phonebookEntry->index >= 0 && phonebookEntry->telNo ) {

 if ( !phonebookEntry->name ) 
  индекс и телефон
 else 
  индекс, телефон и имя

}
anonymous
()
Ответ на: комментарий от anonymous

Немного о читабельности кода

if ( phonebookEntry->index < 0  && phonebookEntry->telNo  && !phonebookEntry->name ) {
//только телефон

} else 
if ( phonebookEntry->index < 0  && phonebookEntry->telNo  && phonebookEntry->name ) {
//телефон и имя

} else
if ( phonebookEntry->index >= 0 && !phonebookEntry->telNo && !phonebookEntry->name ) {
//только индекс

} else 
if ( phonebookEntry->index >= 0 && phonebookEntry->telNo  && !phonebookEntry->name ) {
//индекс и телефон

} else
if ( phonebookEntry->index >= 0 && phonebookEntry->telNo  && phonebookEntry->name ) {
//индекс, телефон и имя

} else{
//недопустимое сочетание
}
anonymous
()
Ответ на: комментарий от yars068

нужно писатьbreak;

Это понятно, речь то шла об использовании меток при преобразовании в ассемблер.

Грубо говоря, если мы положили яблоко на стол и потом подносим к нему другие яблоки и сравниваем то создаётся ощущение что первое сравниваемое яблоко ложится 1 раз, а другие подносим, вроде как экономнее, чем каждый раз подносить по два яблока, как в условии else ifгде нужно каждый раз указывать обе переменные. Но на самом деле это кажущаяся экономия, в ассемблере это всё равно будут прыжки между метками и сравнение обоих переменных, там нет switch.

AZJIO
()

На мой взгляд, если дать битовым маскам внутри свитча нормально читаемые названия, то код будет лучше, чем пачка условий в else if’ах. И лучше, и читаемее.

Но это если не оставлять в метках месиво из 0 и 1 и всё через enum’ы использовать, чтобы не надо было туда-сюда прыгать, чтобы понять, что происходит.

Ivan_qrt ★★★★★
()