C에서 가장 일반적인 명명 규칙은 무엇입니까?


126

C에서 일반적으로 사용되는 명명 규칙은 무엇입니까? 적어도 두 가지가 있다는 것을 알고 있습니다.

  1. GNU / Linux / K & R with lower_case_functions
  2. ? 이름? UpperCaseFoo 함수 사용

여기서 만 C에 대해 이야기하고 있습니다. 대부분의 프로젝트는 C를 사용하는 소형 임베디드 시스템입니다.

다음 프로젝트에 사용할 계획입니다.


C 명명 규칙

Struct              TitleCase
Struct Members      lower_case or lowerCase

Enum                ETitleCase
Enum Members        ALL_CAPS or lowerCase

Public functions    pfx_TitleCase (pfx = two or three letter module prefix)
Private functions   TitleCase
Trivial variables   i,x,n,f etc...
Local variables     lower_case or lowerCase
Global variables    g_lowerCase or g_lower_case (searchable by g_ prefix)

7
전역 변수에 'g_'접두사를 강요하지 않습니다. 의미있는 이름을 적용합니다 (따라서 전역 변수 이름으로 cl_lc가 아닌 client_locale). 클래식 C는 카멜 케이스를 사용하지 않습니다. C에서 camel-case로 코드를 작성했는데 이상해 보입니다 (그래서 더 이상 그렇게하지 않습니다). 즉, 틀린 것이 아니며 어떤 규칙을 사용하는 것보다 일관성이 더 중요합니다. 구조 포인터를 캡슐화하는 typedef를 피하십시오. C 표준을 고려하십시오. 따라서 'FILE *'의 철자는 FILE_PTR이 아닙니다.
Jonathan Leffler

2
@Jonathan Leffler, g_가 글로벌을 의미하는 데 문제가 있습니까? 임베디드 시스템에서는 글로벌 vars 및 extern g_somevar를 통해 모듈 간 종속성을 추적하기가 어려웠던 문제가있었습니다. 나는 개인적으로 일반적으로 나쁜 생각이라고 생각하지만 이런 종류의 일은 대개 성능상의 이유로 수행됩니다. 예를 들어, 데이터가 준비되었음을 나타내는 인터럽트에 의해 설정된 전역 플래그입니다.
JeffV 2009

2
그만한 가치가있는이 명명 규칙은 대부분 PalmOS API 규칙에서 찢어졌습니다. 또한 O'Reilly의 책 "C 및 GNU 개발 도구로 임베디드 시스템 프로그래밍"에 사용 된 규칙과 유사합니다. 개인적으로 저는 함수 이름에서 TitleCase를 좋아합니다. 내부 연결 함수에서 lowerCamelCase를 사용할 생각이었습니다 (제 질문에서 private이라고 불렀습니다).
JeffV 2009

3
@Chris Lutz, 진심으로 동의합니다. 가능한 한 vars는 가장 좁은 범위로 유지되어야합니다. 실제로 우리가 논의하고있는 세 가지 범위가 있습니다 : 함수에 로컬, 모듈에 로컬 (변수에 대한 외부 연결 없음) 및 외부 연결이있는 전역. 임베디드 시스템에서 "모듈 전역"변수를 갖는 것은 일반적입니다. 따라서 최소한으로 유지하고 모듈 상호 작용을 이해할 수 있도록 외부 연결이있는 전역을 식별하는 데주의를 기울여야합니다. 여기서 "g_"접두사가 도움이됩니다.
JeffV

46
전역 변수에 // 접두사를 붙이고 싶습니다.
plafer 2015

답변:


128

