C语言目录:
3.1 常量
常量表示一些固定的数据,也就是不能改变的数据
3.1.1 整型常量
十进制整数
八进制整数:以0开头
十六进制:以0X开头
二进制:以0b开头
a. 小数形式
单精度小数:以字母f或者F结尾
双精度小数:lf结尾,默认类型
0.x 可以没有整数位只有小数位,如 .3
、.6f
b. 指数形式
以幂的形式表示,以字母e或者字母E后跟一个10为底的幂数
如:1.23×10在C语言中表示为 1.23e5
- e或E后前后必须有数字
- e或E前后不能有空格
3.1.3 字符常量
字符常量都是用 ''
括起来的
字符常量只能有一个字符
转义字符
'\n'
'\r'
3.1.4 字符串常量
字符型常量都是用 ""
括起来的
系统会自动在字符串常量末尾添加一个字符 '\0'
表示字符串结束标志
3.1.5 常量关键字
const
是一个类型修饰符:使用const
修饰变量可以让变量的值不能改变
-
用
const
修饰的常量不可改变const int MaxSize = 10; int Array[MaxSize];
-
编译器知道被
const
修饰的常量不允许被修改void fn(const int i){}
可以避免模糊的数字的出现,防止意外修改,增加程序健壮性
-
可以很方便地进行参数的调整和修改,与宏定义一样,一个修改全部修改
-
可以节省空间,避免不必要的内存分配
# define PI 3.14 int main(){ double A = PI;//编译期间进行宏代换,分配一次内存 double B = PI;//再次分配内存 return 0; } // 宏定义给出的是立即数,所以调用一次需要分配一次内存
const double PI = 3.14; int main(){ double A = PI;//此时为A分配内存,以后不再分配 double B = PI;//此时不再分配内存 return 0; } //const修饰的常量在程序运行中只有一份拷贝,是地址传递 //编译器通常不为 const 变量分配存储空间,而是将它们保存在符号表中, //使得它称为一个编译期间的常量,没有存储与读内存的操作,提高了效率
a. const的使用
const
修饰什么看左侧邻接什么
-
左侧是
数据类型
,则修饰值,此时内容不可修改数据类型 const
与const 数据类型
等价 -
左侧是
*
,则修饰指针,此时指向不能修改
基本数据类型
int const x = 2;
const int x = 2;
若想要获得可以修改的常量,用 const
修饰指针,改变指针指向的存储空间中的内容即可
int a = 10;
// a = 5;//报错
const int *p = &a;
*p = 5;//此时不报错
修饰常数组
int const a[5] = {1,2,3,4,5};
const int a[5] = {1,2,3,4,5};
a[1] = 77;//报错
修饰函数的形参
void fn(const int a){
//告诉编译器,函数体中不能改变形参a的值
...
}
修饰函数返回值
const int fn(int a){}
//告诉编译器,函数的返回值不能修改
修饰常指针
int a = 10;
int b = 5;
//const修饰指向的内容,指向可变,内容不可变
int const *A;//与 const int *A; 等价
A = &b;
*A = 5;//报错
//const修饰指针,指向不可变,内容可变
int *const A;
A = &b;//报错
*A = 5;
//const修饰指针和内容,指向和内容都不可变
const int *const A;
A = &b;//报错
*A = 5;//报错
3.2 变量
只有定义了变量才会分配数据的存储空间
不同数据类型占用不同大小的存储空间,指定数据类型,则这段存储单元只能存该类型的数据
3.2.1 变量定义格式
# 变量类型 变量名称;
int a;
float b;
char ch;
# 变量类型 变量名称,变量名称;
int a,b,c;
3.2.2 命名规则
- 首字母必须是 字母或下划线
- 只能包含字母、数字、下划线
- 标识符不能是关键字
- 不能跨行书写
3.2.3 变量的初始化
变量的第一次赋值称为初始化
# 先定义后初始化
int value;
value = 998;
# 定义用时初始化
int a = 10;
a. 未初始化的变量
- 随机数
- 上次程序分配的存储空间留下的 “垃圾值”
- 系统正在使用的一些数据
b. 变量之间的值传递
可以将一个变量存储的值赋给另一个变量
int a = 10;
int b = a;//相当于把a中存储的10拷贝了一份给b
3.2.4 作用域
变量的可用范围
a. 局部变量
定义在函数内部的变量以及函数的形参
作用域范围:从定义开始,到 }
为止或者遇到 return
为止
生命周期:从程序运行到定义哪一行开始分配存储空间到程序离开该变量所在的作用域
存储位置:局部变量会存储在内存的栈内
注意:
- 相同作用域内不可定义同名变量
- 不同作用范围可以定义同名变量,内部作用域的变量会覆盖外部作用域的变量
- 若要扩充作用域使用
extern
b. 全局变量
定义在函数外的变量
作用域范围:从定义开始到源文件结束
生命周期:程序一启动就会分配存储空间,直到程序退出
存储位置:静态存储区
特点:
- 多个同名的全局变量指向同一块存储空间
- 全局变量任意函数都可访问、修改
c. 只能修饰局部变量的关键字
auto
:只能修饰局部变量,局部变量如果没有其他修饰符,默认是 auto
特点:用时开辟,用完销毁
auto int num; // 等价于 int num;
register
:只能修饰局部变量,将内存中的变量提升到CPU寄存器中存储,提高访问速度
- 通常不同平台和编译器在优化阶段会自动转换为
auto
register int num;
d. static
变量
对局部变量的作用:延长局部变量的生命周期(从程序启动到程序退出),不扩充作用域
- 定义变量的代码在整个程序运行期间仅仅会执行一次
#include <stdio.h>
int main(){
for(int i = 0;i < 3;++i){
static int num = 1;
printf("%d\n",num++);
}
// 如果不加static输出 1 1 1
// 如果添加static输出 1 2 3
// printf("%d\n" ,num);
return 0;
}
对全局变量的作用:约束作用域 ,用
static
标注的变量不能在其他源文件中使用,且不和其他源文件的同名全局变量共享同一块存储空间
-
内部变量:只能在本源文件中访问的变量
-
外部变量:可以在其他文件中访问的变量(默认)
默认情况下,多个同名的外部变量会共享同一块存储空间
# A文件中的代码
# "a.h"
int num;
void test(){
printf("%d\n",num);
}
---
# B文件中的代码
# "b.c"
# include<stdio.h>
# "a.h"
int main(){
num = 10;
test(); //10
return 0;
}
# A文件中的代码
# "a.h"
static int num;
void test(){
printf("%d\n",num);
}
---
# B文件中的代码
# "b.c"
# include<stdio.h>
# "a.h"
int main(){
num = 10;
test(); //0
return 0;
}
函数
内部函数:只能在当前源文件中访问的函数
外部函数(默认):在所有源文件中都可访问的函数
static
对于函数的作用是声明或定义一个内部函数
static int sum(int n1,int n2);
static int sum(int num1,int num2){
return n1 + n2;
}
e. extern
变量
extern
表示声明一个变量,而不是定义一个变量
局部变量:不可作用域局部变量,会报错
全局变量:声明一个全局变量,告诉编译器在其他地方已经定义了这个变量
#include <stdio.h>
int main(){
extern int num; // 声明我们有名称叫做num变量
num = 996; // 使用时已经有对应的存储空间
printf("num = %i\n", num);
return 0;
}
int num; // 全局变量, 程序启动就会分配存储空间
函数
默认情况都是外部函数,所以省略 extern
extern int sum(int n1,int n2);
extern int sum(int n1,int n2){
return n1 + n2;
}
由于默认情况下所有的函数都是外部函数,所以 extern
一般会省略
如果只有函数声明添加了 static
与 extern
,而定义时没有添加,则无效