今日目标
- 了解常量和字面量的概念及其用法。
- 掌握存储类别及其在变量和函数中的应用。
- 每日练习
常量和字面量
常量
常量是指其值在程序执行过程中不会改变的量。常量有以下几种类型:
1. 整型常量
整型常量用于表示整数值。
const int age = 30; // 整型常量
2. 浮点型常量
浮点型常量用于表示带小数点的数值。
const float pi = 3.14; // 浮点型常量
3. 字符常量
字符常量用于表示单个字符,用单引号括起来。
const char initial = 'A'; // 字符常量
4. 字符串常量
字符串常量用于表示字符串,用双引号括起来。
const char* name = "Alice"; // 字符串常量
字面量
字面量是指直接出现在代码中的固定值。常见的字面量有以下几种:
1. 整数字面量
整数字面量可以是十进制、八进制或十六进制。
int decimal = 100; // 十进制
int octal = 0144; // 八进制
int hex = 0x64; // 十六进制
2. 浮点数字面量
浮点数字面量可以是小数形式或指数形式。
float num1 = 3.14;
float num2 = 3.14e2; // 等于314
3. 字符字面量是单个字符,用单引号括起来。
字符字面量是单个字符,用单引号括起来。
char ch = 'A';
4. 字符串字面量是由双引号括起来的字符串。
字符串字面量是由双引号括起来的字符串。
char str[] = "Hello, World!";
char* str1="hello world"
存储类别
存储类别定义了变量和函数的作用域(可见性)和生命周期。C语言中有以下几种存储类别:
1. 自动变量(auto)
自动变量是局部变量,在函数或代码块内声明,默认存储类别为auto。
void function() {
auto int localVar = 10; // 自动变量
}
2. 寄存器变量(register)
寄存器变量建议编译器将变量存储在CPU寄存器中,以提高访问速度。
void function() {
register int counter = 0; // 寄存器变量
}
3. 静态变量
静态变量在程序的生命周期内保持其值不变,可以是局部静态变量或全局静态变量。
局部静态变量
void function() {
static int count = 0; // 局部静态变量
count++;
printf("Count: %d\n", count);
}
全局静态变量
static int globalVar = 0; // 全局静态变量
void function() {
globalVar++;
printf("GlobalVar: %d\n", globalVar);
}
静态变量的生命周期和程序是一致的,定义局部的静态变量后,变量不会随方法的出栈而销毁,而非静态的局部变量会随方法的出栈而销毁
如下代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <Windows.h>
int* test1() {
int a = 1;
printf("%p\n", &a);
// 为了演示效果,加上下面代码
// 不同机器运行速度不通,有可能无法复现问题,可以多循环几次
for (int i = 0; i < 100; i++){
printf("");
}
return &a;
}
int* test2() {
static int b = 2;
printf("%p\n", &b);
for (int i = 0; i < 100; i++) {
printf("");
}
return &b;
}
int main() {
int* p1 = test1();
int* p2 = test2();
printf("p1:%p,p1 value:%d\n", p1, *p1);
printf("p2:%p,p2 value:%d\n", p2, *p2);
}
运行结果
00EFF68C
009FA000
p1:00EFF68C,p1 value:-858993460
p2:009FA000,p2 value:2
可以看到,在函数外获取指针p1的值时已经不是预期的1了,而是变成一串不知道是啥的数字,而p2的值仍然是2
也就是说,在main方法中,非静态变量p1出栈已经被销毁,而静态变量p2在出栈后仍然存活
4. 外部变量
外部变量在一个文件中声明,但可以在其他文件中使用。
// 在file1.c中
int globalVar = 100; // 全局变量
// 在file2.c中
extern int globalVar; // 外部变量声明
void function() {
printf("GlobalVar: %d\n", globalVar);
}
需要注意的是,使用extern时,不能有两个同名的变量,否则会报错
例如file1.c中有一个int globalVar,file2.c中也有一个int globalVar
此时在file3.c中使用extern int globalVar则会出现如下报错
_globalVar 已经在 file1.obj 中定义
找到一个或多个多重定义的符号
每日练习
- 编写一个程序,定义各种类型的常量和字面量,并输出它们的值。
#include <stdio.h>
int main() {
// 整型常量
const int intConst = 100;
int intLiteral = 1234;
// 浮点型常量
const float floatConst = 3.14;
float floatLiteral = 3.14e2;
// 字符常量
const char charConst = 'A';
char charLiteral = 'B';
// 字符串常量
const char* stringConst = "Hello, World!";
char stringLiteral[] = "C Programming";
// 输出常量和字面量的值
printf("Integer Constant: %d\n", intConst);
printf("Integer Literal: %d\n", intLiteral);
printf("Float Constant: %.2f\n", floatConst);
printf("Float Literal: %.2f\n", floatLiteral);
printf("Char Constant: %c\n", charConst);
printf("Char Literal: %c\n", charLiteral);
printf("String Constant: %s\n", stringConst);
printf("String Literal: %s\n", stringLiteral);
return 0;
}
运行结果
Integer Constant: 100
Integer Literal: 1234
Float Constant: 3.14
Float Literal: 314.00
Char Constant: A
Char Literal: B
String Constant: Hello, World!
String Literal: C Programming
- 编写一个程序,演示自动变量、寄存器变量、静态变量和外部变量的使用,并观察它们的生命周期和作用域。
file1.c
#include <stdio.h>
// 全局变量
int globalVar = 0;
// 函数声明
void demonstrateStorageClasses();
int main() {
printf("In main function\n");
demonstrateStorageClasses();
demonstrateStorageClasses();
return 0;
}
file2.c
#include <stdio.h>
// 外部变量
extern int globalVar;
void demonstrateStorageClasses() {
// 自动变量
int autoVar = 0;
autoVar++;
// 寄存器变量
register int registerVar = 0;
registerVar++;
// 局部静态变量
static int staticVar = 0;
staticVar++;
// 修改全局变量
globalVar++;
printf("Auto Variable: %d\n", autoVar);
printf("Register Variable: %d\n", registerVar);
printf("Static Variable: %d\n", staticVar);
printf("Global Variable: %d\n", globalVar);
}
运行结果
In main function
Auto Variable: 1
Register Variable: 1
Static Variable: 1
Global Variable: 1
Auto Variable: 1
Register Variable: 1
Static Variable: 2
Global Variable: 2