C (또는 일반적으로 절차 적 프로그래밍)를위한 디자인 원칙, 모범 사례 및 디자인 패턴? [닫은]


91

C 프로젝트를 설계하는 동안 따를 수있는 알려진 설계 원칙, 모범 사례 및 설계 패턴이 있습니까? 아니면 일반적으로 절차 적 (명령 적) 프로그래밍에 유용한 설계 원칙이 있습니까?

(저는 '객체 지향 세대'의 자식이며 처음으로 대규모 C 프로젝트를 설계해야합니다.)


1
당신은이 질문에 anwsers에 관심이있을 수 있습니다 : stackoverflow.com/questions/661307/...
mouviciel

7
나는 내 질문을 게시하기 전에 인터넷과 대학 도서관 조사를 해봤는데 C를위한 소프트웨어 디자인에 대한 책으로 압도적이지 않았습니다. 당신이 가장 좋아하는 책을 요청합니다 (일반적인 C 책에 대해 이야기하지 않고 의미있는 변수와 같은 코딩 규칙에 대해 이야기하지 않음). 이름, 그러나 더 높은 추상화, 소프트웨어 아키텍처 수준). 또한 나는 당신의 '다른 사람에 의존'하는 비난에 동의하지 않습니다. 각 프로그래머가 모범 사례와 좋은 디자인 패턴에 대해 스스로 알아 내야한다는 뜻입니까? 이것은 확실히 다른 사람의 경험을 사용해야하는 질문입니다.
Dimi

2
미안 해요, 디미, 그건 특별히 당신에 대한 게 아니에요. 이 물건은 다른 어떤 방식 으로든 구전 전통에 의해 많이 전해졌습니다. 공식적인 "패턴"이라는 명목상의 세트가 없었고, Jonathon의 대답은 책에서 찾을 수있는 것이었지만 모든 사람들 이 정보 숨김에 대해 알고있었습니다. 구전 전통이 사라지고있는 것 같고 많은 젊은 프로그래머들은 OOP가 캡슐화와 분리를 발명했다고 생각합니다. 이 커뮤니티는 내가보고 싶은 것보다 자신의 역사에 대해 덜 이해하는 것 같습니다. 따라서 내가 심술 궂은 노인 영역에 있다는 것을 인정합니다.
dmckee --- ex-moderator kitten

1
현장에서 내 발을 찾았 기 때문에 회고 적 견해를 공유 할 수는 없지만 귀하의 제안을 수락합니다. 경험 많은 사람의 견해를 읽을 수 있도록 항상 큰 가치를 지닌 자신을 더 명확하게 표현해 주셔서 감사합니다. 당신의 기여에 정말 감사드립니다.
Dimi

SEI CERT C 코딩 표준은 사용을 피해야 할 사항뿐만 아니라 좋은 규칙 세트와 일반적인 모범 사례 를 제공합니다.
Rami

답변:


65

정보 숨김-Parnas ( Software Fundamentals ) 가지지하는대로 .

헤더 및 가시성의 신중한 관리 :

  • 외부 세계에서 숨길 수있는 소스 파일의 모든 것이 있어야합니다. 문서화 된 외부 인터페이스 만 노출되어야합니다.
  • 노출되는 모든 것은 헤더에 선언됩니다.
  • 해당 헤더는 기능이 필요한 곳 ​​(및 정의 된 곳)에 사용됩니다.
  • 헤더는 자체 포함되어 있습니다. 헤더는 필요한 모든 것을 포함하여 작동하도록 보장하기 때문에 필요할 때 사용하고 '내가 포함해야하는 다른 헤더'에 대해 걱정할 필요가 없습니다. 작업.
  • 헤더는 자체 보호되므로 여러 번 포함 되어도 상관 없습니다.

    #ifndef HEADER_H_INCLUDED
    #define HEADER_H_INCLUDED
    ...rest of header contents, including other #include lines if necessary
    #endif /* HEADER_H_INCLUDED */
    
  • '객체'(일반적으로 구조)에서 작동하도록 함수 세트를 설계하고이를 사용하는 코드에서 구조의 내부를 파고 드는 대신 해당 함수를 사용합니다. 자체 부과 캡슐화로 생각하십시오.


고마워요, 조나단 추상 데이터 유형은 사용과 구현 (알려진 외부 인터페이스 및 알 수없는 내부 구현)을 명확하게 구분하여 정보를 숨기는 또 다른 좋은 예입니다.
Dimi

23

