既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
.............................................
佛祖保佑 有无BUG
━━━━━━神兽出没━━━━━━
┏┓ ┏┓
┏┛┻━━━━━━┛┻┓
┃ ┃
┃ ━ ┃
┃ ┳┛ ┗┳ ┃
┃ ┃
┃ ┻ ┃
┃ ┃
┗━┓ ┏━┛Code is far away from bug with the animal protecting
┃ ┃ 神兽保佑,代码无bug
┃ ┃
┃ ┗━━━┓
┃ ┣┓
┃ ┏━━┛┛
┗┓┓┏━┳┓┏┛
┃┫┫ ┃┫┫
┗┻┛ ┗┻┛
━━━━━━感觉萌萌哒━━━━━━
´´´´´´´´██´´´´´´´
´´´´´´´████´´´´´´
´´´´´████████´´´´
´´`´███▒▒▒▒███´´´´´
´´´███▒●▒▒●▒██´´´
´´´███▒▒▒▒▒▒██´´´´´
´´´███▒▒▒▒██´ 项目:第一个C语言程序
´´██████▒▒███´´´´´ 语言: C语言
´██████▒▒▒▒███´´ 编辑器: Qt Creator
██████▒▒▒▒▒▒███´´´´ 版本控制:git-github
´´▓▓▓▓▓▓▓▓▓▓▓▓▓▒´´ 代码风格:江哥style
´´▒▒▒▒▓▓▓▓▓▓▓▓▓▒´´´´´
´.▒▒▒´´▓▓▓▓▓▓▓▓▒´´´´´
´.▒▒´´´´▓▓▓▓▓▓▓▒
..▒▒.´´´´▓▓▓▓▓▓▓▒
´▒▒▒▒▒▒▒▒▒▒▒▒
´´´´´´´´´███████´´´´´
´´´´´´´´████████´´´´´´´
´´´´´´´█████████´´´´´´
´´´´´´██████████´´´´ 大部分人都在关注你飞的高不高,却没人在乎你飞的累不累,这就是现实!
´´´´´´██████████´´´ 我从不相信梦想,我,只,相,信,自,己!
´´´´´´´█████████´´
´´´´´´´█████████´´´
´´´´´´´´████████´´´´´
________▒▒▒▒▒
_________▒▒▒▒
_________▒▒▒▒
________▒▒_▒▒
_______▒▒__▒▒
_____ ▒▒___▒▒
_____▒▒___▒▒
____▒▒____▒▒
___▒▒_____▒▒
███____ ▒▒
████____███
█ _███_ _█_███
——————————————————————————女神保佑,代码无bug——————————————————————
---
### 多语言对比
* C语言
#include<stdio.h>
int main() {
printf(“南哥带你装B带你飞”);
return 0;
}
* C++语言
#include
using namespace std;
int main() {
cout << “南哥带你装B带你飞” << endl;
return 0;
}
* OC语言
#import <Foundation/Foundation.h>
int main() {
NSLog(@“南哥带你装B带你飞”);
return 0;
}
* Java语言
class Test
{
public static viod main()
{
system.out.println(“南哥带你装B带你飞”);
}
}
* Go语言
package main
import “fmt” //引入fmt库
func main() {
fmt.Println(“南哥带你装B带你飞”)
}
### 什么是注释?
* 注释是在所有计算机语言中都非常重要的一个概念,从字面上看,就是注解、解释的意思
* 注释可以用来解释某一段程序或者某一行代码是什么意思,方便程序员之间的交流沟通
* 注释可以是任何文字,也就是说可以写中文
* 被注释的内容在开发工具中会有特殊的颜色
---
### 为什么要使用注释?
* 没有编写任何注释的程序
void printMap(char map[6][7] , int row, int col);
int main(int argc, const char * argv[])
{
char map[6][7] = {
{‘#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’},
{‘#’, ’ ', ’ ‘, ’ ‘, ‘#’ ,’ ‘, ’ ‘},
{’#’, ‘R’, ’ ‘, ‘#’, ‘#’, ’ ‘, ‘#’},
{’#’, ’ ‘, ’ ‘, ’ ‘, ‘#’, ’ ‘, ‘#’},
{’#’, ‘#’, ’ ‘, ’ ‘, ’ ‘, ’ ‘, ‘#’},
{’#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’}
};
int row = sizeof(map)/sizeof(map[0]);
int col = sizeof(map[0])/ sizeof(map[0][0]);
printMap(map, row, col);
int pRow = 2;
int pCol = 1;
int endRow = 1;
int endCol = 6;
while (‘R’ != map[endRow][endCol]) {
printf(“亲, 请输入相应的操作\n”);
printf(“w(向上走) s(向下走) a(向左走) d(向右走)\n”);
char run;
run = getchar();
switch (run) {
case ‘s’:
if (’#’ != map[pRow + 1][pCol]) {
map[pRow][pCol] = ’ ‘;
pRow++;//3
map[pRow][pCol] = ‘R’;
}
break;
case ‘w’:
if (’#’ != map[pRow - 1][pCol]) {
map[pRow][pCol] = ’ ‘;
pRow–;
map[pRow][pCol] = ‘R’;
}
break;
case ‘a’:
if (’#’ != map[pRow][pCol - 1]) {
map[pRow][pCol] = ’ ‘;
pCol–;
map[pRow][pCol] = ‘R’;
}
break;
case ‘d’:
if (’#’ != map[pRow][pCol + 1]) {
map[pRow][pCol] = ’ ';
pCol++;
map[pRow][pCol] = ‘R’;
}
break;
}
printMap(map, row, col);
}
printf(“你太牛X了\n”);
printf(“想挑战自己,请购买完整版本\n”);
return 0;
}
void printMap(char map[6][7] , int row, int col)
{
system(“cls”);
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
printf(“%c”, map[i][j]);
}
printf(“\n”);
}
}
![](https://img-blog.csdnimg.cn/img_convert/9eb2da75e4aa1df095e2ddcf4b886364.gif)
* 编写了注释的程序
/*
R代表一个人
#代表一堵墙
// 0123456
####### // 0
# # // 1
#R ## # // 2
# # # // 3
## # // 4
####### // 5
分析:
>1.保存地图(二维数组)
>2.输出地图
>3.操作R前进(控制小人行走)
3.1.接收用户输入(scanf/getchar)
w(向上走) s(向下走) a(向左走) d(向右走)
3.2.判断用户的输入,控制小人行走
3.2.1.替换二维数组中保存的数据
(
1.判断是否可以修改(如果不是#就可以修改)
2.修改现有位置为空白
3.修改下一步为R
)
3.3.输出修改后的二维数组
4.判断用户是否走出出口
*/
// 声明打印地图方法
void printMap(char map[6][7] , int row, int col);
int main(int argc, const char * argv[])
{
// 1.定义二维数组保存迷宫地图
char map[6][7] = {
{‘#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’},
{‘#’, ’ ', ’ ‘, ’ ‘, ‘#’ ,’ ‘, ’ ‘},
{’#’, ‘R’, ’ ‘, ‘#’, ‘#’, ’ ‘, ‘#’},
{’#’, ’ ‘, ’ ‘, ’ ‘, ‘#’, ’ ‘, ‘#’},
{’#’, ‘#’, ’ ‘, ’ ‘, ’ ‘, ’ ‘, ‘#’},
{’#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’}
};
// 2.计算地图行数和列数
int row = sizeof(map)/sizeof(map[0]);
int col = sizeof(map[0])/ sizeof(map[0][0]);
// 3.输出地图
printMap(map, row, col);
// 4.定义变量记录人物位置
int pRow = 2;
int pCol = 1;
// 5.定义变量记录出口的位置
int endRow = 1;
int endCol = 6;
// 6.控制人物行走
while (‘R’ != map[endRow][endCol]) {
// 6.1提示用户如何控制人物行走
printf(“亲, 请输入相应的操作\n”);
printf(“w(向上走) s(向下走) a(向左走) d(向右走)\n”);
char run;
run = getchar();
// 6.2根据用户输入控制人物行走
switch (run) {
case ‘s’:
if (’#’ != map[pRow + 1][pCol]) {
map[pRow][pCol] = ’ ‘;
pRow++;//3
map[pRow][pCol] = ‘R’;
}
break;
case ‘w’:
if (’#’ != map[pRow - 1][pCol]) {
map[pRow][pCol] = ’ ‘;
pRow–;
map[pRow][pCol] = ‘R’;
}
break;
case ‘a’:
if (’#’ != map[pRow][pCol - 1]) {
map[pRow][pCol] = ’ ‘;
pCol–;
map[pRow][pCol] = ‘R’;
}
break;
case ‘d’:
if (’#’ != map[pRow][pCol + 1]) {
map[pRow][pCol] = ’ ';
pCol++;
map[pRow][pCol] = ‘R’;
}
break;
}
// 6.3重新输出行走之后的地图
printMap(map, row, col);
}
printf(“你太牛X了\n”);
printf(“想挑战自己,请购买完整版本\n”);
return 0;
}
/**
- @brief printMap
- @param map 需要打印的二维数组
- @param row 二维数组的行数
- @param col 二维数组的列数
*/
void printMap(char map[6][7] , int row, int col)
{
// 为了保证窗口的干净整洁, 每次打印都先清空上一次的打印
system(“cls”);
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
printf(“%c”, map[i][j]);
}
printf(“\n”);
}
}
---
### 注释的分类
* 单行注释
+ // 被注释内容
+ 使用范围:任何地方都可以写注释:函数外面、里面,每一条语句后面
+ 作用范围: 从第二个斜线到这一行末尾
+ 快捷键:Ctrl+/
* 多行注释
+ /\* 被注释内容 \*/
+ 使用范围:任何地方都可以写注释:函数外面、里面,每一条语句后面
+ 作用范围: 从第一个/\*到最近的一个\*/
---
### 注释的注意点
* 单行注释可以嵌套单行注释、多行注释
// 南哥 // it666.com
// /* 江哥 */
// 帅哥
* 多行注释可以嵌套单行注释
/*
// 作者:LNJ
// 描述:第一个C语言程序作用:这是一个主函数,C程序的入口点
*/
* 多行注释\*\*\*不能\*\*\*嵌套多行注释
/*
哈哈哈
/嘻嘻嘻/
呵呵呵
*/
---
### 注释的应用场景
* 思路分析
/*
R代表一个人
#代表一堵墙
// 0123456
####### // 0
# # // 1
#R ## # // 2
# # # // 3
## # // 4
####### // 5
分析:
>1.保存地图(二维数组)
>2.输出地图
>3.操作R前进(控制小人行走)
3.1.接收用户输入(scanf/getchar)
w(向上走) s(向下走) a(向左走) d(向右走)
3.2.判断用户的输入,控制小人行走
3.2.1.替换二维数组中保存的数据
(
1.判断是否可以修改(如果不是#就可以修改)
2.修改现有位置为空白
3.修改下一步为R
)
3.3.输出修改后的二维数组
4.判断用户是否走出出口
*/
* 对变量进行说明
// 2.计算地图行数和列数
int row = sizeof(map)/sizeof(map[0]);
int col = sizeof(map[0])/ sizeof(map[0][0]);
* 对函数进行说明
/**
- @brief printMap
- @param map 需要打印的二维数组
- @param row 二维数组的行数
- @param col 二维数组的列数
*/
void printMap(char map[6][7] , int row, int col)
{
system(“cls”);
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
printf(“%c”, map[i][j]);
}
printf(“\n”);
}
}
* 多实现逻辑排序
// 1.定义二维数组保存迷宫地图
char map[6][7] = {
{'#', '#', '#', '#', '#', '#', '#'},
{'#', ' ', ' ', ' ', '#' ,' ', ' '},
{'#', 'R', ' ', '#', '#', ' ', '#'},
{'#', ' ', ' ', ' ', '#', ' ', '#'},
{'#', '#', ' ', ' ', ' ', ' ', '#'},
{'#', '#', '#', '#', '#', '#', '#'}
};
// 2.计算地图行数和列数
int row = sizeof(map)/sizeof(map[0]);
int col = sizeof(map[0])/ sizeof(map[0][0]);
// 3.输出地图
printMap(map, row, col);
// 4.定义变量记录人物位置
int pRow = 2;
int pCol = 1;
// 5.定义变量记录出口的位置
int endRow = 1;
int endCol = 6;
// 6.控制人物行走
while ('R' != map[endRow][endCol]) {
... ...
}
---
### 使用注释的好处
* 注释是一个程序员必须要具备的良好习惯
* 帮助开发人员整理实现思路
* 解释说明程序, 提高程序的可读性
+ 初学者编写程序可以养成习惯:先写注释再写代码
+ 将自己的思想通过注释先整理出来,在用代码去体现
+ 因为代码仅仅是思想的一种体现形式而已
---
### 什么是关键字?
* 关键字,也叫作保留字。是指一些被C语言赋予了特殊含义的单词
* 关键字特征:
+ 全部都是小写
+ 在开发工具中会显示特殊颜色
* 关键字注意点:
+ 因为关键字在C语言中有特殊的含义, 所以不能用作变量名、函数名等
* C语言中一共有32个关键字
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| --- | --- | --- | --- | --- | --- | --- | --- |
| char | short | int | long | float | double | if | else |
| return | do | while | for | switch | case | break | continue |
| default | goto | sizeof | auto | register | static | extern | unsigned |
| signed | typedef | struct | enum | union | void | const | volatile |
>
> 这些不用专门去记住,用多了就会了。在编译器里都是有特殊颜色的。 我们用到时候会一个一个讲解这个些关键字怎么用,现在浏览下,有个印象就OK了
>
>
>
---
### 关键字分类
![](https://img-blog.csdnimg.cn/img_convert/3f73cc45cf0a0bb4e4f0f1b9c972b2be.png)
### 什么是标识符?
* 从字面上理解,就是用来标识某些东西的符号,标识的目的就是为了将这些东西区分开来
* 其实标识符的作用就跟人类的名字差不多,为了区分每个人,就在每个人出生的时候起了个名字
* C语言是由函数构成的,一个C程序中可能会有多个函数,为了区分这些函数,就给每一个函数都起了个名称, 这个名称就是标识符
* 综上所述: 程序员在程序中给函数、变量等起名字就是标识符
---
### 标识符命名规则
* 只能由字母(a~z、 A~Z)、数字、下划线组成
* 不能包含除下划线以外的其它特殊字符串
* 不能以数字开头
* 不能是C语言中的关键字
* 标识符严格区分大小写, test和Test是两个不同的标识符
---
### 练习
* 下列哪些是合法的标识符
| | | | | | | |
| --- | --- | --- | --- | --- | --- | --- |
| fromNo22 | from#22 | my\_Boolean | my-Boolean | 2ndObj | GUI | lnj |
| Mike2jack | 江哥 | \_test | test!32 | haha(da)tt | jack\_rose | jack&rose |
---
### 标识符命名规范
* 见名知意,能够提高代码的可读性
* 驼峰命名,能够提高代码的可读性
+ 驼峰命名法就是当变量名或函数名是由多个单词连接在一起,构成标识符时,第一个单词以小写字母开始;第二个单词的首字母大写.
+ 例如: myFirstName、myLastName这样的变量名称看上去就像驼峰一样此起彼伏
+ ![](https://img-blog.csdnimg.cn/img_convert/2b8f50edb3b6449fb02a26a07c671ab4.png)
+ ![](https://img-blog.csdnimg.cn/img_convert/eb3e23d1df05b88339f18f213c7e8521.png)
### 什么是数据?
* 生活中无时无刻都在跟数据打交道
+ 例如:人的体重、身高、收入、性别等数据等
* 在我们使用计算机的过程中,也会接触到各种各样的数据
+ 例如: 文档数据、图片数据、视频数据等
---
### 数据分类
* 静态的数据
+ ***静态数据是指一些永久性的数据,一般存储在硬盘中***。硬盘的存储空间一般都比较大,现在普通计算机的硬盘都有500G左右,因此硬盘中可以存放一些比较大的文件
+ 存储的时长:***计算机关闭之后再开启,这些数据依旧还在,只要你不主动删掉或者硬盘没坏,这些数据永远都在***
+ 哪些是静态数据:静态数据一般是以文件的形式存储在硬盘上,比如文档、照片、视频等。
* 动态的数据
+ ***动态数据指在程序运行过程中,动态产生的临时数据,一般存储在内存中***。内存的存储空间一般都比较小,现在普通计算机的内存只有8G左右,因此要谨慎使用内存,不要占用太多的内存空间
+ 存储的时长:***计算机关闭之后,这些临时数据就会被清除***
+ 哪些是动态数据:当运行某个程序(软件)时,整个程序就会被加载到内存中,在程序运行过程中,会产生各种各样的临时数据,这些临时数据都是存储在内存中的。当程序停止运行或者计算机被强制关闭时,这个程序产生的所有临时数据都会被清除。
* 既然硬盘的存储空间这么大,为何不把所有的应用程序加载到硬盘中去执行呢?
+ 主要\*\*\*原因就是内存的访问速度比硬盘快N倍\*\*\*
---
* 静态数据和动态数据的相互转换
+ 也就是从磁盘加载到内存
![](https://img-blog.csdnimg.cn/img_convert/a6b6212999cefecf6467abd427c27bbf.png)
* 动态数据和静态数据的相互转换
+ 也就是从内存保存到磁盘
![](https://img-blog.csdnimg.cn/img_convert/8a9f31e02e46723156c2ffba4a00819c.png)
* 数据的计量单位
+ 不管是静态还是动态数据,都是0和1组成的
+ 数据越大,包含的0和1就越多
1 B(Byte字节) = 8 bit(位)
// 00000000 就是一个字节
// 111111111 也是一个字节
// 10101010 也是一个字节
// 任意8个0和1的组合都是一个字节
1 KB(KByte) = 1024 B
1 MB = 1024 KB
1 GB = 1024 MB
1 TB = 1024 GB
---
### C语言数据类型
* ***作为程序员, 我们最关心的是内存中的动态数据***,因为我们写的程序就是在内存中运行的
* 程序在运行过程中会产生各种各样的临时数据,***为了方便数据的运算和操作, C语言对这些数据进行了分类***, 提供了丰富的数据类型
* C语言中有4大类数据类型:***基本类型、构造类型、指针类型、空类型***
![](https://img-blog.csdnimg.cn/img_convert/73b03f1ce2062d094514e574bf3d0089.png)
---
### 什么是常量?
* "量"表示数据。常量,则表示一些固定的数据,也就是不能改变的数据
* 就好比现实生活中生男生女一样, 生下来是男孩永远都是男孩, 生下来是女孩就永远都是女孩, 所以性别就是现实生活中常量的一种体现
+ 不要和江哥吹牛X说你是泰国来的, 如果你真的来自泰国, 我只能说你赢了
---
### 常量的类型
* 整型常量
+ 十进制整数。例如:666,-120, 0
+ 八进制整数,八进制形式的常量都以0开头。例如:0123,也就是十进制的83;-011,也就是十进 制的-9
+ 十六进制整数,十六进制的常量都是以0x开头。例如:0x123,也就是十进制的291
+ 二进制整数,逢二进一 0b开头。例如: 0b0010,也就是十进制的2
* 实型常量
+ 小数形式
- 单精度小数:以字母f或字母F结尾。例如:0.0f、1.01f
- 双精度小数:十进制小数形式。例如:3.14、 6.66
- 默认就是双精度
- 可以没有整数位只有小数位。例如: .3、 .6f
+ 指数形式
- 以幂的形式表示, 以字母e或字母E后跟一个10为底的幂数
* 上过初中的都应该知道科学计数法吧,指数形式的常量就是科学计数法的另一种表 示,比如123000,***用科学计数法表示为1.23×10的5次方***
* ***用C语言表示就是1.23e5或1.23E5***
* 字母e或字母E后面的指数必须为整数
* 字母e或字母E前后必须要有数字
* 字母e或字母E前后不能有空格
* 字符常量
+ 字符型常量都是用’’(单引号)括起来的。例如:‘a’、‘b’、‘c’
+ 字符常量的单引号中只能有一个字符
+ 特殊情况: 如果是转义字符,单引号中可以有两个字符。例如:’\n’、’\t’
* 字符串常量
+ 字符型常量都是用""(双引号)括起来的。例如:“a”、“abc”、“lnj”
+ 系统会自动在字符串常量的末尾加一个字符’\0’作为字符串结束标志
* 自定义常量
+ 后期讲解内容, 此处先不用了解
* 常量类型练习
| | | | | | | |
| --- | --- | --- | --- | --- | --- | --- |
| 123 | 1.1F | 1.1 | .3 | ‘a’ | “a” | “李南江” |
---
### 什么是变量?
* "量"表示数据。变量,则表示一些不固定的数据,也就是可以改变的数据
* 就好比现实生活中人的身高、体重一样, 随着年龄的增长会不断发生改变, 所以身高、体重就是现实生活中变量的一种体现
* 就好比现实生活中超市的储物格一样, 同一个格子在不同时期不同人使用,格子中存储的物品是可以变化的。张三使用这个格子的时候里面放的可能是尿不湿, 但是李四使用这个格子的时候里面放的可能是面包
---
### 如何定义变量
* 格式1: 变量类型 变量名称 ;
+ 为什么要定义变量?
- 任何变量在使用之前,必须先进行定义, 只有定义了变量才会分配存储空间, 才有空间存储数据
+ 为什么要限定类型?
- 用来约束变量所存放数据的类型。一旦给变量指明了类型,那么这个变量就只能存储这种类型的数据
- 内存空间极其有限,不同类型的变量占用不同大小的存储空间
+ 为什么要指定变量名称?
- 存储数据的空间对于我们没有任何意义, 我们需要的是空间中存储的值
- 只有有了名称, 我们才能获取到空间中的值
int a;
float b;
char ch;
* 格式2:变量类型 变量名称,变量名称;
+ 连续定义, 多个变量之间用逗号(,)号隔开
int a,b,c;
* 变量名的命名的规范
+ 变量名属于标识符,所以必须严格遵守标识符的命名原则
---
### 如何使用变量?
* 可以利用=号往变量里面存储数据
+ 在C语言中,利用=号往变量里面存储数据, 我们称之为给变量赋值
int value;
value = 998; // 赋值
* 注意:
+ 这里的=号,并不是数学中的“相等”,而是C语言中的\*\*\*赋值运算符\*\*\*,作用是将右边的整型常量998赋值给左边的整型变量value
+ 赋值的时候,= 号的左侧必须是变量 (10=b,错误)
+ 为了方便阅读代码, 习惯在 = 的两侧 各加上一个 空格
---
### 变量的初始化
* C语言中, 变量的第一次赋值,我们称为“初始化”
* 初始化的两种形式
+ 先定义,后初始化
+ `int value; value = 998; // 初始化`
+ 定义时同时初始化
+ `int a = 10; int b = 4, c = 2;`
+ 其它表现形式(不推荐)
int a, b = 10; //部分初始化
int c, d, e;
c = d = e =0;
* 不初始化里面存储什么?
+ 随机数
+ 上次程序分配的存储空间,存数一些 内容,“垃圾”
+ 系统正在用的一些数据
---
### 如何修改变量值?
* 多次赋值即可
+ 每次赋值都会覆盖原来的值
int i = 10;
i = 20; // 修改变量的值
---
### 变量之间的值传递
* 可以将一个变量存储的值赋值给另一个变量
int a = 10;
int b = a; // 相当于把a中存储的10拷贝了一份给b
---
### 如何查看变量的值?
* 使用printf输出一个或多个变量的值
int a = 10, c = 11;
printf(“a=%d, c=%d”, a, c);
* 输出其它类型变量的值
double height = 1.75;
char blood = ‘A’;
printf(“height=%.2f, 血型是%c”, height, blood);
---
### 变量的作用域
* C语言中所有变量都有自己的作用域
* 变量定义的位置不同,其作用域也不同
* 按照作用域的范围可分为两种, 即局部变量和全局变量
---
* 局部变量
+ 局部变量也称为内部变量
+ 局部变量是在\*\*\*代码块内\*\*\*定义的, 其作用域仅限于代码块内, 离开该代码块后无法使用
int main(){
int i = 998; // 作用域开始
return 0;// 作用域结束
}
int main(){
{
int i = 998; // 作用域开始
}// 作用域结束
printf(“i = %d\n”, i); // 不能使用
return 0;
}
int main(){
{
{
int i = 998;// 作用域开始
}// 作用域结束
printf(“i = %d\n”, i); // 不能使用
}
return 0;
}
---
* 全局变量
+ 全局变量也称为外部变量,它是在代码块外部定义的变量
int i = 666;
int main(){
printf(“i = %d\n”, i); // 可以使用
return 0;
}// 作用域结束
int call(){
printf(“i = %d\n”, i); // 可以使用
return 0;
}
---
* 注意点:
+ 同一作用域范围内不能有相同名称的变量
int main(){
int i = 998; // 作用域开始
int i = 666; // 报错, 重复定义
return 0;
}// 作用域结束
int i = 666;
int i = 998; // 报错, 重复定义
int main(){
return 0;
}
* 不同作用域范围内可以有相同名称的变量
int i = 666;
int main(){
int i = 998; // 不会报错
return 0;
}
int main(){
int i = 998; // 不会报错
return 0;
}
int call(){
int i = 666; // 不会报错
return 0;
}
---
### 变量内存分析(简单版)
* 字节和地址
+ 为了更好地理解变量在内存中的存储细节,先来认识一下内存中的“字节”和“地址”
+ ***每一个小格子代表一个字节***
+ ***每个字节都有自己的内存地址***
+ ***内存地址是连续的***
![](https://img-blog.csdnimg.cn/img_convert/5515a7f3bbb5194db1f67b4f98de31c5.png)
* 变量存储占用的空间
+ 一个变量所占用的存储空间,和\*\*\*定义变量时声明的类型\*\*\*以及\*\*\*当前编译环境\*\*\*有关
| 类型 | 16位编译器 | 32位编译器 | 64位编译器 |
| --- | --- | --- | --- |
| char | 1 | 1 | 1 |
| int | 2 | 4 | 4 |
| float | 4 | 4 | 4 |
| double | 8 | 8 | 8 |
| short | 2 | 2 | 2 |
| long | 4 | 4 | 8 |
| long long | 8 | 8 | 8 |
| void\* | 2 | 4 | 8 |
* 变量存储的过程
+ 根据定义变量时声明的类型和当前编译环境确定需要开辟多大存储空间
+ 在内存中开辟一块存储空间,开辟时从内存地址大的开始开辟(内存寻址从大到小)
+ 将数据保存到已经开辟好的对应内存空间中
int main(){
int number;
int value;
number = 22;
value = 666;
}
#include <stdio.h>
int main(){
int number;
int value;
number = 22;
value = 666;
printf(“&number = %p\n”, &number); // 0060FEAC
printf(“&value = %p\n”, &value); // 0060FEA8
}
![](https://img-blog.csdnimg.cn/img_convert/3ac2c92b7d317d38441f3948865d98d0.png)
>
> 先不要着急, 刚开始接触C语言, 我先了解这么多就够了. 后面会再次更深入的讲解存储的各种细节。
>
>
>
### printf函数
![](https://img-blog.csdnimg.cn/img_convert/1a1d70de9ee22c638b43de8009048570.png)
* printf函数称之为格式输出函数,方法名称的最后一个字母f表示format。其功能是按照用户指定的格式,把指定的数据输出到屏幕上
* printf函数的调用格式为:
+ `printf("格式控制字符串",输出项列表 );`
+ 例如:`printf("a = %d, b = %d",a, b);`
![](https://img-blog.csdnimg.cn/img_convert/30dae0fb7fa2f93706031066d3cd99cf.png)
+ 非格式字符串原样输出, 格式控制字符串会被输出项列表中的数据替换
+ 注意: 格式控制字符串和输出项在数量和类型上\*\*\*必须一一对应\*\*\*
---
* 格式控制字符串
+ 形式: `%[标志][输出宽度][.精度][长度]类型`
---
* 类型
+ 格式: `printf("a = %类型", a);`
+ 类型字符串用以表示输出数据的类型, 其格式符和意义如下所示
| 类型 | 含义 |
| --- | --- |
| d | 有符号10进制整型 |
| i | 有符号10进制整型 |
| u | 无符号10进制整型 |
| o | 无符号8进制整型 |
| x | 无符号16进制整型 |
| X | 无符号16进制整型 |
| f | 单、双精度浮点数(默认保留6位小数) |
| e / E | 以指数形式输出单、双精度浮点数 |
| g / G | 以最短输出宽度,输出单、双精度浮点数 |
| c | 字符 |
| s | 字符串 |
| p | 地址 |
#include <stdio.h>
int main(){
int a = 10;
int b = -10;
float c = 6.6f;
double d = 3.1415926;
double e = 10.10;
char f = ‘a’;
// 有符号整数(可以输出负数)
printf(“a = %d\n”, a); // 10
printf(“a = %i\n”, a); // 10
// 无符号整数(不可以输出负数)
printf("a = %u\n", a); // 10
printf("b = %u\n", b); // 429496786
// 无符号八进制整数(不可以输出负数)
printf("a = %o\n", a); // 12
printf("b = %o\n", b); // 37777777766
// 无符号十六进制整数(不可以输出负数)
printf("a = %x\n", a); // a
printf("b = %x\n", b); // fffffff6
// 无符号十六进制整数(不可以输出负数)
printf("a = %X\n", a); // A
printf("b = %X\n", b); // FFFFFFF6
// 单、双精度浮点数(默认保留6位小数)
printf("c = %f\n", c); // 6.600000
printf("d = %lf\n", d); // 3.141593
// 以指数形式输出单、双精度浮点数
printf("e = %e\n", e); // 1.010000e+001
printf("e = %E\n", e); // 1.010000E+001
// 以最短输出宽度,输出单、双精度浮点数
printf("e = %g\n", e); // 10.1
printf("e = %G\n", e); // 10.1
// 输出字符
printf("f = %c\n", f); // a
}
---
* 宽度
+ 格式: `printf("a = %[宽度]类型", a);`
+ 用十进制整数来指定输出的宽度, 如果实际位数多于指定宽度,则按照实际位数输出, 如果实际位数少于指定宽度则以空格补位
#include <stdio.h>
int main(){
// 实际位数小于指定宽度
int a = 1;
printf(“a =|%d|\n”, a); // |1|
printf(“a =|%5d|\n”, a); // | 1|
// 实际位数大于指定宽度
int b = 1234567;
printf(“b =|%d|\n”, b); // |1234567|
printf(“b =|%5d|\n”, b); // |1234567|
}
---
* 标志
+ 格式: `printf("a = %[标志][宽度]类型", a);`
| 标志 | 含义 |
| --- | --- |
| - | 左对齐, 默认右对齐 |
| + | 当输出值为正数时,在输出值前面加上一个+号, 默认不显示 |
| 0 | 右对齐时, 用0填充宽度.(默认用空格填充) |
| 空格 | 输出值为正数时,在输出值前面加上空格, 为负数时加上负号 |
| # | 对c、s、d、u类型无影响 |
| # | 对o类型, 在输出时加前缀o |
| # | 对x类型,在输出时加前缀0x |
#include <stdio.h>
int main(){
int a = 1;
int b = -1;
// -号标志
printf(“a =|%d|\n”, a); // |1|
printf(“a =|%5d|\n”, a); // | 1|
printf(“a =|%-5d|\n”, a);// |1 |
// +号标志
printf(“a =|%d|\n”, a); // |1|
printf(“a =|%+d|\n”, a);// |+1|
printf(“b =|%d|\n”, b); // |-1|
printf(“b =|%+d|\n”, b);// |-1|
// 0标志
printf(“a =|%5d|\n”, a); // | 1|
printf(“a =|%05d|\n”, a); // |00001|
// 空格标志
printf(“a =|% d|\n”, a); // | 1|
printf(“b =|% d|\n”, b); // |-1|
// #号
int c = 10;
printf(“c = %o\n”, c); // 12
printf(“c = %#o\n”, c); // 012
printf(“c = %x\n”, c); // a
printf(“c = %#x\n”, c); // 0xa
}
---
* 精度
+ 格式: `printf("a = %[精度]类型", a);`
+ 精度格式符以"."开头, 后面跟上十进制整数, 用于指定需要输出多少位小数, 如果输出位数大于指定的精度, 则删除超出的部分
#include <stdio.h>
int main(){
double a = 3.1415926;
printf(“a = %.2f\n”, a); // 3.14
}
* 动态指定保留小数位数
+ 格式: `printf("a = %.*f", a);`
#include <stdio.h>
int main(){
double a = 3.1415926;
printf(“a = %.*f”, 2, a); // 3.14
}
* 实型(浮点类型)有效位数问题
+ 对于单精度数,使用%f格式符输出时,仅前6~7位是有效数字
+ 对于双精度数,使用%lf格式符输出时,前15~16位是有效数字
+ 有效位数和精度(保留多少位)不同, 有效位数是指从第一个非零数字开始,误差不超过本数位半个单位的、精确可信的数位
+ 有效位数包含小数点前的非零数位
#include <stdio.h>
int main(){
// 1234.567871093750000
float a = 1234.567890123456789;
// 1234.567890123456900
double b = 1234.567890123456789;
printf(“a = %.15f\n”, a); // 前8位数字是准确的, 后面的都不准确
printf(“b = %.15f\n”, b); // 前16位数字是准确的, 后面的都不准确
}
---
* 长度
+ 格式: `printf("a = %[长度]类型", a);`
| 长度 | 修饰类型 | 含义 |
| --- | --- | --- |
| hh | d、i、o、u、x | 输出char |
| h | d、i、o、u、x | 输出 short int |
| l | d、i、o、u、x | 输出 long int |
| ll | d、i、o、u、x | 输出 long long int |
#include <stdio.h>
int main(){
char a = ‘a’;
short int b = 123;
int c = 123;
long int d = 123;
long long int e = 123;
printf(“a = %hhd\n”, a); // 97
printf(“b = %hd\n”, b); // 123
printf(“c = %d\n”, c); // 123
printf(“d = %ld\n”, d); // 123
printf(“e = %lld\n”, e); // 123
}
* 转义字符
+ 格式: `printf("%f%%", 3.1415);`
+ %号在格式控制字符串中有特殊含义, 所以想输出%必须添加一个转移字符
#include <stdio.h>
int main(){
printf(“%f%%”, 3.1415); // 输出结果3.1415%
}
---
### Scanf函数
* scanf函数用于接收键盘输入的内容, 是一个阻塞式函数,程序会停在scanf函数出现的地方, 直到接收到数据才会执行后面的代码
* printf函数的调用格式为:
+ `scanf("格式控制字符串", 地址列表);`
+ 例如: `scanf("%d", &num);`
![](https://img-blog.csdnimg.cn/img_convert/6df3856aa41baa48cfc65ead2e0294de.png)
---
* 基本用法
+ 地址列表项中只能传入变量地址, 变量地址可以通过&符号+变量名称的形式获取
#include <stdio.h>
int main(){
int number;
scanf(“%d”, &number); // 接收一个整数
printf(“number = %d\n”, number);
}
* 接收非字符和字符串类型时, 空格、Tab和回车会被忽略
#include <stdio.h>
int main(){
float num;
// 例如:输入 Tab 空格 回车 回车 Tab 空格 3.14 , 得到的结果还是3.14
scanf(“%f”, &num);
printf(“num = %f\n”, num);
}
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
ong long int |
#include <stdio.h>
int main(){
char a = 'a';
short int b = 123;
int c = 123;
long int d = 123;
long long int e = 123;
printf("a = %hhd\n", a); // 97
printf("b = %hd\n", b); // 123
printf("c = %d\n", c); // 123
printf("d = %ld\n", d); // 123
printf("e = %lld\n", e); // 123
}
- 转义字符
- 格式:
printf("%f%%", 3.1415);
- %号在格式控制字符串中有特殊含义, 所以想输出%必须添加一个转移字符
- 格式:
#include <stdio.h>
int main(){
printf("%f%%", 3.1415); // 输出结果3.1415%
}
Scanf函数
- scanf函数用于接收键盘输入的内容, 是一个阻塞式函数,程序会停在scanf函数出现的地方, 直到接收到数据才会执行后面的代码
- printf函数的调用格式为:
scanf("格式控制字符串", 地址列表);
- 例如:
scanf("%d", &num);
- 基本用法
- 地址列表项中只能传入变量地址, 变量地址可以通过&符号+变量名称的形式获取
#include <stdio.h>
int main(){
int number;
scanf("%d", &number); // 接收一个整数
printf("number = %d\n", number);
}
- 接收非字符和字符串类型时, 空格、Tab和回车会被忽略
#include <stdio.h>
int main(){
float num;
// 例如:输入 Tab 空格 回车 回车 Tab 空格 3.14 , 得到的结果还是3.14
scanf("%f", &num);
printf("num = %f\n", num);
}
[外链图片转存中...(img-Q6xTze6C-1715361326058)]
[外链图片转存中...(img-kVWtKZu4-1715361326058)]
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618658159)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**