여기서 가장 중요한 것은 일관성입니다. 즉, 다음과 같이 요약 할 수있는 GTK + 코딩 규칙을 따릅니다.

  1. 대문자로 된 모든 매크로 및 상수 : MAX_BUFFER_SIZE, TRACKING_ID_PREFIX.
  2. 카멜 케이스의 구조체 이름과 typedef : GtkWidget, TrackingOrder.
  3. 구조체에서 작동하는 함수 : 클래식 C 스타일 : gtk_widget_show(), tracking_order_process().
  4. 포인터 : 여기에 멋진 것은 없습니다 : GtkWidget *foo, TrackingOrder *bar.
  5. 전역 변수 : 전역 변수를 사용하지 마십시오. 그들은 사악합니다.
  6. 거기에 있지만 직접 호출해서는 안되는 함수, 사용이 모호한 것 등 : 처음에 하나 이상의 밑줄 : _refrobnicate_data_tables(), _destroy_cache().

13
6 번 포인트에서는 static모듈 접두사 를 사용 하고 건너 뛰는 것을 선호 하므로 gtk_widget_show()파일 범위가있는 함수라면 단순히 widget_show()정적 스토리지 클래스가 추가 된 상태가됩니다.
August Karlstrom

27
포인트 6에 대한 추가 참고 사항 : C 표준에는 _구현 및 향후 사용 을 위해 시작하는 이름 예약에 대한 몇 가지 규칙이 있습니다. 로 시작하는 이름에는 몇 가지 예외가 _있지만 제 생각에는 암기 할 가치가 없습니다. 안전한 규칙은 _코드에서로 시작하는 이름을 사용하지 않는 것 입니다. 관련 C FAQ 항목 : c-faq.com/~scs/cgi-bin/faqcat.cgi?sec=decl#namespace
jw013

5
# 2는 더 구체적으로 대문자 카멜 케이스 또는 파스칼 케이스 입니다. 카멜 케이스 또는 소문자 카멜 케이스는 첫 글자에 소문자를 사용합니다.
Clint Pachl

9
지역 다중 단어 변수는 어떻습니까? my_var 또는 myVar?
Dean Gurvitz

4
Global variables: just don't use global variables. They are evil.-임베디드 프로젝트에서 작업하고 있고 1024 바이트의 RAM과 8MHz CPU가없는 경우.
Kamil

30

"구조 포인터"는이를 다루기 위해 명명 규칙 절이 필요한 엔티티가 아닙니다. 그들은 단지 struct WhatEver *. 영리하고 "명백한"typedef와 관련된 포인터가 있다는 사실을 숨기지 마십시오. 목적이없고 더 이상 입력 할 수 없으며 선언과 액세스 사이의 균형을 파괴합니다.


29
"포인터를 숨기지 마십시오"항목에 대해 +1-이 답변이 나머지 질문을 많이 다루지는 않지만 (아직).
Jonathan Leffler

1
@unwind, 나는 동의하는 경향이 있습니다. 그러나 때때로 포인터는 외부 역 참조를위한 것이 아니며 소비자가 사용할 구조체에 대한 실제 포인터보다 소비자에 대한 핸들에 가깝습니다. 그것이 내가 TitleCasePtr을 남긴 것입니다. typedef struct {필드} MyStruct, * MyStructPtr;
JeffV 2009

TitleCasePtr을 제거하고 있는데 실제 질문에서 산만합니다.
JeffV 2009

1
포인터 유형 선언은 특히 함수 시그니처에서 혼란을 줄이고 선언과 액세스 간의 "불균형"이 구현 파일에만 표시되므로 클라이언트가 필드 멤버에 직접 액세스해서는 안됩니다.
August Karlstrom

1
@AugustKarlstrom 좋아. 구현 파일에 대해 "유일한"것이 무엇인지 이해하지 못합니다. 그 코드도 아닌가요? 나는이 질문을 "외부"이름에 관한 것으로 해석하지 않았습니다. 모든 코드는 어떤 수준에서 "구현"입니다.
긴장 풀기

17

