✨前言✨
作为一个小白说出标题这样的话看来是有些大言不惭,但博主有心将这个系列做好、做精。实话说博主学习C语言不过两个多月,也很能明白初学者的困惑,所以会尽肯能详细。同时作为一个系统的教程,这个系列会持续推新的,所以关注博主🍻,在学习C语言的路上结伴前行吧!
🐱💻作者概况: 就读南京邮电大学努力学习的大一小伙
🐱🐉联系方式:2879377052(QQ小号) [有问题欢迎留言讨论,作者尽力帮忙]✨
🐱👤资源推荐:C语言从入门到进阶
🐱🚀今日书籍分享:《C陷阱与缺陷》 提取码:CSDN
🐱👓gitee码云链接: Gitee仓库 test
✨复习✨
在上一篇博客里(没看过?点这里),我们学习了如何安装VS,并写下了第一段代码。重点知识如下,我以问题的形式帮助大家回想:
①main函数的作用?—— main函数的特点?
②什么是库函数?—— printf的各种格式控制符的作用?(慢慢熟悉,先记常用的)
库函数不会用,送你一本库函数字典
③什么是数据类型?—— 数据类型有哪些?—— 各种类型大小? —— 数据类型存在的意义?
④能否实现在屏幕上打印“hello world!”
上面的问题都能回想起来说明上一篇文章掌握的很好。没掌握也没关系,再看一遍肯定会掌握的。好了,现在开始我们今天的学习内容。
目录
一、变量⭐
知识点一:什么是变量🌵
知识点二:如何使用变量🌕
知识点三:变量的分类🌕
二、常量⭐
知识点一:什么是常量🌵
知识点二:有哪些类型的常量🌕
①字面常量🌲
②常变量:const🌳
③#define定义变量🌴
④枚举常量🌾
三、字符串⭐⭐
知识点一:字符串怎么存🌵
知识点二:\0是什么?有什么用 ?⭐⭐⭐
四、转义字符⭐
知识点一:什么是转移字符🌵
笔试题⭐⭐
五、后记(投个票再走呗)
一、变量⭐
知识点一:什么是变量🌵
顾名思义,变量就是可变的量,可以被任意的赋值和修改。与之相对的是常量,一旦被初始化之后便不可以被修改(后文会详细讲)
知识点二:如何使用变量🌕
变量的使用要遵循“先定义后使用的原则”。那什么是定义变量呢?定义变量就是创建一个对象,并根据变量的类型向内存申请相应大小的空间(如一个变量为int类型,则向内存申请4字节的空间)。我们现在创建了一个变量m,并给他初始化为10。
int main()
{
int m = 10;
}
问题一:如果不初始化会怎么样?🤔
答:如果这个变量为全局变量,则其初始值为0。如果这个变量为局部变量,则其初始值为随机值(全局变量后文讲)。既然是随机值鬼知道他到底是多大(不看监控的话),所以在使用局部变量的时候要记得赋值,最好定义后随即跟上赋值,防止忘记赋值了。
强行使用编译器也不会允许的
易错一:分号
注意:新手在写代码的时候;老是会落掉。好在VS的报错够智能会即使提醒你。那有人会问分号有什么用呢?在c语言中一行表示一条语句,加上;表示这条语句的结束。
补充一:C99之前的标准📜
在C99标准之前要求先变量定义要放在最前面。什么意思呢,现在演示一下。在C99标准下第二种写法就不正确了。但这个问题大家不用太关心,VS2013~VS2019对C99是支持的,所以以下都可以。
int main()
{
int a=1;
int b=1;
b = a + 1;
return 0;
}
int main()
{
int a = 1;
int b = a + 1;
return 0;
}
知识点三:变量的分类🌕
变量分为全局变量和局部变量。怎么区分的呢?其实很简单,在代码块外的就是全局变量,在代码块内的就是局部变量。(代码块就是“{ }”)
(里面的for语句先别管,以后会提到)
int g_val = 1;//全局变量
int main()
{
int i=1;//局部变量
int count = 0;//局部变量
for (i = 1; i < 3; i++)
{
int j = 1;//局部变量
for (j = 1; j < 3; j++)
{
count++;
}
}
return 0;
}
建议一:全局变量
在C程序里最好少用全局变量。试想一个几万行代码的工程突然冒出来一个变量不免让人疑惑。如果一定要使用全局变量,在命名时最好加上g_,g就表示global嘛,表明它是一个全局变量,避免人们误会。
问题一:全局变量和局部变量的区别
区别一:
谈到两者的区别不得不提到两个概念:作用域和生命周期
作用域:就是变量有效的范围。局部变量的作用域在它所在的代码块范围内
……{ { int i { { …… } } } }如这里i在随后的两个代码块里都是可以用的,但是在最外面的代码块已经出了它的作用域。
全局变量的作用域是整个工程,即在一个工程文件下即使在多个.c文件内都可以使用。
生命周期:变量的创建到变量的销毁之间的一个时间段
就如上文所提到的i,{ int i }进入代码块i被创建,出代码块i被销毁
生命周期和作用域在表现效果的时候有重叠的现象,但一个是空间一个是时间。不理解也没必要深究
在上文作用域和生命周期的介绍中已经体现全局部变量的区别,现在看实际代码加深理解
全局变量跨文件使用只要声明一下就可以了
顺便谈谈声明与定义的区别:声明的关键字extern
定义就好比两个人确定男女朋友关系,只能定义一次,总不能两个人好着但又确定男女朋友关系吧🤔。所以代码里不能出现两次的 int xxx=xxx;
声明就好比你高兴的和室友说你有女朋友了,只要室友不打死你,你说多少次都可以,可以多次声明🤣
区别二:全局变量开辟在内存上的静态区;局部变量开辟在内存上的栈区。(不深究,以后会讲)
问题二: 全局变量和局部变量重名问题
大家看以下这段代码,判断输出结果
#include<stdio.h>
int g_val=10;
int main()
{
int g_val=100;
printf("%d\n",g_val);
return 0;
}
当全局变量和局部变量重名时,遵循“局部变量优先”原则。所以打印的结果为100
二、常量⭐
知识点一:什么是常量🌵
顾名思义,常量就是固定不变的量,一旦被初始化后便不可以被修改。
问题一:以下行为算是修改吗?(const 修饰表示这个数为常变量)
int main()
{
const int a = 10;
return 0;
}
答:初始化不算修改。初始化之后便不可以被修改,不信去试试。
知识点二:有哪些类型的常量🌕
①字面常量🌲
很简单,就是如10,20,‘a’,‘b’;
②常变量:const🌳
const为关键字,说明这个类型的数据为“只读变量”。被const修饰的变量具有某种常属性——即只可以被读取,但是不可以被修改。然而他本质上还是个变量,只不过具有常属性。我们以下面的例子说明。
上面有我们没提到的数组,也顺便讲一下吧。其实很简单,数组就像一个连续货架,他们在内存上开辟的空间连续。这里的int表示数组存储的数据类型为int ,【】表示这个数组有多大,这里为10,说明可以存放十个整形。整形的赋值要用{},赋值为{0}表示将数组里十个元素都赋值为0。这里不细讲,可以看看别人的博文 点这里前往——数组
这里想表达的是,【】内必须是一个常量,而a即使别const定义了还是不能用,说明他本质还是变量
补充一:
在C99语法中支持变长数组这一概念,即【】内可以是变量。但在VS2019 c语言中不支持,且这种方式也不大流行。如果你【】内放入的是变量但是却没有报错,看看自己文件后缀是.c还是.cpp,cpp表示的是c++文件,在c++中是允许的,这点在主线①中有指出过。
③#define定义变量🌴
define定义的就是一个真常量了 ,不行你看 ,以下代码没有任何问题。博主的注释也可以看看,刚写也掉进坑了
#define MAX 10 //没有“=”注意! ,没有;
int main()
{
int arr1[10] = { 0 };
int arr2[MAX] = {0};
return 0;
}
建议一:
#define定义的变量最好名字为大写
④枚举常量🌾
有些事物是可以一一列举的比如性别,我们可以创建一个枚举变量,使用的时候引用就行。
注意中间使用逗号分隔的,不是分号
int main()
{
enum SEX //创建枚举常量
{
MALE,
FEMALE,
SECRET
};
enum SEX man = MALE;//使用枚举常量创建变量
return 0;
}
创建的变量都是有值得我们可以打印一下
这个值也是可以改变的,但他们还是按顺序增长的
三、字符串⭐⭐
知识点一:字符串怎么存🌵
我们学过字符类型,那该怎么储存字符串类型呢?是不是在C语言里也有字符串对应的类型吗。我只能遗憾的告诉你,在C语言里并没有字符串类型,那我们该怎么存放字符串呢?
字符串储存在数组中,用“”引起来(注意区别:字符是用''引起来的)。我们现在演示一下
int main()
{
char str[] = "abcd";//数组不指定元素个数则根据后面元素的个数确定
return 0;
}
我们从上面可可以看到字符串的本质是一个数组,里面一次存入各个字符
‘a’ ‘b’ ‘c’ ‘d’ ‘\0’
\0是什么?明明没有啊。别急,你现在只需记住,凡是字符串在末尾都会自带一个\0
知识点二:\0是什么?有什么用 ?⭐⭐⭐
是什么:\0的ASCLL码值为10,他标志着字符串的结束。
有什么用:就如是什么中提到的,他标志着字符串的结束。没有\0就无法判断一个字符串是否结束。比如strlen和printf以%s的格式打印时就是一直运行直到到达\0停止
我们现在用sizeof和函数strlen(库函数,作用是返回一个字符串的长度。尝试用博主上文提到的方法自主学习,不会欢迎向作者提问) 来验证\0的存在
size为什么会比strlen长呢?这从侧面说明了\0的存在,要额外占用一字节的空间,而strlen本质上是计算出\0前的字符数。
什么你还不信,那就给你看看内存里到底存的是什么。首先要ctrl+fn+f10(或者ctrl+f10)进入调试状态,敲黑板,一定要进调试状态,不然看不到。
怎么样,信了吧。
那来看看一下的几个问题:
问题一:下面打印的结果是
#include <string.h>//库函数要引用头文件
#include <stdio.h>
int main()
{
char str[6] = "abcdef";
printf("%s",str);
return 0;
}
这是什么鬼东西?别急我们仔细观察下,我们在创建数组是指定了数组的长度为6,也就是说\0放不进去了,所以打印字符串就不知道什么时候会停下来,直到它幸运的在后面遇到一个\0,因此会多很多奇怪的东西。
问题二:下面打印的结果是什么
#include <string.h>//库函数要引用头文件
#include <stdio.h>
int main()
{
char str[] = {'a','b','c','d','e','f'};
printf("%s", str);
return 0;
}
这又是什么鬼结果?明明字符串大小已经可以自动调节了,可结果怎么还是这么奇怪。来我们分析一下。我们将六个字符存入字符串,这时\0没有被加入,为什么?因为你没写啊。而“abcdef”里的\0是字符串类型自带的,可这里只是把字符放进去,怎么改呢?既然不自动加\0我们就自己加嘛!
问题三:下面打印的结果是什么
#include <string.h>//库函数要引用头文件
#include <stdio.h>
int main()
{
char str[7] = {'a','b','c','d','e','f'};
printf("%s", str);
return 0;
}
咦,为什么这样就可以了。因为字符类型的数组,空间有多,自动存入\0。现在我们验证一下
四、转义字符⭐
知识点一:什么是转移字符🌵
我们现在猜测一下下面的结果是什么
#include<stdio.h>
int main()
{
printf("c:\test\test.c");
return 0;
}
来揭晓答案
为什么会这样呢?其实就是转义字符在作怪。那到底什么是转义字符
是什么:'\'+某个特定字符表示特定的意思(注意转义字符是C语言规定的,不能自行设置)。我们之前就见过\n,他表示换行符。
转义字符 | 意义 | ASCII码值(十进制) |
\a | 响铃(BEL) | 007 |
\b | 退格(BS) ,将当前位置移到前一列 | 008 |
\f | 换页(FF),将当前位置移到下页开头 | 012 |
\n | 换行(LF) ,将当前位置移到下一行开头 | 010 |
\r | 回车(CR) ,将当前位置移到本行开头 | 013 |
\t | 水平制表(HT) (跳到下一个TAB位置) | 009 |
\v | 垂直制表(VT) | 011 |
\\ | 代表一个反斜线字符''\' | 092 |
\' | 代表一个单引号(撇号)字符 | 039 |
\" | 代表一个双引号字符 | 034 |
\? | 代表一个问号 | 063 |
\0 | 空字符(NUL) | 000 |
\ddd | 1到3位八进制数所代表的任意字符 | 三位八进制 |
\xhh | 十六进制所代表的任意字符 | 十六进制 |
现在我们来演示一下。结果大家实际操作一下。
#include<stdio.h>
int main()
{
printf("abc\b\n");//b相当于backspace
printf("abc\rd\n");//r相当于用鼠标将光标移到开始位置,也就是a,此时我们在这里输入d
printf("abc\tdef\n");//t相当于table,水平制表符
printf("\\n\n");//就是想要输出\n而不要理解成换行符,就把\给转义
printf("\"\n");//不加\,则第一个“会和第二个”自动组合,第三就会显示不匹配的问题
printf("\110\n");//1到3个小于8的数字,理解为八进制数字。对照ASCLL码表转化为字符输出
printf("\x61\n");//x加上任意个小于16的数字表示16进制
}
笔试题⭐⭐
#include<stdio.h>
int main()
{
printf("%d\n", strlen("c:\test\628\test.c"));
return 0;
}
答案:14
分析:1.一个转义字符虽然由多个符号组成,但计算字符个数时,当成一个
2.\628虽然有三个数字,但8不可能是8进制的数字,所以自动忽略
再比如\6687则这里的转义字符为\66,后面不算
c :\t e s t \62 8 \t e s t . c 一共14个
五、后记
一不小心写了6000+,是不是我太啰嗦了🤣 。但不管怎么样还是希望对大家有帮助吧。再给大家提个小建议,遇到不会或是什么bug,百度和CSDN都是很好平台去寻求解决方案,也提升自己个人解决问题能力。写的代码可以保存到代码仓库(不会上传,看这里),小绿点是你努力的证明。
主线③已更新:主线③
没看过瘾,看看新推出的《深入剖析系列》 —— —— 《深入剖析C语言》C语言与内存
更多推荐
【全网最强C语言学习】C语言入门篇(主线)——初始C语言②
发布评论