C语言学习笔记--(3)数据类型

一.编程规范

C语言编程规范是一套旨在提高代码质量、可读性和维护性的标准和建议。遵循良好的编程规范可以使得代码更加清晰、易于理解和管理,尤其是在团队协作的项目中。以下是一些常见的C语言编程规范和最佳实践:

1. 代码格式化

if (condition) {
    // 代码块
} else {
    // 另一个代码块
}
  • 缩进:使用空格或用Tap键制表符(通常是4个空格)进行缩进,以保持代码结构的清晰。
  • 大括号风格:对于函数、条件语句和循环,大括号的使用有多种风格(如K&R、Allman等)。选择一种风格并保持一致。
  • 行长度:限制代码的行长度(通常不超过80或120个字符),过长的行可以适当换行。
  • 例如
    printf("这是一个非常非常非常非常非常非常非常非常非常非常长的字符串,可能会导致阅读和维护上的不便");
    

2. 命名约定

不推荐

int n; // 不清楚变量用途
float prc; // 缩写可能导致混淆

推荐

int itemCount;
float itemPrice;
  • 变量和函数命名:使用有意义的名称,避免使用缩写。变量名使用小写字母,多个单词之间可以用下划线分隔;函数名可以使用驼峰命名法。
  • 常量命名:常量名使用大写字母,单词之间用下划线分隔。
  • #define MAX_SIZE 100
    const int MaxScore = 100;
    
  • 枚举命名:枚举类型及其值的命名应体现枚举的意图和内容。

3. 注释和文档

  • 函数注释:每个函数声明前应有注释,描述函数的目的、参数、返回值和任何副作用。
  • /**
     * 计算两个整数的最大值。
     * @param a 第一个整数
     * @param b 第二个整数
     * @return 两个整数中的最大值
     */
    int max(int a, int b) {
        return a > b ? a : b;
    }
    
  • 代码注释:对复杂的逻辑或代码段进行适当注释,解释其实现的目的和方式。
  • 避免过多注释:代码本身应尽可能清晰自解释,避免不必要或显而易见的注释。

4. 编程实践

  • 避免使用全局变量:全局变量会增加代码间的耦合,使得程序的流程难以跟踪和维护。
  • int gCounter;
    void increment() {
        gCounter++;
    }
    
  • 这个时候我们可通过将变量作为参数传递,减少全局变量的使用。
    int increment(int counter) {
        return counter + 1;
    }
    
  • 使用常量和宏:对于不会改变的值,使用#define宏或const关键字声明常量,以增强代码的可读性和可维护性。
  • 指针安全:使用指针时,注意检查空指针并避免悬挂指针和内存泄露。
  • 错误处理:适当检查函数返回值和错误码,进行错误处理。
    FILE *file = fopen("example.txt", "r");
    if (file == NULL) {
        perror("文件打开失败");
        return -1;
    }
    

5. 代码重用和模块化

// 计算数组中所有元素的和
int sum(int arr[], int size) {
    int total = 0;
    for (int i = 0; i < size; i++) {
        total += arr[i];
    }
    return total;
}
  • 函数复用:避免重复代码,将重复逻辑抽象为函数进行复用。
  • 模块化设计:将相关功能组织为模块或库,提高代码的模块化程度和重用性。

二.C语言中的关键字

我们在这例举了44个关键字,我们要知道C语言中,关键字是不允许作为标识符被出现在程序中的。

下面我们来看看C语言的关键字

  1. auto

  2. break

  3. case

  4. char

  5. const

  6. continue

  7. default

  8. do

  9. double

  10. else

  11. enum

  12. extern

  13. float

  14. for

  15. goto

  16. if

  17. inline (C99)

  18. int

  19. long

  20. register

  21. restrict (C99)

  22. return

  23. short

  24. signed

  25. sizeof

  26. static

  27. struct

  28. switch

  29. typedef

  30. union

  31. unsigned

  32. void

  33. volatile

  34. while

  35. _Alignas (C11)

  36. _Alignof (C11)

  37. _Atomic (C11)

  38. _Bool (C99)

  39. _Complex (C99)

  40. _Generic (C11)

  41. _Imaginary (C99)

  42. _Noreturn (C11)

  43. _Static_assert (C11)

  44. _Thread_local (C11)

三.标识符

int mainCounter;     // 正确:以字母开头
float _temperature;  // 正确:以下划线开头
char *myString;      // 正确:使用字母和下划线

int 2ndAttempt;      // 错误:不能以数字开头
float float;         // 错误:不能使用C语言的关键字
char a*b;            // 错误:不能包含除字母、数字和下划线以外的字符

标识符的规则:

  1. 开头:标识符必须以字母(A-Za-z)或下划线(_)开头。
  2. 字符:标识符的其余部分可以包含字母、数字和下划线。
  3. 区分大小写:C语言中的标识符是区分大小写的,这意味着ExampleexampleEXAMPLE是三个不同的标识符。
  4. 关键字限制:标识符不能是C语言的关键字。
  5. 长度限制:尽管大多数现代C编译器支持的标识符长度非常长,但是前31个字符对于标识符的唯一性是有保证的,超过这个长度的部分可能会被编译器忽略。

标识符的命名最佳实践:

  • 明确性:选择有意义的名称,使得标识符能够准确反映其代表的实体或用途。
  • 简洁性:尽量简洁,同时保持明确和有意义。
  • 规范性:遵守项目或团队的命名规范,如驼峰命名法(myVariableName)或下划线分隔法(my_variable_name)。
  • 避免使用下划线开头:尽管下划线开头的标识符在C语言中是合法的,但通常它们被保留用于特定的编译器或库的实现,因此在普通项目中使用时应谨慎。