나의 세 가지 조언 :

  • 단위 테스트를 작성합니다. 그들은 당신이 진행하면서 당신의 문제에 맞는 디자인에 집중하는 데 도움이 될 것입니다. 미리 명상 된 사고에만 의존하는 것보다 훨씬 낫습니다.
  • 메모리 누수 감지기 (모든 종류의 라이브러리가 있음)를 설치하고 첫날부터 실행하십시오. 프로그램 / 테스트가 종료되는 즉시이 라이브러리가 모든 누출을 인쇄하도록하십시오. 이렇게하면 누출을 도입하자마자 누출을 포착 할 수 있으므로 수리가 훨씬 덜 고통 스럽습니다.
  • C로 OOP 코드를 작성합니다. 그리 어렵지 않습니다. 메서드 재정의를 에뮬레이션 할 수 있지만 간단한 개체의 에뮬레이션으로 시작하는 것이 좋습니다. 이 간단한 메커니즘조차도 큰 마일리지를 제공 할 수 있습니다.

예를 들면 다음과 같습니다.

typedef struct Vector {
  int size;
  int limit;
  int* ints; 
} Vector;

Vector* Vector_new() {
  Vector* res = (Vector*) malloc(sizeof(Vector));
  res->limit = 10;
  res->size = 0;
  res->ints = (int*) malloc(sizeof(int) * res.limit);

  return res;
}


void Vector_destroy(Vector* v) {
  free(v->ints);
  free(v);
}

void Vector_add(Vector* v, int n) {
  if(v->size == v->limit) {
    v->limit = v->limit * 2 + 10;
    v->ints = realloc(v->ints, v->limit);     
  }

  v->ints[v->size] = n;
  ++v->size;
}

int Vector_get(Vector* v, int index) {
  if(index >= 0 && index < v->size)
    return v->ints[index];

  assert false;
}

고마워요, Itay. 나는 당신의 조언을 따를 것입니다.
Dimi

1
4. 결과를 캐스트하지 마십시오 malloc.
SS Anne

22

C로 객체 지향 코드를 작성하는 주제를 다루는 ANSI-C를 사용한 Object-Oriented Programming 이라는 제목의 좋은 무료 온라인 책 이 있습니다. "object-oriented C"에 대한 Google 검색 은 또한 많은 다른 장점을 산출합니다. 예와 자원.

프로젝트가 안전에 중요한 경우 MISRA-C 는 좋은 규칙 세트입니다. 주로 임베디드 c를위한 것이지만 다른 영역에서도 유용 할 수 있습니다.

저는 제 자신을 OO 코더라고 생각하고 임베디드 -C로 많은 작업을합니다. 특히 대규모 프로젝트에 대해 제가 드릴 수있는 최선의 조언은 과용하지 말라는 것입니다. ANSI C를 기반으로 완전한 OO 프레임 워크를 만드는 것은 매우 유혹적 일 수 있지만 제대로 작동하려면 많은 시간과 노력이 필요합니다. 더 좋아질수록 실제 프로젝트 에서 작업하는 대신 프레임 워크를 디버깅하는 데 더 많은 시간을 할애하게됩니다 . 명확한 머리와 YAGNI를 잘 이해하고 작업에 접근하십시오 . 행운을 빕니다!


감사합니다, e. James. ANSI C 위에 객체 지향 프레임 워크를 만들고 싶지 않지만 특별하고 적절한 절차 적 프로그래밍 디자인 원칙을 찾습니다. MISRA-C 힌트는 특히 실제로 포함 된 프로젝트이기 때문에 매우 유용합니다. 자세히 살펴 보겠습니다.
Dimi

아, 임베디드 C의 즐거움입니다. 함수 상단 (또는 { }블록 상단)에 변수를 선언해야한다는 것을 잊지 마십시오 . 그 하나는 항상 한 번 또는 두 번 나에게 물린:)
e.James

7

OOP는 기술이 아닌 방법론입니다. 그래서 첫 번째 조언은 그것을 절차 적 프로그래밍으로 생각하지 말라는 것입니다.

e. James의 지적에 따르면, 객체 지향 언어를 재창조하거나 그 능력이있는 척하고 싶지는 않습니다. 몇 가지 간단한 원칙을 고수하면 모든 올바른 일을 할 수 있습니다.

  1. 모든 것을 시험 운전하십시오.
  2. 무엇이 변하는 지 찾아서 캡슐화하십시오.
  3. 인터페이스 디자인.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.