加载中...
从零接触C语言-II: 数据类型 和 变量

从零接触C语言-II: 数据类型 和 变量

周二 7月 08 2025
3747 字 · 16 分钟

C语言的数据类型 和 变量

在上一篇文章中, 举了一个最简单的C语言例子:

C
#include <stdio.h>

int main() {
    printf("Hello World");
    
    return 0;
}

通过在main()函数中调用printf("Hello World");打印出来了Hello World

printf()是函数, 那么"Hello World"是什么呢?

在C语言中, 凡是被双引号""包裹的字符, 被称为字符串, 也叫字符串字面量

无论里面是英文字符、数字、符号, 甚至是中文字符, 只要被双引号括起来, 它就是一个字符串

例如: "123""2.333""###""你好""Hello" 都是字符串, 哪怕只是 "1"" ""h" 这样的单字符内容, 也依然是字符串

甚至连 "" 这样什么都没有的内容, 也是一个合法的字符串, 称为空字符串

不过, 字符串实际是由一个个”字符”按顺序组成的

C
"Hello"'H' 'e' 'l' 'l' 'o'组成

C语言中, 单个字符通常使用单引号 '' 包裹, 比如 'A''1''%' 等. 这些字符会被存储为一种特定的数据类型: char 类型

char类型之外, C语言中还有其他基本数据类型:

C
// 空类型
void
// 字符类型
char
// 短整型
short
// 整型(整数类型)
int
// 长整型
long
// 更长的整型
long long
// 单精度浮点数(单精度小数)
float
// 双精度浮点数(双精度小数)
double
// 扩展精度浮点数(不常用)
long double

这就是C语言中所有的基本数据类型了

你会发现, 这里边并没有字符串类型

实际上, C语言中字符串并不是一种单独的数据类型, 字符串是由字符组成的一种类型

变量

C语言中, 你可以使用这些数据类型, 定义并使用变量

什么是变量?

从字面上看, “变量”就是可以变化的量, 即值会发生变化的数据

而在编程语言中, 并不是这么简单的, 不过也可以 以一种简单的视角理解变量:

可以将变量, 当作一个有名字的”盒子”

这个盒子有特定的大小(由数据类型决定), 我们可以把数据放进去, 也可以随时拿到数据使用或替换成新的数据

在C语言中, 变量 具体的定义方式是这样的:

C
char character = 'c';
int age = 20;
float weight = 55.5;

character age weight即为不同类型、不同大小的变量, 把变量当成一个”盒子”来看, 这些盒子可以存储对应类型大小的数据, 这里的大小指的是bit(位)byte(字节)

character age weight就是变量的名字, 'c'就是放在character中的数据, 20就是放在age中的数据, 55.5就是放在weight中的数据

已经放在变量中的数据, 在之后的代码中, 就可以直接通过变量名来使用了, 比如:

C
#include <stdio.h>

int main() {
    int age1 = 18; // 变量age1, 放入数字18
    int age2 = 20; // 变量age2, 放入数字20
    printf("age1 加 age2 和为 %d\n", age1 + age2);

    return 0;
}

这段代码的执行结果为:

在C语言程序中, 不同的数据类型, 占用的大小是不同的, 这意味着”盒子”的大小不同, 即 变量的大小不同

每种类型的大小, 具体如下表所示:

数据类型占用大小
char1 byte
short2 byte
int4 byte
long4/8 byte(根据平台编译器的具体实现决定)
long long8 byte
float4 byte
double8 byte
long double8/16 byte(根据平台编译器的具体实现决定)
void不是用来存储数据的类型, 可以看作是一种空类型占位符, 不能用于定义变量

这些数据类型具体的大小占用, 也可以通过代码的形式在程序中打印出来:

C
#include <stdio.h>

int main() {
    printf("char size: %lu\n", sizeof(char));
    printf("short size: %lu\n", sizeof(short));
    printf("int size: %lu\n", sizeof(int));
    printf("long size: %lu\n", sizeof(long));
    printf("long long size: %lu\n", sizeof(long long));
    printf("float size: %lu\n", sizeof(float));
    printf("double size: %lu\n", sizeof(double));
    printf("long double size: %lu\n", sizeof(long double));

    return 0;
}

这段代码, 使用gcc main.c将其编译为可执行程序并运行的结果是:

可以看到打印结果是符合上面表格中的内容的

变量的命名规则

已经大概了解了, 变量可以简单理解为 程序中, 一个命名的有大小的存储数据用的盒子

不过, 变量命名也是有一定规则的, 并不是可以随便给变量命名

C语言标准中, 标识符(变量名、函数名等)的命名规则如下:

  1. 只能包含以下字符:

    • 字母: a-zA-Z
    • 数字: 0-9
    • 下划线: _

    标准中并未提及中文字符命名的相关规则, 但编译器可能支持

  2. 首字符必须是字母或下划线

    即, 首字符不允许是数字

  3. 区分大小写

    即, ageAge不属于同一标识符

  4. 禁止与关键字冲突

    即, 标识符的命名禁止与C语言中的关键字完全一致

    有关 关键字 并非本章介绍内容

下面是一些变量命名的正确例子和错误例子:

C
/* 正确例子 */
int age;
int Age;
float weight1;
double _theFloat;
double Double;

/* 错误例子 */
int 2age;	// 首字符禁止为数字
int float;	// 禁止与关键字完全一致
float the-weight;	// 非法字符
double $float;	// 非法字符

变量的分类 以及 作用域和生命周期

