2.2 C 语言常量的定义与变量命名的规范及原则

目录

1 常量

1.1 常量的分类

1.2 符号常量(#define)

1.2.1 定义不同类型的符号常量

1.2.2 注意事项

1.3 使用 const 定义常量

1.3.1 定义不同类型的常量

1.3.2 常量的命名规范

2 变量

2.1 变量名的作用

2.2 变量的命名规范

2.3 变量的命名原则

2.4 大小驼峰命名法


1 常量

        常量是指在程序运行过程中,其值不发生变化的量。

1.1 常量的分类

        常量又可分为整型、实型(也称浮点型)、字符型和字符串型,如下所示:

整型:100, 125, -100, 0
实型(浮点型):3.14, 0.125, -3.789
字符型:'a', 'B', '2'
字符串型:"a”, "Thanks_ks", "1c34", "你好,世界!", "一战成硕"

        整型常量、实型常量、字符型常量和字符串型常量都是在编译时就已经确定了它们的值,并且这些值可以直接被编入代码段中。这意味着在程序运行之前,这些常量的值就已经是固定的,不会在程序执行过程中改变

  • 整型常量:如 100、-23 等,表示整数值的常量。它们在代码中直接表示整数,其值在编译时就已确定。
  • 实型常量(浮点型常量):如 3.14、-0.001、1.2E3(等于 1200.0 )等,表示具有小数部分的数值。这些常量的值在编译时也被确定,用于表示实数或浮点数。
  • 字符型常量:如 'a'、'B'、'\n'(换行符)等,表示单个字符的常量。字符常量用单引号括起来,其值在编译时确定。
  • 字符串型常量:如 "Hello, World!"、""(空字符串)等,表示一系列字符的集合。字符串常量用双引号括起来,编译时会被处理为字符数组,并在末尾自动添加一个空字符( '\0' )作为字符串的结束标志。字符串常量的值在编译时确定。

        提示:考研不会考汉字的字符串常量,CLion 中需要修改配置才可以输出不乱码的汉字,感兴趣者可以参考这篇博客:clion控制台中文乱码及网上常见方法更改后出现printf和scanf顺序错乱的问题_clion控制台输出乱码-CSDN博客

1.2 符号常量(#define)

        在 C 语言中,符号常量(或称宏定义)是通过预处理指令 #define 来创建的。预处理器在编译之前的一个阶段——预处理阶段,会遍历源代码,将代码中所有的宏定义替换为它们各自所代表的具体值

        这种做法为开发者提供了一种便利,使得他们能够为复杂的数值或字符串等数据类型值指定易于记忆和理解的名称(即标识符)。之后,在整个程序代码中,就可以通过这些标识符来引用这些值,从而增强代码的可读性和可维护性。

1.2.1 定义不同类型的符号常量

        下面这个程序使用 #define 定义了整型、实型(也称浮点型)、字符型和字符串型符号常量:

#include <stdio.h>

// 定义整型常量
#define MAX_INT 100  // 这里不要加分号;

// 定义浮点型常量
#define PI 3.14159

// 定义字符型常量(注意:通常字符常量直接用单引号定义,但这里演示宏定义方式)
// 注意:宏定义通常不直接用于单个字符,因为直接使用字符字面量更方便且安全
#define NEWLINE_CHAR '\n'

// 定义字符串型常量(字符串宏定义末尾不需要加'\0',因为字符串字面量自动包含终止符)
#define WELCOME_MESSAGE "Welcome to C programming!"

int main(){
    // 使用整型常量进行简单运算
    int doubleMax = MAX_INT * 2;
    printf("Double the maximum integer is %d.\n", doubleMax);
    
    // 使用浮点型常量进行简单运算
    float radius = 5.0f; // float 类型变量建议加上 f 后缀
    float area = PI * radius * radius; // 计算圆的面积
    printf("The area of a circle with radius %f is approximately %f.\n", radius, area);
    
    
    // 使用字符型常量(虽然这里用宏定义可能不是最佳实践)
    printf("This is a new line character: %c", NEWLINE_CHAR); // 会换行
    
    // 使用字符串型常量
    printf("%s\n", WELCOME_MESSAGE);
    
    return 0;
}

         输出结果如下所示:

1.2.2 注意事项

        对于字符型常量,通常直接使用字符字面量(如 'a'、'\n' 等)更为常见和方便。宏定义在这里主要用于演示目的,实际编程中可能并不常见。

        字符串型常量在宏定义中非常有用,特别是当字符串很长或需要在多个地方重复使用时。不过,需要注意的是,字符串字面量在 C 语言中本身就是以 \0(空字符)结尾的,因此在宏定义字符串常量时,不需要(也不应该)在末尾显式添加 \0

        #define 指令创建的宏定义没有作用域限制,它们在整个源文件中都是可见的,除非被 #undef 指令取消定义。此外,如果多个源文件包含同一个头文件,并且该头文件中定义了宏,则这些宏将在所有包含该头文件的源文件中都可用。这可能会导致命名冲突,因此在使用宏定义时需要谨慎选择名称

        由于 #define 指令只是简单的文本替换,所以在使用时需要注意可能发生的意外情况,比如宏展开导致的运算符优先级问题。例如:

#include <stdio.h>

// 不要在定义符号常量的后面加分号
#define PI 3+2

int main() {
    int i = PI * 2; // 3 + 2 * 2 = 7
    printf("i=%d\n", i); // i=7 而不是 10
    return 0;
}

        C 语言中的宏替换是纯粹的文本替换。上面这个例子最终的输出结果是 i=7 而不是 i=10,原因是符号常量 PI 是直接替换的效果。PI 会被直接替换为 3+2,表达式 3 + 2 * 2 会被计算为 3 + (2 * 2),结果是 7。

       注意: 不要在定义符号常量的后面加分号,如 #define PI 3+2; 是不规范的写法。

1.3 使用 const 定义常量

        在学习 1.3 小节之前,建议先预览并掌握后续内容中关于如何定义整型、浮点型、字符以及字符串型变量的知识点。

        在 C 语言中,const 关键字用于声明常量,即其值在程序执行期间不会改变的变量。

1.3.1 定义不同类型的常量

整型常量

        整型常量可以是 short, int, unsigned int, long, unsigned long, long long 等等。使用 const 定义整型常量的例子:

const int myIntConst = 42;
const long myLongConst = 123456789L;  // L 后缀用于明确指定该字面量的类型为 long 整型
const unsigned int myUnsignedIntConst = 42u; // u 后缀用于明确指定该字面量的类型为 unsigned (无符号)整型

浮点型常量

        浮点型常量可以是 float, double 或 long double 类型。使用 const 定义浮点型常量的例子:

const float myFloatConst = 3.14f;  // f 后缀用于明确指定该字面量为 float 类型
const double myDoubleConst = 2.71828;
const long double myLongDoubleConst = 1.618033988749895L;  // L 后缀用于明确指定该字面量为 long double 类型

字符型常量

        字符型常量是单个字符,用单引号括起来。使用 const 定义字符型常量的例子:

const char myCharConst = 'A';

字符串型常量

        在 C 语言中,字符串实际上是字符数组,以空字符 \0 结尾使用 const 定义字符串型常量通常意味着定义一个指向字符串字面量的指针一个不可修改的字符数组。使用 const 定义字符串型常量的例子:

// myStringConst 是一个指向字符串字面量的常量指针
const char* myStringConst = "Hello, World!"; 

// myCharArrayConst 是一个初始化为字符串的常量字符数组
const char myCharArrayConst[] = "Hello, World!";

1.3.2 常量的命名规范

        当定义常量时,必须在声明时立即初始化

        使用 const 定义的常量有助于提高代码的可读性,减少错误,因为它强制要求在编译时就确定常量的值,而不是在运行时。

        在定义常量时,良好的实践是使用全大写字母,中间用下划线分隔,以区别于普通变量。例如,MY_CONSTANT。

#include <stdio.h>

// 使用 const 定义常量,并在声明时立即初始化
// 遵循全大写字母和下划线分隔的命名规范
const int MY_CONSTANT = 42;

int main() {
    // 尝试打印常量的值
    printf("The value of MY_CONSTANT is: %d\n", MY_CONSTANT);
    // 输出结果:The value of MY_CONSTANT is: 42
    
    // 尝试修改常量的值(这将导致编译错误)
    // MY_CONSTANT = 100; // 这行代码如果取消注释,将会导致编译失败
    
    // 由于 MY_CONSTANT 是 const 的,编译器会确保它在编译时就已经确定值
    // 并且不允许在运行时修改它
    
    return 0;
}

        注意:尽管 const 在 C 语言中被广泛使用,并且从 C99 标准开始就被正式纳入,但一些老旧的编译器或特定的编程环境可能不完全支持 const 的所有用法。此外,const 在 C 语言中对于编译器的优化和防止运行时错误(如意外修改常量值)的帮助可能不如 C++ 中那么显著。因此,在需要确保常量在编译时就被固定,并且希望这种固定性在编译器的优化和错误检查中得到体现时,使用 #define 可能是一个更安全的选择。然而,#define 也存在一些缺点,比如没有类型检查,可能会导致宏展开后的代码难以理解和维护。因此,在选择使用哪种方式定义常量时,需要根据具体情况进行权衡。 


2 变量

        变量代表内存中具有特定属性的一个存储单元,它用来存放数据,即变量的值。这些值在程序的执行过程中是可以改变的

2.1 变量名的作用

        变量名实际上以一个名字代表一个对应的存储单元地址,也称为标识符。编译、链接程序时,由编译系统为每个变量名分配对应的内存地址(就是空间)。

        变量名本身并不直接存储在内存中,存储在内存中的是变量的值以及与之相关联的元数据(如类型信息、作用域等)。

        变量名是在编译过程中由编译器处理的,用于在源代码中引用变量。一旦程序被编译成机器代码,变量名就不再需要了,取而代之的是变量的内存地址

        从变量中取值实际上是通过变量名找到内存中存储单元的地址,并从该存储单元中读取数据。

2.2 变量的命名规范

        C 语言规定标识符只能由字母、数字和下画线三种字符组成,并且第一个字符必须为字母或下画线(即数字不能开头。例如:

正确的变量命名示例:
studentName1:以字母开头,后跟字母和数字的组合,符合 C 语言的命名规则。
ageOfStudent:清晰表达了变量的用途(学生的年龄),且完全由字母、数字和下划线组成。
_isFirstTime:以下划线开头,用于表示某种特殊含义的变量(如全局变量或成员变量)。
maxScore:简短且描述性强,用于表示最高分。
total_sales:使用下划线分隔单词,提高了变量的可读性。

错误的变量命名示例:
2stYear:以数字开头,违反了 C 语言的命名规则。
my-age:包含连字符,不是有效的 C 语言标识符。
temp temp:包含空格,不是有效的 C 语言标识符。
M.DJohn:包含点,不是有效的 C 语言标识符。
¥123:包含¥,不是有效的 C 语言标识符。
a>b:包含>,不是有效的 C 语言标识符。

不建议的变量命名示例:
class:虽然不是 C 语言的关键字,但它是许多编程语言中的关键字,用作变量名可能会引起混淆。
intScore:尽管这里 intScore 本身是一个合法的标识符,但它看起来像是一个类型声明(int Score),这可能会导致代码阅读者的混淆。在命名变量时,应避免使用与类型名相似的名称。

2.3 变量的命名原则

        大小写敏感性:C 语言的编译系统严格区分大写字母和小写字母,这意味着 myVariable 和  MyVariable 会被视为两个不同的变量。

        先定义后使用:在 C 语言中,所有变量在使用之前必须先进行定义。这是编程的基本规则之一,有助于编译器理解变量的类型和作用域。变量定义告诉编译器变量的类型,并为其分配存储空间

        避免与关键字同名:在选择变量名时,必须避免与上文提到的关键字重名,否则会导致编译错误。

        见名知意:选择变量名和其他标识符时,应尽可能遵循 “见名知意” 的原则。这意味着变量名应该能够直观反映其用途或内容,使用具有含义的英文单词(或其合理的缩写)作为标识符,以提高代码的可读性和可维护性。

2.4 大小驼峰命名法

        大驼峰命名法(UpperCamelCase):每个单词的首字母都大写,不使用下划线连接单词例如,MyVariable、ThisIsAnExample。在 C 语言中,这种风格可能不太常见用于变量命名,但可能会用于常量、宏定义或全局变量的命名,以区别于局部变量和函数参数。

        小驼峰命名法(lowerCamelCase):第一个单词的首字母小写,之后每个单词的首字母大写,不使用下划线连接单词例如,myVariable、thisIsAnExample。在 C 语言中,这种风格更常用于变量命名,因为它既清晰又易于阅读。

        需要注意的是,C 语言中的宏定义(使用 #define 指令)和枚举常量(使用 enum 关键字)通常使用全大写字母和下划线(如 MAX_VALUE、ERROR_CODE)来命名,以区别于变量和函数。

  • 16
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 支持向量机非线性回归通用MATLAB程序解析 #### 一、概述 本文将详细介绍一个基于MATLAB的支持向量机(SVM)非线性回归的通用程序。该程序采用支持向量机方法来实现数据的非线性回归,并通过不同的核函数设置来适应不同类型的数据分布。此外,该程序还提供了数据预处理的方法,使得用户能够更加方便地应用此程序解决实际问题。 #### 二、核心功能与原理 ##### 1. 支持向量机(SVM) 支持向量机是一种监督学习模型,主要用于分类和回归分析。对于非线性回归任务,SVM通过引入核技巧(kernel trick)将原始低维空间中的非线性问题转换为高维空间中的线性问题,从而实现有效的非线性建模。 ##### 2. 核函数 核函数的选择直接影响到模型的性能。本程序内置了三种常用的核函数: - **线性核函数**:`K(x, y) = x'y` - **多项式核函数**:`K(x, y) = (x'y + 1)^d` - **径向基函数(RBF)**:`K(x, y) = exp(-γ|x - y|^2)` 其中RBF核函数被广泛应用于非线性问题中,因为它可以处理非常复杂的非线性关系。本程序默认使用的是RBF核函数,参数`D`用于控制高斯核函数的宽度。 ##### 3. 数据预处理 虽然程序本身没有直接涉及数据预处理的过程,但在实际应用中,对数据进行适当的预处理是非常重要的。常见的预处理步骤包括归一化、缺失值处理等。 ##### 4. 模型参数 - **Epsilon**: ε-insensitive loss function的ε值,控制回归带宽。 - **C**: 松弛变量的惩罚系数,控制模型复杂度与过拟合的风险之间的平衡。 #### 三、程序实现细节 ##### 1. 函数输入与输出 - **输入**: - `X`: 输入特征矩阵,维度为(n, l),其中n是特征数量,l是样本数量。 - `Y`: 目标值向量,长度为l。 - `Epsilon`: 回归带宽。 - `C`: 松弛变量的惩罚系数。 - `D`: RBF核函数的参数。 - **输出**: - `Alpha1`: 正的拉格朗日乘子向量。 - `Alpha2`: 负的拉格朗日乘子向量。 - `Alpha`: 拉格朗日乘子向量。 - `Flag`: 标记向量,表示每个样本的类型。 - `B`: 偏置项。 ##### 2. 核心代码解析 程序首先计算所有样本间的核矩阵`K`,然后构建二次规划问题并求解得到拉格朗日乘子向量。根据拉格朗日乘子的值确定支持向量,并计算偏置项`B`。 - **核矩阵计算**:采用RBF核函数,通过`exp(-(sum((xi-xj).^2)/D))`计算任意两个样本之间的相似度。 - **二次规划**:构建目标函数和约束条件,使用`quadprog`函数求解最小化问题。 - **支持向量识别**:根据拉格朗日乘子的大小判断每个样本是否为支持向量,并据此计算偏置项`B`。 #### 四、程序扩展与优化 - **多核函数支持**:可以通过增加更多的核函数选项,提高程序的灵活性。 - **自动调参**:实现参数自动选择的功能,例如通过交叉验证选择最优的`Epsilon`和`C`值。 - **并行计算**:利用MATLAB的并行计算工具箱加速计算过程,特别是当样本量很大时。 #### 五、应用场景 该程序适用于需要进行非线性回归预测的场景,如经济预测、天气预报等领域。通过调整核函数和参数,可以有效应对各种类型的非线性问题。 ### 总结 本程序提供了一个支持向量机非线性回归的完整实现框架,通过灵活的核函数设置和参数调整,能够有效地处理非线性问题。对于需要进行回归预测的应用场景,这是一个非常实用且强大的工具。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Thanks_ks

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值