【C/C++】系列文章目录
文章目录
前言
C程序中数据以变量、常量表示,它们都具有类型属性。
一、变量
变量-可以改变的量。如:身高,体重,年龄等。变量本质上指代存储数据的内存单元。在一个C程序中,一个变量有且仅有一个定义。变量的定义用于为变量分配存储空间。在定义变量时,建议为其指定初始值。
定义变量:
int age = 10;//定义变量age为int整型,初始值为10
变量声明用来表明变量的类型和名字,通过使用extern关键字声明变量名。由上可看出:定义变量时已经声明了它的类型和名字。
在不同源文件之间,使用其他源文件定义的变量,需要使用extern关键字先声明变量的类型和名字。使用方法如下:
- 在global.c中定义num为int整型变量,指定初始值为12
- 在test.c中使用extern声明num是一个整型变量
- 在test.c的main函数中使用num变量
二、常量
常量-不可以改变的量。如:圆周率,性别,血型等。
1.常量分类
1)字面常量
字面量是指数据在原程序中直接以值的形式呈现,在程序运行终不能被修改,表现为整型、浮点型和字符串类型。
int main()
{
'a';//字符字面量
"hello";//字符串字面量
'\n';转义字符字面量
3.14;//字面量
1000;//字面量
return 0;
}
2)const修饰的常变量
const修饰的常变量具有常属性——即不能被改变的属性,但本质上是一个变量。
int main()
{
//const 修饰的常变量
const float pi = 3.14f; //这里的pai是const修饰的常变量
pi = 5.14;//报错,pi是不能直接修改的!
return 0;
}
数组定义时指定的数组的大小为常量表达式,使用const修饰的常变量不能被使用,说明const修饰的常变量本质仍然是一个变量。
3)#define定义的标识符常量
由const可对比出,#define定义的标识符常量可以被定义数组大小时使用。
4)枚举常量
枚举就是把这种类型数据可取的值逐一列举出来。枚举类型是一种用户自定义的数据类型。一般定义形式为:
enum 枚举类型名
{
标识符[=整型常数],
标识符[=整型常数],
……
标识符[=整型常数]
}
//举例
enum Sex
{
MALE,
FEMALE,
SECRET
};
//括号中的MALE,FEMALE,SECRET是枚举成员
int main()
{
//枚举常量演示
printf("%d\n", MALE); //0
printf("%d\n", FEMALE); //1
printf("%d\n", SECRET); //2
//注:如果没有为枚举成员指定初值,编译系统为每一个枚举成员赋予一个不同的整型值,第一个成员的值默认是从0开始,依次向下递增1的
return 0;
}
注:如果没有为枚举成员指定初值,即省掉了标识符后的“=整型常数”时,编译系统为每一个枚举成员赋予一个不同的整型值,第一个成员的值默认是从0开始,依次向下递增1的。当枚举类型中的某个成员赋值后,其后的成员则按依次加1的规则确定其值。
enum Color
{
RED=5,
BLUE,
GREEN,
YELLOW=100,
PINK,
BLACK
};
int main()
{
printf("%d\n", RED); // 5
printf("%d\n", BLUE); // 6
printf("%d\n", GREEN); // 7
printf("%d\n", YELLOW); // 100
printf("%d\n", PINK); // 101
printf("%d\n", BLACK); // 102
return 0;
}
三、变量的作用域和生命周期
变量分为全局变量和局部变量。
1.全局变量
全局变量为在代码块外部定义的变量。
2.局部变量
局部变量为在代码块(大括号)内部定义的变量。
int g_val = 68;//全局变量-在代码块外部
int main()
{
int x = 58;//局部变量-在代码块内部
{
int y = 99;//局部变量-在代码块内部
}
return 0;
}
注:作用域可嵌套。
3.作用域
通常来说,一段程序写代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。
C程序中的名字有全局作用域,局部作用域之分,作用域是可以嵌套的。
尽可能将变量定义(声明)在最小的作用域内,并且为其设置初始值。
4.生命周期
int g_val = 68;//全局变量
int main()
{
printf("%d\n", g_val); //68
int x = 58;//局部变量
printf("%d\n", x); //58
{
printf("%d\n", g_val); //68
int y = 99;//局部变量
printf("%d\n", x); //58
printf("%d\n", y); //99
}
printf("%d\n", g_val); //68
printf("%d\n", y); //报错
return 0;
}
以上代码可看出,全局变量g_val在整个工程中可以使用,而x,y分别为局部变量,它们在定义各自的大括号包含的范围内(即作用域内)可以使用。出了定义的大括号范围,就被销毁无法使用了。
四、字符串和转义字符
1.字符字面量是由一对单引号括起来的,如:'A','B'……
2.字符串是用一对双引号括起来的零个或多个字符,即一个连续的字符系列,用特殊字符'\0'结尾。如:"hello","I am very excellent.“……
注:编译系统自动在每一字符串常量的结尾增加'\0'结尾符。所以“A"和‘A’是不同的,"A"是由两个字符(字符'A'和字符'\0')组成的,而‘A’只有一个字符。空字符串“”仅由一个结尾字符'\0'组成。
3.数组是一种集合数据类型,由多个相同数据类型的元素组成,每个元素占有相同大小的存储单元,且在内存中连续存放。当数组中的元素有字符组成时,便称为字符数组。
注:使用printf打印函数须引用<stdio.h>头文件,使用strlen计算字符串长度函数须引入<string.h>头文件。strlen计算长度不计算'\0'。
1.双引号括起来的字符串编译系统自动追加'\0'结束符,所以打印str1为abc。
2.str2中没有结束符'\0',所以printf打印和strlen计算长度时一直到找到字符'\0'为止,str2长度也变成随机值15.
3.str3手动添加了结束符'\0',所以效果同str1一致。
4.综上,双引号括起来的字符串字面量系统自动追加结束符'\0',字符串的结束标志是一个 \0 的转义字符。在计算字符串长度的时候 \0 是结束标志,不算作字符串内容。
2.转义字符
转义字符即转变了字符原来的意思。
\t,\32解析为一个字符。
转义字符 | 释义 |
\? | 在书写连续多个问号时使用,防止他们被解析成三字母词 |
\' | 用于表示字符常量 ' |
\" | 用于表示一个字符串内部的双引号 |
\\ | 用于表示一个反斜杠,防止它被解释为一个转义序列符 |
\a | 警告字符,会产生蜂鸣 |
\b | 退格符 |
\f | 进纸符 |
\n | 换行 |
\r | 回车 |
\t | 水平制表符 |
\v | 垂直制表符 |
\ddd | ddd表示1~3个八进制的数字。如:\130 ---> X |
\xdd | dd表示2个十六进制数字。如:x30 --> 0 |
\130解析为十进制数为1*8^2+3*8^1+0*8^0=88,ASCII值为88对应的字符为X。
\x30解析位十六进制数为3*16^1=48,ASCII值为48对应的字符为0。
总结
区分变量,常量的定义,全局变量和局部变量的作用域范围和生命周期,以及全局作用域和局部作用局。
区分字符和字符串,字符串的结束标志是一个 \0 的转义字符。在计算字符串长度的时候 \0 是结束标志,不算作字符串内容。打印字符串时要注意转义字符。