첫째로 C에는 공개 / 개인 / 가상 기능이 없습니다. 그것은 C ++이고 다른 규칙을 가지고 있습니다. C에서는 일반적으로 다음이 있습니다.

  • ALL_CAPS의 상수
  • 구조체 또는 함수 이름에서 단어를 구분하는 밑줄, C에서 카멜 케이스를 거의 볼 수 없습니다.
  • 구조체, typedef, 공용체, 멤버 (조합 및 구조체의) 및 열거 형 값은 일반적으로 첫 글자를 대문자로 만드는 C ++ / Java / C # / etc 규칙이 아닌 소문자 (내 경험상)이지만 다음에서 가능하다고 생각합니다. C도.

C ++는 더 복잡합니다. 여기서 진짜 믹스를 보았습니다. 클래스 이름 또는 소문자 + 밑줄에 대한 카멜 케이스 (내 경험상 낙타 케이스가 더 일반적 임). 구조체는 거의 사용되지 않습니다 (일반적으로 라이브러리에 필요하기 때문에, 그렇지 않으면 클래스를 사용합니다).


@ cletus, 나는 그것을 알고 있습니다. 비공개 란 모듈 헤더에서 외부 적으로 노출되지 않고 모듈 외부의 코드에서 사용하도록 의도되지 않은 함수를 의미합니다. 공용은 외부에서 사용하기위한 모듈 API 함수입니다.
JeffV 2009

3
정적 함수를 비공개로 간주 할 수 있습니다. 질문은 가상을 언급하지 않습니다. 그러나 'C에서 낙타 케이스를 거의 볼 수 없음'은 +1입니다.
Jonathan Leffler

2
Jeff external linkage는 "공용 기능"과 internal linkage"개인 기능"을 의미한다고 생각 합니다.
pmg

1
ak와 kBufferSize로 시작하는 상수를 보았습니다. 그것이 어디에서 오는지 확실하지 않습니다.
JeffV 2009

2
ALL_CAPS열거 형 값에도 자주 사용됩니다.
caf

14

알다시피, 저는 단순하게 유지하고 싶지만 명확하게 ... 그래서 C에서 제가 사용하는 것은 다음과 같습니다.

  • Trivial Variables : i,n,c, etc ... (단 하나의 문자. 하나의 문자가 명확하지 않으면 로컬 변수로 만드십시오)
  • 지역 변수 :lowerCamelCase
  • 전역 변수 :g_lowerCamelCase
  • 상수 변수 :ALL_CAPS
  • 포인터 변수 : p_접두사 에 a 를 추가 합니다. 전역 변수의 경우 gp_var지역 변수 p_var의 경우 const 변수가 p_VAR됩니다. 먼 포인터를 사용하는 fp_경우 p_.
  • Structs : ModuleCamelCase(Module = 전체 모듈 이름 또는 2-3 자 약어이지만 여전히 CamelCase.)
  • 구조체 멤버 변수 :lowerCamelCase
  • 열거 형 :ModuleCamelCase
  • 열거 형 값 :ALL_CAPS
  • 공공 기능 :ModuleCamelCase
  • 개인 기능 :CamelCase
  • 매크로 :CamelCase

내 구조체를 typedef하지만 태그와 typedef 모두에 동일한 이름을 사용합니다. 태그는 일반적으로 사용되지 않습니다. 대신 typedef를 사용하는 것이 좋습니다. 또한 캡슐화를 위해 공용 모듈 헤더에 typedef를 전달하여 정의에서 typedef의 이름을 사용할 수 있습니다.

전체 struct :

typdef struct TheName TheName;
struct TheName{
    int var;
    TheName *p_link;
};

qt 프레임 워크에 대해 아무것도 모르지만 원하는 스타일 형식으로 코드를 작성할 수 있습니다. 내가 아는 한 아무것도 당신을 막지 못합니다.
SeanRamey

10

C #, Java, C, C ++ 및 객관적인 C 로 동시에 코딩하면서 저는 삶을 단순화하기 위해 매우 간단하고 명확한 명명 규칙을 채택했습니다.

우선, 그것은 최신 IDE (예 : eclipse, Xcode ...)의 힘에 의존하며, 마우스를 가져 가거나 ctrl을 클릭하여 빠른 정보를 얻을 수있는 가능성을 가지고 있습니다. 그것을 받아들이고, 접두사, 접미사 사용을 억제했습니다. 및 단순히 IDE에서 제공하는 기타 마커.

