kebab - estandar camelcase
¿Cuáles son las convenciones de nombres más comunes en C? (10)
¿Cuáles son las convenciones de nombres comúnmente utilizadas en C? Sé que hay al menos dos:
- GNU / linux / K & R con lower_case_functions
- ? nombre ? con funciones UpperCaseFoo
Estoy hablando de C solo aquí. La mayoría de nuestros proyectos son pequeños sistemas integrados en los que utilizamos C.
Aquí está el que planeo usar para mi próximo proyecto:
Convención de Nombramiento 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)
Aquí hay una (aparentemente) poco común, que he encontrado útil: nombre del módulo en CamelCase, luego un guión bajo, luego la función o el nombre del alcance del archivo en CamelCase. Así por ejemplo:
Bluetooth_Init()
CommsHub_Update()
Serial_TxBuffer[]
Bueno, en primer lugar, C no tiene funciones públicas / privadas / virtuales. Eso es C ++ y tiene diferentes convenciones. En C normalmente tienes:
- Constantes en ALL_CAPS
- Subraya para delimitar palabras en estructuras o nombres de funciones, casi nunca se ve camel case en C;
- estructuras, typedefs, uniones, miembros (de uniones y estructuras) y los valores enum normalmente están en minúsculas (en mi experiencia) en lugar de la convención C ++ / Java / C # / etc de hacer que la primera letra sea mayúscula, pero supongo que es posible C también.
C ++ es más complejo. He visto una mezcla real aquí. Estuche Camel para nombres de clase o guiones bajos en minúscula + (el caso de camello es más común en mi experiencia). Las estructuras se utilizan con poca frecuencia (y normalmente porque una biblioteca las requiere, de lo contrario utilizaría clases).
Codificando en C #, Java, C, C ++ y objetivo C al mismo tiempo, he adoptado una convención de nombres muy simple y clara para simplificar mi vida.
En primer lugar, depende del poder de los IDE modernos (como eclipse, Xcode ...), con la posibilidad de obtener información rápida al pasar el ratón o ctrl clic ... Al aceptar eso, suprimí el uso de cualquier prefijo, sufijo y otros marcadores que simplemente dan el IDE.
Entonces, la convención:
- Cualquier nombre DEBE ser una oración legible que explique lo que tienes. Como "esta es mi convención".
- Luego, 4 métodos para obtener una convención de una oración:
- THIS_IS_MY_CONVENTION para macros, enum miembros
- ThisIsMyConvention para nombre de archivo, nombre de objeto (clase, struct, enum, unión ...), nombre de función, nombre de método, typedef
- this_is_my_convention variables globales y locales,
parámetros, estructura y elementos de unión - thisismyconvention [opcional] variables muy locales y temporales (como un índice de bucle for ())
Y eso es.
Da
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;
}
}
}
Estoy confundido por una cosa: estás planeando crear una nueva convención de nombres para un nuevo proyecto. En general, debe tener una convención de nomenclatura que abarque toda la empresa o el equipo. Si ya tiene proyectos que tienen alguna forma de convención de nombres, no debe cambiar la convención para un nuevo proyecto. Si la convención anterior es solo una codificación de sus prácticas existentes, entonces está dorado. Cuanto más difiera de los estándares de facto existentes, más difícil será obtener una participación en el nuevo estándar.
Acerca de la única sugerencia que agregaría es que me ha gustado _t al final de los tipos en el estilo de uint32_t y size_t. Es muy C-ish para mí, aunque algunos pueden quejarse de que es simplemente húngaro "reverso".
Lo más importante aquí es la consistencia. Dicho esto, sigo la convención de codificación GTK +, que se puede resumir de la siguiente manera:
- Todas las macros y las constantes en mayúsculas:
MAX_BUFFER_SIZE
,TRACKING_ID_PREFIX
. - Struct nombres y typedef''s en camelcase:
GtkWidget
,TrackingOrder
. - Funciones que operan en las estructuras: estilo C clásico:
gtk_widget_show()
,tracking_order_process()
. - Punteros: aquí no hay nada sofisticado:
GtkWidget *foo
,TrackingOrder *bar
. - Variables globales: simplemente no use variables globales. Ellos son malvados
- Funciones que están ahí, pero que no se deben
_refrobnicate_data_tables()
directamente, o que tienen usos poco_refrobnicate_data_tables()
, o lo que sea: una o más guiones bajos al comienzo:_refrobnicate_data_tables()
,_destroy_cache()
.
Los "indicadores de estructura" no son entidades que necesitan una cláusula de convención de nomenclatura para cubrirlos. Solo son struct WhatEver *
. NO oculte el hecho de que hay un puntero involucrado con un typedef inteligente y "obvio". No sirve para nada, es más largo para escribir y destruye el equilibrio entre la declaración y el acceso.
Podría haber muchos, principalmente IDE que dictan algunas tendencias y las convenciones de C ++ también están presionando. Para C comúnmente:
- UNDERSCORED_UPPER_CASE (definiciones de macro, constantes, miembros enum)
- underscored_lower_case (variables, funciones)
- CamelCase (tipos personalizados: estructuras, enumeraciones, uniones)
- uncappedCamelCase (estilo oppa Java)
- UnderScored_CamelCase (variables, funciones en el tipo de espacios de nombres)
La notación húngara para globales está bien pero no para tipos. E incluso para nombres triviales, utilice al menos dos caracteres.
Recomendaría no mezclar camel case y separación de subrayado (como propusiste para los miembros de struct). Esto es confuso. Podrías pensar, hey get_length
así que probablemente debería haber make_subset
y luego descubrirás que es makeSubset
. Use el principio de menos asombro y sea consecuente.
Encuentro que CamelCase es útil para escribir nombres, como structs, typedefs y enums. Eso es todo, sin embargo. Para todo lo demás (nombres de funciones, nombres de miembros de estructuras, etc.) uso underscore_separation.
También debe pensar en el orden de las palabras para facilitar la finalización del nombre automático .
Una buena práctica: nombre de la biblioteca + nombre del módulo + acción + asunto
Si una parte no es relevante, sáltela, pero al menos debe presentarse un nombre de módulo y una acción.
Ejemplos:
- nombre de la función:
os_task_set_prio
,list_get_size
,avg_get
- define (aquí generalmente no hay parte de acción ):
OS_TASK_PRIO_MAX
Ya sabes, me gusta mantenerlo simple, pero claro ... Así que aquí está lo que uso, en C:
- Variables Triviales :
i,n,c
, etc. ... (Solo una letra. Si una letra no está clara, entonces hazla una Variable Local) - Variables locales :
lowerCamelCase
- Variables globales :
g_lowerCamelCase
- Variables de Const :
ALL_CAPS
- Variables del puntero : agregue un
p_
al prefijo. Para las variables globales, seríagp_var
, para las variables localesp_var
, para las variables constp_VAR
. Si se utilizan punteros lejanos, utilice unfp_
lugar dep_
. - Structs :
ModuleCamelCase
(Module = nombre completo del módulo, o una abreviatura de 2-3 letras, pero aún enCamelCase
). - Struct Variables miembro :
lowerCamelCase
- Enumeraciones :
ModuleCamelCase
- Valores de Enum :
ALL_CAPS
- Funciones públicas :
ModuleCamelCase
- Funciones privadas :
CamelCase
- Macros :
CamelCase
Escribo mis estructuras, pero uso el mismo nombre tanto para la etiqueta como para el typedef. La etiqueta no está destinada a ser utilizada comúnmente. En cambio, es preferible usar typedef. También reenvío declarar el typedef en el encabezado del módulo público para la encapsulación y para que pueda usar el nombre typedef''d en la definición.
Ejemplo de struct
completa :
typdef struct TheName TheName;
struct TheName{
int var;
TheName *p_link;
};