四.数据类型

在C语言中,数据类型是一个非常重要的概念,它定义了变量可以存储的数据种类,以及对数据可以进行的操作。C语言提供了多种数据类型,主要可以分为以下几类:

1. 基本类型

  • 整型(Integer Types):用于存储整数。包括 int, short, long, long long 以及它们的无符号版本 unsigned int, unsigned short, unsigned long, unsigned long long
  • 字符型(Character Type):用于存储单个字符。包括 char 以及 unsigned charsigned char
  • 浮点型(Floating-point Types):用于存储带有小数部分的数。包括 float, double, 和 long double
  • 布尔型(Boolean Type):C99标准新增,用 _Bool 表示,通常用于表示真 (1) 或假 (0)。

2. 枚举类型

  • 枚举(Enumeration Type):一种用户定义的类型,它允许程序员为整数值指定更具可读性的名字。通过关键字 enum 定义。

3. 派生类型

  • 指针(Pointer Types):用于存储变量地址的类型。
  • 数组(Array Types):用于存储固定大小和类型相同的元素序列。
  • 结构体(Structure Types):允许将多个不同类型的数据项组合成一个单一的复合类型。
  • 联合体(Union Types):允许在相同的内存位置存储不同的数据类型,但一次只能使用其中一个。
  • 函数类型(Function Types):代表函数的类型,定义了函数的返回类型和参数类型。

4. void类型

  • void:特殊的类型,表示无类型。常用于指定没有返回值的函数,或作为无类型指针 void* 使用。

示例

int main() {
    int integer = 10;               // 整型
    char character = 'A';           // 字符型
    float floatingPoint = 3.14f;    // 浮点型
    _Bool boolean = 0;              // 布尔型 (C99)

    // 枚举类型
    enum color {RED, GREEN, BLUE} myColor;
    myColor = RED;

    // 指针类型
    int* pointerToInt = &integer;

    // 数组类型
    int integerArray[5] = {0, 1, 2, 3, 4};

    // 结构体类型
    struct person {
        char name[50];
        int age;
    };
    struct person person1 = {"Alice", 30};

    // 联合体类型
    union data {
        int integer;
        float floatingPoint;
        char string[20];
    };
    union data myData;

    // 函数类型
    // 定义一个返回整型,参数为两个整型的函数
    int add(int a, int b) {
        return a + b;
    }

    return 0;
}

5.数值型和字符型数据的字节数和储存范围

整型

  • char:通常1字节,范围通常是-128到127(有符号char),或0到255(无符号uchar)。
  • short:通常2字节,范围通常是-32,768到32,767(有符号short),或0到65,535(无符号ushort)。
  • int:通常4字节,范围通常是-2,147,483,648到2,147,483,647(有符号int),或0到4,294,967,295(无符号uint)。
  • long:在32位系统上通常是4字节,64位系统上可能是4字节(LP64模型)或8字节(LLP64模型),范围至少是-2,147,483,648到2,147,483,647(有符号long),或0到4,294,967,295(无符号ulong)。在8字节的系统上,范围扩展到-9,223,372,036,854,775,808到9,223,372,036,854,775,807(有符号),或0到18,446,744,073,709,551,615(无符号)。
  • long long:通常8字节,范围是-9,223,372,036,854,775,808到9,223,372,036,854,775,807(有符号),或0到18,446,744,073,709,551,615(无符号)。

浮点型

  • float:通常4字节,范围大约是±3.4e±38(7位有效数字)。
  • double:通常8字节,范围大约是±1.7e±308(15位有效数字)。
  • long double:大小和范围依编译器和平台不同,通常比double拥有更高的精度和更大的范围,可能是8, 12, 或16字节。

字符型

  • char:如上所述,即使char主要用来表示字符,它在内存中的存储也是以数值形式,因此也遵循上述的字节数和范围。

五.变量的储存类别

1. auto

  • 描述auto是默认的存储类别,用于局部变量。实际上,局部变量默认就是auto,因此很少显式使用这个关键字。
  • 作用域:局部作用域。
  • 生命周期:只在定义它们的代码块内有效。
void function() {
 auto int localVar = 0; 
}

2. register

  • 描述register存储类别用于声明寄存器变量。寄存器变量被建议存储在CPU的寄存器中,以便快速访问,但实际上这是编译器的优化决策。
  • 作用域:局部作用域。
  • 生命周期:只在定义它们的代码块内有效。
void function() {
 register int loopCounter = 0; 
}

3. static

  • 描述static存储类别用于声明静态变量。静态局部变量的值在函数调用之间保持持久,静态全局变量只在声明它们的文件内可见。
  • 作用域:局部变量时为局部作用域,但在函数调用之间保持其值不变;全局变量时为文件作用域。
  • 生命周期:整个程序执行期间。
void function() { 
static int staticVar = 0; // 局部静态变量 
} 
static int fileScopeVar = 0; // 文件作用域的静态变量

4. extern

  • 描述extern存储类别用于提供一个全局变量的引用,该变量在其他文件中定义。它用于在一个文件中声明另一个文件中定义的全局变量或函数。
  • 作用域:全局作用域。
  • 生命周期:整个程序执行期间。
// 假设在file1.c中定义了globalVar 
extern int globalVar; // 在file2.c中声明,可以使用file1.c中定义的globalVar
 void function() {
 globalVar = 5; 
}

注意点

  • 作用域和生命周期:作用域决定了代码中可以访问变量的区域。生命周期决定了变量在内存中存在的时间。
  • 选择存储类别:正确选择变量的存储类别对于程序的正确性和效率至关重要。
  • 编译器优化:对于register声明,现代编译器会进行自己的优化判断,可能会忽略register建议。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值