Как можно улучшить эти функции преобразования дел? - PullRequest
16 голосов
/ 07 октября 2010

В качестве учебного упражнения мои три функции - ToggleCase, LowerCase и UpperCase - каждая ожидает указатель на строку символов ASCII, оканчивающуюся нулевым символом; они работают как положено. Существуют ли более эффективные или более быстрые методы решения этой задачи? Я нарушаю какие-либо невысказанные правила хорошего C-кодирования? Я использовал макросы, потому что, я думаю, он делает код лучше и эффективнее вызовов функций. Это типично или излишне?

Пожалуйста, не стесняйтесь придираться и критиковать код (но будьте добры).

case_conversion.h

#define CASE_FLAG 32
#define a_z(c) (c >= 'a' && c <= 'z')
#define A_Z(c) (c >= 'A' && c <= 'Z')

void ToggleCase(char* c);
void LowerCase(char* c);
void UpperCase(char* c);

case_conversion.c

#include "case_conversion.h"

void ToggleCase(char* c)
{
 while (*c)
 {
  *c ^= a_z(*c) || A_Z(*c) ? CASE_FLAG : 0;
  c++;
 }
}
void LowerCase(char* c)
{
 while (*c)
 {
  *c ^= A_Z(*c) ? CASE_FLAG : 0;
  c++;
 }
}
void UpperCase(char* c)
{
 while (*c)
 {
  *c ^= a_z(*c) ? CASE_FLAG : 0;
  c++;
 }
}

Ответы [ 12 ]

0 голосов
/ 07 октября 2010

как насчет (почти работает):

char slot[] = { 0, 31, 63, 63 };
*c = slot[*c/32] + *c%32;

Пара вещей, которые вы можете изменить:

*c += a_z(*c)*CASE_FLAG; // adds either zero or three two
// you could also replace multiplication with the shift (1<<5) trick

строки на самом деле являются массивами:

char upper[] = "ABC..ABC..."; // 
...
*c = upper[*c+offset];

или

char upper[] = "ABC.."; // 
...
*c = upper[*c%32];

или

*c = 'A' + *c%32;

или что угодно ...

0 голосов
/ 07 октября 2010

Во-первых, я бы сказал, что переименуйте a_z и A_Z в что-то вроде is_ASCII_Lowercase и is_ASCII_Uppercase.Это не C-ish, но его легче понять.

Кроме того, использование ^= и ?: работает, но, опять же, я считаю его менее читабельным, чем простое if утверждение.

...