그런 다음 컨벤션 :

  • 모든 이름은 가지고있는 것을 설명하는 읽기 쉬운 문장이어야합니다. "이건 내 컨벤션"처럼.
  • 그런 다음 문장에서 관례를 얻는 4 가지 방법 :
    1. 매크로, 열거 형 멤버의 경우 THIS_IS_MY_CONVENTION
    2. ThisIsMyConvention for file name, object name (class, struct, enum, union ...), function name, method name, typedef
    3. this_is_my_convention 전역 및 지역 변수,
      매개 변수, 구조체 및 공용체 요소
    4. thisismyconvention [선택 사항] 매우 지역적이고 임시적인 변수 (for () 루프 인덱스와 같은)

그리고 그게 다야.

그것은 준다

class MyClass {
    enum TheEnumeration {
        FIRST_ELEMENT,
        SECOND_ELEMENT,
    }

    int class_variable;

    int MyMethod(int first_param, int second_parameter) {
        int local_variable;
        TheEnumeration local_enum;
        for(int myindex=0, myindex<class_variable, myindex++) {
             localEnum = FIRST_ELEMENT;
        }
    }
}

8

나는 낙타 케이스와 밑줄 분리를 혼합하지 않는 것이 좋습니다 (구조 멤버에게 제안한 것처럼). 이것은 혼란 스럽습니다. 당신은 생각할 것입니다, 헤이 내가 가지고 get_length있기 때문에 아마도 내가 있어야 할 것이고 make_subset당신은 그것이 실제로 makeSubset. 최소한 경악의 원칙을 사용하고 일관성을 유지하십시오.

CamelCase는 구조체, typedef 및 enum과 같은 이름을 입력하는 데 유용합니다. 그래도 그게 전부입니다. 나머지 (함수 이름, 구조체 멤버 이름 등)는 underscore_separation을 사용합니다.


1
예, 모든 명명 규칙의 가장 중요한 점은 예측 가능성과 일관성입니다. 또한 C 라이브러리 자체는 공백으로 _와 함께 모두 소문자를 사용하기 때문에 프로젝트에서 두 가지 다른 명명 규칙을 처리 할 필요가 없도록이를 사용하는 것이 좋습니다 (만들기 위해 libc 주위에 래퍼를 작성하지 않는다고 가정). 그것은 당신의 이름과 일치합니다 .. 그러나 그것은 총체적입니다)
Earlz

또한 끝에 " t" 가 붙은 typedef를 사용 하지만 추천하는 사람은 없습니다. 사실, 표준 라이브러리는 일관성이 없습니다. div_t (stdlib.h)는 구조체이고 tm (time.h)도 마찬가지입니다. 또한 tm 구조체 멤버를 살펴보면 모두 무의미하고 추악 해 보이는 tm (IMO) 접두사가 붙습니다 .
JeffV 2009

1
"이름을 입력하는 데 CamelCase가 유용하다고 생각합니다 ..."대문자로 시작하면 실제로 PascalCase입니다.
Tagc

7

다음은 CamelCase의 모듈 이름, 밑줄, CamelCase의 함수 또는 파일 범위 이름입니다. 예를 들면 :

Bluetooth_Init()
CommsHub_Update()
Serial_TxBuffer[]

2
그렇게 드물지는 않지만 매우 유용합니다.
chux-Monica 복원

3

한 가지 혼란 스럽습니다. 새 프로젝트에 대한 새 명명 규칙을 만들 계획입니다. 일반적으로 회사 또는 팀 전체의 명명 규칙이 있어야합니다. 어떤 형식의 명명 규칙이있는 프로젝트가 이미있는 경우 새 프로젝트에 대한 규칙을 변경해서는 안됩니다. 위의 관습이 기존 관행의 코드 화일 뿐이라면 황금색입니다. 기존의 사실상의 표준 과 다를 수록 새로운 표준에서 마음을 공유하기가 더 어려워집니다.