C语言程序的入口是main()函数

那么, 即使是最简单的C语言程序, 也会分出两种区域:

C
/*
入口外, 即 main() 函数外
*/
int main() {
    /*
    入口内, 即 main() 函数内
    */
	return 0;
}
/*
入口外, 即 main() 函数外
*/

在之前的例子中, 变量都是在main()函数内部定义的

这里可能有一个问题出现: 变量可以在main()函数外部定义吗?

答案是可以

C语言中, 变量可以在main()函数外部定义

并且, 定义在main()函数内部和外部的变量, 是有一定区别的:

  1. main()函数外部定义的变量, 被称为全局变量

    在函数内部定义的变量, 被称为局部变量

  2. 全局变量的作用域, 一般为整个C 程序

    局部变量的作用域, 则只在定义局部变量所在的范围

    什么是变量的作用域?

    C语言中, 变量的作用域, 就是变量能被使用的有效范围

    比如, 在main()函数内定义的变量, 那这个变量的作用域就在main()函数的范围内, 出了main()函数就无法再使用

    实际上, 在C语言中一个{}声明一个代码块, 在代码块内定义变量, 此变量的作用域即为所在代码块

  3. 全局变量的生命周期, 为整个C 程序

    局部变量的生命周期, 为定义局部变量所在的范围

    变量的生命周期, 可以简单理解为变量的存活时间

    变量的生命周期, 一般是从变量完成定义到其所在作用域结束

  4. 全局变量和局部变量可以同名, 但在使用上 遵循就近原则

以实际的代码为例子:

C
#include <stdio.h>

int globalVar = 10; // 全局变量
int var = 20;		// 全局变量

int main() {
	printf("globalVar: %d\n", globalVar);
	printf("var: %d\n", var);

	int var = 30; // 局部变量
	printf("var: %d\n", var);

	{
		int _var = 40;
		int var = 50;
		printf("_var: %d\n", _var);
		printf("var: %d\n", var);
	}

	// printf("_var: %d\n", _var);
	printf("var: %d\n", var);

	return 0;
}

这段代码定义了很多个变量, 可以先来看一下执行结果:

我们可以结合现象, 分析一下每一句printf()所使用的变量是哪一个:

序号调用语句打印值值对应变量名是否有重名变量实际使用变量
17行: printf("globalVar: %d\n", globalVar);10globalVarglobalVar(第3行)
28行: printf("var: %d\n", var);20varvar(第4行)
311行: printf("var: %d\n", var);30varvar(第10行)
416行: printf("_var: %d\n", _var);40_var_var(第14行)
517行: printf("var: %d\n", var);50varvar(第15行)
621行: printf("var: %d\n", var);30varvar(第10行)

从结果来看, 可以分析出一些特性:

  1. 全局变量和局部变量可以重名

    编译没有问题, 运行也没有问题

  2. 变量的使用, 遵循就近原则

    即, 如果存在重名变量, 使用时 会使用已经定义的, 离调用位置近的变量

    在例子中表现为:

    局部变量var没有定义时, 使用var变量, 实际使用的是全局变量var

    局部变量var定义后, 使用var变量, 实际使用的是局部变量var

  3. 变量只在其作用域内生效

    即, 变量出了其作用域, 其生命周期就会结束, 无法再使用

    在例子中的表现为:

    17行打印的var值是50, 而第21行打印的var值是30

    如果把第20行代码的注释解开(删掉//), 编译会报错:

    报错信息为: _var未声明


总结来讲, 究竟什么是变量?

变量是一个命名的存储单元, 它可以用来存储程序运行过程中可能发生变化的数据

它有: 名字(标识符)、类型(数据类型决定它能存什么数据)、大小(由类型决定)、作用域(在哪能访问)、生命周期(存在多久)

还有这些特点:

  1. 类型明确:每个变量都有明确的数据类型(如 intfloat 等)

  2. 内存占用不同:不同类型的变量占用不同的字节数

  3. 命名有规则

    只能由字母、数字和下划线组成,且不能以数字开头

    不能与C语言中的关键字完全一致

  4. 作用域限制

    全局变量在程序内全局有效

    局部变量只能在其定义的代码块中有效。

  5. 生命周期不同

    局部变量:随函数或代码块执行完毕而消失

    全局变量:存在于整个程序生命周期

  6. 支持赋值与修改:变量可以在程序中多次赋新值

  7. 使用需先定义:C语言要求变量在使用前必须先定义

const修饰变量

const是C语言标准中的一个关键字, 它是单词constant(常量)的简写

const在C语言中可以在定义变量时放在类型前修饰变量, 让变量具有常量属性, 即const修饰变量, 可以使变量的值无法改变

来看下面的代码:

C
#include <stdio.h>

int main() {
    int var = 10;
    const int con = 20;
    /*
    定义变量时, cosnt 放在类型前 修饰变量
    */

    printf("var: %d\n", var);
    printf("con: %d\n", con);

    return 0;
}

这段代码的执行结果很明显:

但是如果你试图修改con:

C
#include <stdio.h>

int main() {
    int var = 10;
    const int con = 20;
    con = 11;

    printf("var: %d\n", var);
    printf("con: %d\n", con);

    return 0;
}

那么, 编译就会发生报错:

报错信息为: 试图给只读变量con赋值

可以看到, const修饰的变量, 具有了常量属性, 无法修改, 只能读取


Thanks for reading!

从零接触C语言-II: 数据类型 和 变量

周二 7月 08 2025
3747 字 · 16 分钟