무분별한 if문을 정리하려 합니다.

sinta의 이미지

안녕하세요.

기존에 운영되고 있는 소스를 분석하며 개선할 수 있는 부분이 없는지 찾고 있던 중에
제 기준에선 수정이 필요한 if문을 보다 궁금증이 생겼습니다.

unsigned char caCase[2] 의 범위가 "80" ~ "89"일 경우 실행되는는 로직이 있는데

현재는 이렇게 구현되어 있습니다.

if ((memcmp(caCase, "80", 2) == 0) ||(memcmp(caCase, "81", 2) == 0) || ~ (memcmp(caCase, "89", 2) == 0))
{
실행
}

동작에는 이상이 없지만 코드가 조금 난잡(?)하다는 생각에 이렇게 바꾸려고 생각했습니다.

if (caCase[0] == 0x38 && (caCase[1] >= 0x30 && caCase[1] <= 0x39))
{
실행
}

바꿔서 테스트를 해보면 되겠지만..

1. 위의 코드보다 아래의 코드를 선택해야할 이유가 무엇일까?
- 단순히 아래의 코드가 더 간결하고 빠르겠거니 라고 짐작중입니다.
- 다수의 사람이 읽기에는 상단의 코드가 더 좋겠지만.. 뭔가 정리의 욕구를 불러일으키는 코드라고 생각해서..

2. 예외케이스는 없을까?
- 메모리를 비교하는 로직을 단순 아스키 코드비교로 바꾸는게 위험한 행동이 아닌지 걱정중입니다.

짧은 지식에 미처 고려하지 못한 부분이 있을지 도움을 부탁드립니다.

감사합니다.

seriously?!의 이미지

Quote:
다수의 사람이 읽기에는 상단의 코드가 더 좋겠지만..

정말로요?! "다수의 사람"은 어떨지 모르겠지만 저는 반댑니다. 80~89인지 테스트하기 위해서 memcmp 10번을, 그것도 직렬로 쭉 검사한다고요? 성능과 가독성 등 어떤 지표로 봐도 좋은 점을 못 찾겠는데요?

제시하신 개선안이 더 낫다고 생각합니다만, '8' 대신 0x38을 쓴다던가 하는 트릭이 아주 맘에 들지는 않는군요. 일단 (1)성능 얻는 거 없고 (2)이식성을 (알게 모르게) 깎아먹으며 (3) 가독성을 해칩니다.

그냥 이러면 안 되나요?

if (caCase[0] == '8' && ('0' <= caCase[1] && caCase[1] <= '9'))
{
    // 실행
}

혹은 이렇게 해 볼 수도 있겠죠.

if (caCase[0] == (unsigned char)'8' && isdigit(caCase[1])) // requires <ctype.h>
{
    // 실행
}

라스코니의 이미지

처음 if 문은 memcmp() 가 너무 불필요하게 중복으로 사용되네요.
저라면 아래와 같이 수정해 보겠습니다.

먼저 가정이 좀 필요한데
가정) caCase[0], caCase[1]이 가질 수 있는 값은 모두 '0' ~ '9' 중 하나이다.

그렇다면 caCase[0]이 '8' 이라는 것만 확인해도 됩니다.

if (!(caCase[0] ^ '8'))
{
실행
}

bitwise-op의 이미지

그와 같은 가정이 있다고 했을 때, if (caCase[0] == '8')이 아니라 if (!(caCase[0] ^ '8'))를 선택하신 건 개인 취향인가요, 아니면 어떤 공학적인 목적이 있었던 건가요?

전자라면 뭐 타인이 관여할 일은 아니겠습니다만, 후자라면 좀 더 자세히 알고 싶습니다.

라스코니의 이미지

그냥 취향입니다. 특히 어떤 값이 아니라 비트 패턴과 비교할 때는 이렇게 가끔 쓰거든요.
또 위에서 == 로 하셨기에 다른 걸로 하고 싶기도 했고요. 하긴 ^ (XOR) 하는 것은 가독성에 매우 좋지 않죠.

심심해서 XOR 했을 때 속도 향상이 있는지에 대한 글이 있는지 찾아 봤는데 그런 분석글은 잘 못찾겠네요. 한가진 흥미로운 글(http://www.codemaster.blog/2008/04/xor-vs.html)이 있었어요.

hsnks100의 이미지

        char sg[3];
	std::copy(&caCase[0], &caCase[2], sg);
	sg[2] = '\0';
	int i = std::stoi(sg);
	if(80 <= i && i <= 89) {
		cout << "true\n";
 
	}
	else{
		cout << "false\n";
 
	}

적어도 코드에서 노골적으로 80 <= a <= 89 라는 표현이 드러나야 한다고 생각합니다. 최적화 트릭을 쓰시려면 '18' 과 '98' 을 이용하는 트리키한 방법도 있습니다.

----------------------------------------------------
개인 블로그: https://kangssu.com

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.