我尝试用这博客记录下我所热爱
我只不过是个无名小辈
无休止地更新
在名利中苦苦挣扎
世事变幻莫测
就算每一次早早被淘汰
在失败边缘挣扎
我的数据结构与算法系列开始了,有一定C语言基础的同学可以去学习!
数据结构与算法_时间复杂度
有任何问题都可以私信我。
目录
变量的作用域和生命周期
变量的作用域
变量的生命周期
常量
字面常量const
const修饰的常变量
#define定义的标识符常量
枚举常量
字符串+转义字符
字符串
转义字符
选择语句
循环语句
变量的作用域和生命周期
变量的作用域
什么是作用域?
举个简单的例子,当我执行以下代码时:
#include <stdio.h>
int main()
{
{
int a = 100;
printf("%d", a);
}
return 0;
}
可以得到预期的结果:
而当我执行下边的代码时:
#include <stdio.h>
int main()
{
{
int a = 100;
}
printf("%d", a);
return 0;
}
会发现编译器会报错:
说明a在{}内部可以使用,但出了{}就不能用了。
通俗地讲,哪里可以使用它,哪里就是它的作用域。
现在定义一个全局变量,再定义一个函数,看看两个2022能不能都打印出来。
#include <stdio.h>
int g_a = 2022;
void test()
{
printf("test:%d\n", g_a);
}
int main()
{
printf("%d\n", g_a);
test();
return 0;
}
经调试发现得到了预期的结果。
过程如下:
如果我们执行以下代码:
#include <stdio.h>
void test()
{
printf("test:%d\n", g_a);
}
int g_a = 2022;
int main()
{
printf("%d\n", g_a);
test();
return 0;
}
会发现编译器会报错:
要解决问题,在开头的时候声明一下就好:
#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;
}
真正定义在后边,第一个只是声明。
也可以直接在代码开头定义。
要使用变量,一定要先声明再使用。
全局变量还可以这么用:
新建一个.c源文件,在里边定义一个变量,能否在一个.c文件中调用另一个.c文件里的变量呢?
会发现编译器会报错:
这时候就要声明外部符号了!
在test.c中加上extern int g_a;
#include <stdio.h>
extern int a;
int main()
{
printf("%d\n", a);
return 0;
}
经调试得到了预期的结果:
所以,全局变量的作用域是整个项目(工程)!
变量的生命周期
什么是变量的生命周期?
变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段。
在之前我们演示过这样的代码的调用:
#include <stdio.h>
int main()
{
{
int a = 100;
}
printf("%d", a);
return 0;
}
a并不能在printf中使用。
为什么不能?
就是因为局部变量在进入作用域时创建,一旦出了作用域就会销毁。销毁了就不能用了。
本质上是在变量创建时向内存申请一块空间,销毁时把这块空间还给内存。
局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。
全局变量的生命周期是:整个程序的生命周期。
只要程序还活着,全局变量就可以使用。
常量
会变的值是变量,恒不变的值是常量。
C语言中常量和变量的定义有所差异:
C语言中的常量分为以下以下几种:
字面常量
const修饰的常变量
#define定义的标识符常量
枚举常量
这些常量都有自己的特点,要根据需求去选择。
字面常量const
字面常量可以这样定义:
int main()
{
100;
'a';
3.141592653589;
3.14;
"hello world";
return 0;
}
100是整型常量,a是字符型常量,3.141592653589是双精度浮点型常量,3.14是单精度浮点型常量,hello world是字符串常量。都是字面常量。
const修饰的常变量
为什么叫常变量?是因为它本质上是变量,但是不能通过某种方式改变。
这里仅仅点到为止,想仔细了解可阅读我先前的博客文章http://t.csdn.cn/PdCHE
比如我创建一个变量,在它前面加上const,然后想改变它的值,但发现编译器会报错:
#include <stdio.h>
int main()
{
const int a = 0;
a = 100;
printf("%d",a);
return 0;
}
也就是说,它是变量,但有常量的部分属性。
#define定义的标识符常量
现在用#define给M定义100
#define M 100
这就是#define标识符常量的定义方法。
执行以下代码,会打印出100
#include <stdio.h>
#define M 100
int main()
{
printf("%d",M);
return 0;
}
枚举常量
枚举其实就是一一列举。
生活中有些值可以一一列举,如血型、性别、三原色等等。
如果想定义三原色,就要用到enum
#include <stdio.h>
enum COLOR
{
RED,
GREEN,
BLUE
};
int main()
{
return 0;
}
如果我想让c代表的颜色为红色,那就需要这样:
enum COLOR c = RED;
RED、GREEN和BLUE有其相对应的值吗?
执行以下代码:
#include <stdio.h>
enum COLOR
{
RED,
GREEN,
BLUE
};
int main()
{
printf("%d\n",RED);
printf("%d\n", GREEN);
printf("%d\n", BLUE);
return 0;
}
可以发现它们的值分别是0、1、2。
更多常量相关的细节日后再讲。
字符串+转义字符
字符串
“hello world.\n"
这种由双引号引起来的一串字符称为字符串字面值,或者简称字符串。
注意!字符串的结束标志是一个 \0 的转义字符。
在计算字符串长度的时候\0是结束标志,不算作字符串内容。
如果想存储一个字符,就要用字符型变量。
如果想存储多个字符或是字符串,就用到数组了。
比如,我想存储hello world,可以这样定义数组:
char arr[] = "hello world";
注意,用字符串就要用字符型变量char。
也可以这样:
char arr[] = { 'h','e','l','l','l','o',' ','w','o','r','l','d','\0' };
这样存储字符串时,一定要以\0结尾!!!
如果去掉\0再去执行代码:
#include <stdio.h>
int main()
{
char arr[] = { 'h','e','l','l','l','o',' ','w','o','r','l','d'};
printf("%s", arr);
return 0;
}
会出现“烫”的字样。
是内存太烫了吗?......
为什么会出现这种情况?
调试以下代码,对arr1和arr2进行监视:
#include <stdio.h>
int main()
{
char arr1[] = { 'h','e','l','l','l','o',' ','w','o','r','l','d'};
char arr2[] = "hello world";
gets();//无实际意义,仅用于不让程序结束。
return 0;
}
可以发现arr2比arr1多了\0。
arr2中的\0是隐藏的、自动补上的,我们看不到但它是实际存在的。而arr1中没有\0。
这是两种不同书写形式带来的差异。
上文已提到\0是字符串结束的标志。
%s是打印字符串。
在初始化arr1和arr2时会向内存分别申请一块空间,分别存放hello world和hello world\0。
在打印字符串的时候,一直要打印到\0才停止。
由于arr1中没有\0,那么将继续往后打印,与arr1相邻的内存空间中存放的是什么完全不知道,直至遇到\0为止。
所以就会看到乱码的现象。
如果不想出现乱码,就要在arr1末尾手动加上\0
另外,计算字符串长度时,\0不算作字符串内容。
比如用常用库函数strlen(需要引用string.h头文件):
#include <stdio.h>
#include <string.h>
int main()
{
int length = 0;
char arr[] = "hello world";
length = strlen(arr);
printf("%d", length);
return 0;
}
strlen统计的是\0之前的字符串的个数。
转义字符
在屏幕上打印abcndef
printf("abcndef");
而当我在n之前加上\的时候:
printf("abc\ndef");
此时\n是转义字符换行符,不再是字符n。
假如我们要在屏幕上打印一个目录: c:\code\test.c
printf("c:\code\test.c\n");
实际上运行效果是这样的
这是因为t前边由于\的存在,t被转义了。
下边看一些转义字符:
看一道笔试题:
int main()
{
printf("%d\n", strlen("abcdef"));
printf("%d\n", strlen("c:\test\628\test.c"));
return 0;
}
程序会输出什么?
是6和14。
第一行打印很简单,第二行稍复杂。
首先\t会成为转义字符,那么接下来是\6成为转义字符?还是\62成为转义字符?还是\628成为转义字符?
是\62,因为根据上表,\ddd中ddd表示1~3个八进制的数字。
既然是八进制,那8就不能参与成为转义字符的一部分了。
为什么不是\6?因为三位之内的八进制数都可以成为转义字符的一部分。
还有就是,转义字符不管看起来长多少,都是一个字符的长度。
选择语句
如果你好好学习,校招的时候拿一个好offer,走上人生巅峰。
如果你不学习,毕业即失业,回家卖红薯!
这就是选择。
如果用C语言表达,是这样的:
#include <stdio.h>
int main()
{
int input = 0;
printf("你要好好学习吗?(1/0)\n");
scanf("%d",&input);
if (input == 1)
{
printf("好offer");
}
else if (input == 0)
{
printf("卖红薯");
}
else
{
printf("输入错误!");
}
return 0;
}
要么打印输出“好offer”,要么打印输出“卖红薯”,要么打印输出“输入错误!”,不可能两个或者三个同时执行。
C语言中if语句就是选择语句。
循环语句
生活中有很多事情需要我们日复一日甚至年复一年地去做,比如上课、学习。
你一直在学计算机,天天买彩票。
某天你买了张彩票,中了大奖,那你走上了人生巅峰(相对的,因为可能会有人看不上这奖)。
然后就迎娶白富美,学习?学什么习!
如果你天天买彩票都没中奖,你还会去老实学习,虽然是菜鸟,但是在坚持日复一日地学习。
直到有一天,你成为了大牛,你没有买彩票中奖,同样走上了人生巅峰。
C语言中有三种循环,分别是while语句、for语句和do...while语句。
今天只讲while语句,其他两个后期讲。
你选择了好好学习,然后日复一日地敲代码。
只有在敲够20000行代码(有意义的代码)后才能拿到好offer。
如果你没有敲够20000行,就日复一日地敲代码。
某天你敲够了20000行代码,恭喜!你拿到了好offer!
#include <stdio.h>
int main()
{
printf("加入比特\n");
int line = 0;
while (line <= 20000)
{
line++;
printf("我要继续努力敲代码\n");
}
if (line > 20000)
printf("好offer\n");
return 0;
}
如果你在学习过程中开始摆烂,没有敲够20000行代码,那就没有好offer了。
一定要满足line>20000的条件,否则会提示“好好学习,天天编程”。
#include <stdio.h>
int main()
{
printf("加入比特\n");
int line = 0;
while (line <= 20000)
{
line++;
printf("我要继续努力敲代码\n");
}
if (line > 20000)
printf("好offer\n");
else
printf("好好学习,天天编程");
return 0;
}
创作不易,码了五千多字,求各位老铁三连支持下!