내가 추가 할 유일한 제안은 uint32_t 및 size_t 스타일의 유형 끝에있는 _t를 좋아한다는 것입니다. 어떤 사람들은 그것이 단지 "역"헝가리어라고 불평 할 수도 있지만 그것은 나에게 매우 C-ish입니다.


3
글쎄요, 여기에있는 관습은 도처에 있고 일관성이 없기 때문에 하나를 문서화하려고합니다. 또한 그것이 내가 묻는 이유입니다. 커뮤니티 합의가 무엇인지 확인합니다.
JeffV 2009

그 고통을 이해합니다. 그러나 가장 인기있는 기존 규칙의 일부가 있어야합니다. 임의의 인터넷 웹 페이지가 아닌 거기서 시작해야합니다. 또한 다른 개발자에게 무엇이 좋을지 물어봐야합니다.
jmucchiello

7
_t로 끝나는 유형 이름은 POSIX 표준에 의해 예약되어 있다고 생각합니다.
caf

4
_t로 끝나는 이름은 예약되어 있습니다. 참조 gnu.org/software/libc/manual/html_node/Reserved-Names.html은 "이름 '_t'로 끝이 추가 유형 이름을 위해 예약되어있다."
에티엔

2

자동 이름 완성을 더 쉽게 만들려면 단어순서도 고려해야합니다 .

모범 사례 : 라이브러리 이름 + 모듈 이름 + 조치 + 주제

부품이 관련이없는 경우 건너 뛰지 만 최소한 모듈 이름과 작업은 항상 표시되어야합니다.

예 :

  • 함수 이름 : os_task_set_prio, list_get_size,avg_get
  • 정의 (여기서는 일반적으로 작업 부분 없음 ) :OS_TASK_PRIO_MAX

0

주로 IDE가 일부 트렌드를 지시하고 C ++ 규칙도 추진하고 있습니다. C의 경우 일반적으로 :

  • UNDERSCORED_UPPER_CASE (매크로 정의, 상수, 열거 형 멤버)
  • underscored_lower_case (변수, 함수)
  • CamelCase (사용자 정의 유형 : 구조체, 열거 형, 공용체)
  • uncappedCamelCase (oppa Java 스타일)
  • UnderScored_CamelCase (변수, 네임 스페이스 종류의 함수)

전역에 대한 헝가리 표기법은 괜찮지 만 유형에는 적합하지 않습니다. 그리고 사소한 이름의 경우에도 최소한 두 문자를 사용하십시오.


-1

초보자에게 도움이 될 수 있다고 생각합니다 : c에서 변수 명명 규칙

  1. 알파벳 문자 (az, AZ), 숫자 (0-9) 및 Under Score (_)를 사용해야합니다. %, $, #, @ 등과 같은 특수 문자는 사용할 수 없습니다 . 따라서 user_name 은 변수로 사용할 수 있지만 user & name은 사용할 수 없습니다 .
  2. 단어 사이에 공백을 사용할 수 없습니다. 따라서 user_name 또는 username 또는 username 을 변수로 사용할 수 있지만 user name 은 사용할 수 없습니다 .
  3. 숫자로 명명을 시작할 수 없습니다. 따라서 user1 또는 user2 는 변수로 사용할 수 있지만 1user 는 사용할 수 없습니다 .
  4. 대소 문자를 구분하는 언어입니다. 대문자와 소문자가 중요합니다. username 과 같은 변수를 사용하는 경우 USERNAME 또는 Username 을 아버지 용도로 사용할 수 없습니다 .
  5. 변수 선언 에는 키워드 (char, int, if, for, while 등) 를 사용할 수 없습니다 .
  6. ANSI 표준은 변수 이름으로 31 자의 길이를 인식합니다.

이 게시물은 제한이 아닌 명명 규칙 을 논의하는 것을 목표로합니다 . 나열한 것은 구문 오류이기 때문에 할 수없는 일 입니다.
Chase
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.