前言
书接上回,本文将继续了解C语言的基础知识,主要内容有:
- 变量、常量
- 字符串、转义字符
- 注释
- 分支和循环语句
4. 变量、常量
5).变量的作用域和生命周期
1)). 作用域
作用域(scope)是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/可用的而限定这个名字的可用性的代码范围就是这个名字的作用域。
- 局部变量的作用域是该变量所在的局部范围。
#include <stdio.h>
int main()
{
{
int a = 100;//a和b都是局部变量
int b = 233;
printf("%d\n", a);//显然在屏幕上只能打印出a的值100
}//代码块(局部范围)
printf("%d\n", b);//err //“b”:未声明的标识符(报错)
return 0;
}//局部变量的作用域是该变量所在的局部范围
- 全局变量的作用域是整个工程。
例1:
#include <stdio.h>
int g_a;//声明
void test()
{
printf("test:%d\n", g_a);
}
int g_a = 2022;//定义
int main()
{
printf("%d\n", g_a);
test();//调用函数
return 0;
}//全局变量的作用域是整个工程
例2:
#include <stdio.h>
//extern是用来声明外部符号
extern int g_a;
int main()
{
printf("%d\n", g_a);
return 0;
}//全局变量的作用域是整个工程
2)). 生命周期
变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段。
- 局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。
#include <stdio.h>
int main()
{
//局部变量的生命周期
{//进入作用域开始
int a = 10;
printf("test1: %d\n", a);
}//出作用域结束
printf("test2: %d\n", a);//err
return 0;
}
- 全局变量的生命周期是:整个程序的生命周期。
全局变量在一个工程(项目)内的各个源文件内都可以使用(extern – 声明外部符号),在主函数的整个范围内都可以使用。
6). 常量
C语言中,不变的值用常量的概念来表示,可变的值用变量的概念来表示。常量和变量的定义的形式有所差异。
C语言中的常量分为以下以下几种:
- 字面常量
- "const"修饰的常变量
- "#define"定义的标识符常量
- 枚举常量
1)). 字面常量
//字面常量
100;//整型
3.14;//浮点
'a';//字符
"abcdef";//字符串
2)). "const"修饰的常变量 – 带有常属性的变量
int main()
{
//1. const修饰变量num,让其带有常属性
const int num = 100;
//num被const修饰,带有常属性,从C语言语法层面上不能被修改
num = 200;//err//此时num是不可修改的值
printf("%d\n", num);
//2. 常变量是带有常属性的变量,本质上还是变量
int n = 10;
int arr[n] = { 0 };//err//数组的[]内应输入常量表达式
int arr[10] = { 0 };//正确创建数组
//我们可以用这个思路来验证:
int arr[num] = { 0 };//err//说明常变量本质上还是变量
return 0;
}
3)). "#define"定义的标识符常量
#include <stdio.h>
#define M 100
int main()
{
//用两种思路来验证 "#define"定义的标识符是常量
//1. 数组的[]内应输入常量表达式
int arr[M] = { 0 };
printf("%d\n", M);
//2. 赋值操作符'='的左操作数必须是可修改的值,而非常量
M = 200;//err
return 0;
}
4)). 枚举常量 – enum
枚举(enum),即为一一列举。像血型、性别、三原色这些可以被一一列举出所有可能取值的不变的值可以用枚举常量来表示。
#include <stdio.h>
enum Color
{
//RED,GREEN,BLUE是枚举类型Color的可能取值,同时也是常量,所以叫枚举常量
RED,//0
GREEN,//1
BLUE//2
//编译器默认给的初始值
};
int main()
{
enum Color c = BLUE;
int a = 0;
//这三个常量的值都是整型,以%d格式打印
printf("%d\n", RED);
printf("%d\n", GREEN);
printf("%d\n", BLUE);
RED = 100;//err//用赋值操作符证明RED是常量
return 0;
}
5. 字符串、转义字符
1). 字符串
“hello world\n”
这种由双引号(Double Quote)引起来的一串字符称为字符串字面值(String Literal),或者简称字符串。
- 字符串的结束标志是一个’\0’的转义字符。
#include <stdio.h>
int main()
{
//一个字符类型变量只能存储一个字符
char ch = 'w';
//要存储多个字符/字符串应创建一个数组
char ch1[] = { 'a', 'b', 'c' };
char ch2[] = {"abc"};
char ch3[] = {'a', 'b', 'c', '\0'};
//%s -- 打印字符串 -- 打印到'\0'才停止
printf("%s\n", ch1);
printf("%s\n", ch2);
printf("%s\n", ch3);
return 0;
}//'\0'是字符串的结束标志
- 在计算字符串长度的时候 '\0’是结束标志,不算作字符串内容。
#include <stdio.h>
#include <string.h>//包含头文件,调用strlen函数
int main()
{
char ch1[] = { 'a', 'b', 'c'};
char ch2[] = "abc";
int len1 = strlen(ch1);//warn
//没有为字符串"ch1"添加字符串零终止符'\0'
int len2 = strlen(ch2);
printf("%d\n", len1);//随机值
printf("%d\n", len2);//3
return 0;
}
2). 转义字符
转义字符,顾名思义就是转变原来的意思。
转义字符 | 释义 |
---|---|
\? | 在书写连续多个问号时使用,防止其被解析成三字母词 |
\’ | 用于表示字符常量’ |
\" | 用于表示一个字符串内部的双引号 |
\\ | 用于表示一个反斜杠,防止它被解释为一个转义序列符 |
\a | 警告字符,蜂鸣 |
\b | 退格符 |
\f | 进纸符 |
\n | 换行 |
\r | 回车 |
\t | 水平制表符 |
\v | 垂直制表符 |
\ddd | ddd表示1~3个八进制的数字,如:\130 – 字符X |
\xdd | dd表示2个十六进制数字,如:\x30 – 字符0 |
#include <stdio.h>
int main()
{
//??) --> 三字母词 --> ](当前很多编译器不支持三字母词)
printf("(are you ok??)");
//如果编译器支持三字母词,打印结果为:(are you ok]
//1. '\?' -- 防止连续多个问号被解析成三字母词
printf("(are you ok\?\?)");
//2. '\'' -- 表示字符常量'(单引号)
printf("%c\n", '\'');//%c -- 打印字符
//3. "\"" -- 表示一个字符串内部的"(双引号)
printf("%s\n", "\"");//%s -- 打印字符串
//4. '\\' -- 反斜杠
printf("c:\\cdoe\\test.c");
//打印结果为:c:\cdoe\test.c
//5. '\a' -- 警告字符,蜂鸣
printf("\a");
//6. '\b' -- 退格符
printf("abcdef\bc");//打印结果为:abcdec
//7. '\f' -- 进纸符
//8. '\n' -- 换行
printf("abc\ndef");
//打印结果为:abc
// def
//9. '\r' -- 回车
//10. '\t' -- 水平制表符 -- 等价于Tab键(缩进)
printf("c:\code\test.c");
//打印结果为:c:code est.c
//11. '\v' -- 垂直制表符
return 0;
}
重点:
- ‘\ddd’ – ddd表示1~3个八进制的数字
- ‘\xdd’ – dd表示2个十六进制数字
char类型变量以%d格式打印其对应的ASCII码值,int类型变量以%c格式打印ASCII值对应的符号。
#include <stdio.h>
int main()
{
//'\130'表示八进制的130,等价于十进制的88
printf("%c\n", '\130');//打印ASCII码88对应的字符X
//'\x30'表示十六进制的30,等价于十进制的48
printf("%c\n", '\x30');//打印ASCII码48对应的字符0
//数字0和'\0'的ASCII码值都是0,字符'0'的ASCII码值为48
return 0;
}
练习:
#include <stdio.h>
#include <string.h>//包含头文件,调用strlen函数计算字符串长度
int main()
{
printf("%d\n", strlen("abcdef"));
//打印结果显然为6
printf("%d\n", strlen("c:\test\628\test.c"));
//考察转义字符:\t,\ddd(表示1至3个八进制数字,8不算)
//打印结果为:14
return 0;
}
6. 注释
我们在写代码的过程中,有些代码暂时不需要可以注释屏蔽掉,有些代码比较难懂,可以添加注释来解释说明。
注释有两种风格(xxxxxx表示被注释的内容):
/*xxxxxx*/
(C语言风格,不能嵌套注释)//xxxxxx
(C++风格,可以一行或多行注释)
#include <stdio.h>
int get_max(int x, int y)
{
/* C语言风格注释,不能嵌套注释
if (x > y)
return x;
else
return y;
*/
return (x > y ? x : y);
}
int main()
{
int a = 0;
int b = 0;
int max = 0;
//C++风格注释,可以注释一行或多行
//输入
scanf("%d %d", &a, &b);
//调用函数取较大值
max = get_max(a, b);
//输出
printf("max = %d\n", max);
return 0;
}
7. 分支和循环语句
1). 分支语句
在面临判断和选择的情况下,我们需要用到分支语句。
#include <stdio.h>
int main()
{
int input = 0;
printf("你有真正坚持去做一件有意义的事情嘛(1/0)?");
scanf("%d", &input);
//分支(选择)语句
if (input == 1)
printf("你很棒!\n");
else if (input == 0)
printf("请加油!\n");
else
printf("输入错误!\n");
return 0;
}
2). 循环语句
在面临有规律性的重复操作问题,我们需要用到循环语句。
#include <stdio.h>
int main()
{
int line = 0;
//循环语句
while (line <= 20000)
{
printf("敲代码: %d\n", line);
line++;
}
//分支(选择)语句
if (line > 20000)
printf("过上了幸福生活\n");
else
printf("不教一日闲过,继续努力\n");
return 0;
}
总结
- 局部变量的作用域是该变量所在的局部范围,进入作用域生命周期开始,出作用域生命周期结束。
- 全局变量的作用域是整个工程,生命周期是整个程序(主函数)的生命周期。
- 字面常量、(const)常变量、(#define)符号常量、枚举常量
- 字符串、转义字符、注释
- 初识分支和循环语句
以上拙见,欢迎大家指正和交流。