本文最后更新于117 天前,其中的信息可能已经过时,如有错误请发送邮件到shikeAB@outlook.com。
【转载】C语言入门到精通,这一篇就够了(13万字笔记)1
C语言程序组成
- 手机有很多功能, “开机”,“关机”,“打电话”,“发短信”,”拍照”等等
-
手机中的每一个功能就相当于C语言程序中的一个程序段(函数)
-
众多功能中总有一个会被先执行,不可能多个功能一起执行
-
想使用手机必须先执行手机的开机功能
-
所以C语言程序也一样,由众多功能、众多程序段组成, 众多C语言程序段中总有一个会被先执行, 这个先执行的程序段我们称之为”主函数”
-
一个C语言程序由多个”函数”构成,每个函数有自己的功能
-
一个程序***有且只有一个主函数***
-
如果一个程序没有主函数,则这个程序不具备运行能力
-
程序运行时系统会***自动调用***主函数,而其它函数需要开发者***手动调用***
-
主函数有固定书写的格式和范写
函数定义格式
- 主函数定义的格式:
- int 代表函数执行之后会返回一个整数类型的值
- main 代表这个函数的名字叫做main
- () 代表这是一个函数
- {} 代表这个程序段的范围
- return 0; 代表函数执行完之后返回整数0
int main() {
// insert code here...
return 0;
}
- 其它函数定义的格式
- int 代表函数执行之后会返回一个整数类型的值
- call 代表这个函数的名字叫做call
- () 代表这是一个函数
- {} 代表这个程序段的范围
- return 0; 代表函数执行完之后返回整数0
int call() {
return 0;
}
如何执行定义好的函数
- 主函数(main)会由系统自动调用, 但其它函数不会, 所以想要执行其它函数就必须在main函数中手动调用
- call 代表找到名称叫做call的某个东西
- () 代表要找到的名称叫call的某个东西是一个函数
- ; 代表调用函数的语句已经编写完成
- 所以call();代表找到call函数, 并执行call函数
int main() {
call();
return 0;
}
- 如何往屏幕上输出内容
- 输出内容是一个比较复杂的操作, 所以系统提前定义好了一个专门用于输出内容的函数叫做printf函数,我们只需要执行系统定义好的printf函数就可以往屏幕上输出内容
- 但凡需要执行一个函数, 都是通过函数名称+圆括号的形式来执行
- 如下代码的含义是: 当程序运行时系统会自动执行main函数, 在系统自动执行main函数时我们手动执行了call函数和printf函数
- 经过对代码的观察, 我们发现两个问题
- 并没有告诉printf函数,我们要往屏幕上输出什么内容
- 找不到printf函数的实现代码
int call(){
return 0;
}
int main(){
call();
printf();
return 0;
}
- 如何告诉printf函数要输出的内容
- 将要输出的内容编写到printf函数后面的圆括号中即可
- 注意: 圆括号中编写的内容必须用双引号引起来
printf("hello world\n");
- 如何找到printf函数的实现代码
- 由于printf函数是系统实现的函数, 所以想要使用printf函数必须在使用之前告诉系统去哪里可以找到printf函数的实现代码
- #include
就是告诉系统可以去stdio这个文件中查找printf函数的声明和实现
#include
int call(){
return 0;
}
int main(){
call();
printf("hello world\n");
return 0;
}
如何运行编写好的程序
- 方式1:
- 点击小榔头将”源代码”编译成”可执行文件”
- 找到编译后的源代码, 打开终端(CMD)运行可执行文件
- 方式2
- 直接点击Qt开发工具运行按钮
- 直接点击Qt开发工具运行按钮
main函数注意点及其它写法
- C语言中,每条完整的语句后面都必须以分号结尾
int main(){
printf("hello world\n") // 如果没有分号编译时会报错
return 0;
}
int main(){
// 如果没有分号,多条语句合并到一行时, 系统不知道从什么地方到什么地方是一条完整语句
printf("hello world\n") return 0;
}
- C语言中除了注释和双引号引起来的地方以外都不能出现中文
int main(){
printf("hello world\n"); // 这里的分号如果是中文的分号就会报错
return 0;
}
- 一个C语言程序只能有一个main函数
int main(){
return 0;
}
int main(){ // 编译时会报错, 重复定义
return 0;
}
- 一个C语言程序不能没有main函数
int call(){ // 编译时报错, 因为只有call函数, 没有main函数
return 0;
}
int mian(){ // 编译时报错, 因为main函数的名称写错了,还是相当于没有main函数
return 0;
}
- main函数前面的int可以不写或者换成void
#include
main(){ // 不会报错
printf("hello world\n");
return 0;
}
#include
void main(){ // 不会报错
printf("hello world\n");
return 0;
}
- main函数中的return 0可以不写
int main(){ // 不会报错
printf("hello world\n");
}
- 多种写法不报错的原因
- C语言最早的时候只是一种规范和标准(例如C89, C11等)
- 标准的推行需要各大厂商的支持和实施
- 而在支持的实施的时候由于各大厂商利益、理解等问题,导致了实施的标准不同,发生了变化
- Turbo C
- Visual C(VC)
- GNU C(GCC)
- 所以大家才会看到不同的书上书写的格式有所不同, 有的返回int,有的返回void,有的甚至没有返回值
- 所以大家只需要记住最标准的写法即可, no zuo no die
#include
int main(){
printf("hello world\n");
return 0;
}
Tips:
语法错误:编译器会直接报错
逻辑错误:没有语法错误,只不过运行结果不正确
C语言程序练习
- 编写一个C语言程序,用至少2种方式在屏幕上输出以下内容
*** ***
*********
*******
****
**
- 普通青年实现
printf(" *** *** \n");
printf("*********\n");
printf(" *******\n");
printf(" ****\n");
printf(" **\n");
- 2B青年实现
printf(" *** *** \n*********\n *******\n ****\n **\n");
- 文艺青年实现(装逼的, 先不用理解)
int i = 0;
while (1) {
if (i % 2 == 0) {
printf(" *** *** \n");
printf("*********\n");
printf(" *******\n");
printf(" ****\n");
printf(" **\n");
}else
{
printf("\n");
printf(" ** ** \n");
printf(" *******\n");
printf(" *****\n");
printf(" **\n");
}
sleep(1);
i++;
system("cls");
}
初学者如何避免程序出现BUG
_ooOoo_
o8888888o
88" . "88
(| -_- |)
O\ = /O
____/`---'\____
. ' \\| |// `.
/ \\||| : |||// \
/ _||||| -:- |||||- \
| | \\\ - /// | |
| \_| ''\---/'' | |
\ .-\__ `-` ___/-. /
___`. .' /--.--\ `. . __
."" '< `.___\_<|>_/___.' >'"".
| | : `- \`.;`\ _ /`;.`/ - ` : | |
\ \ `-. \_ __\ /__ _/ .-` / /
======`-.____`-.___\_____/___.-`____.-'======
`=---='
.............................................
佛祖保佑 有无BUG
━━━━━━神兽出没━━━━━━
┏┓ ┏┓
┏┛┻━━━━━━┛┻┓
┃ ┃
┃ ━ ┃
┃ ┳┛ ┗┳ ┃
┃ ┃
┃ ┻ ┃
┃ ┃
┗━┓ ┏━┛Code is far away from bug with the animal protecting
┃ ┃ 神兽保佑,代码无bug
┃ ┃
┃ ┗━━━┓
┃ ┣┓
┃ ┏━━┛┛
┗┓┓┏━┳┓┏┛
┃┫┫ ┃┫┫
┗┻┛ ┗┻┛
━━━━━━感觉萌萌哒━━━━━━
´´´´´´´´██´´´´´´´
´´´´´´´████´´´´´´
´´´´´████████´´´´
´´`´███▒▒▒▒███´´´´´
´´´███▒●▒▒●▒██´´´
´´´███▒▒▒▒▒▒██´´´´´
´´´███▒▒▒▒██´ 项目:第一个C语言程序
´´██████▒▒███´´´´´ 语言: C语言
´██████▒▒▒▒███´´ 编辑器: Qt Creator
██████▒▒▒▒▒▒███´´´´ 版本控制:git-github
´´▓▓▓▓▓▓▓▓▓▓▓▓▓▒´´ 代码风格:江哥style
´´▒▒▒▒▓▓▓▓▓▓▓▓▓▒´´´´´
´.▒▒▒´´▓▓▓▓▓▓▓▓▒´´´´´
´.▒▒´´´´▓▓▓▓▓▓▓▒
..▒▒.´´´´▓▓▓▓▓▓▓▒
´▒▒▒▒▒▒▒▒▒▒▒▒
´´´´´´´´´███████´´´´´
´´´´´´´´████████´´´´´´´
´´´´´´´█████████´´´´´´
´´´´´´██████████´´´´ 大部分人都在关注你飞的高不高,却没人在乎你飞的累不累,这就是现实!
´´´´´´██████████´´´ 我从不相信梦想,我,只,相,信,自,己!
´´´´´´´█████████´´
´´´´´´´█████████´´´
´´´´´´´´████████´´´´´
________▒▒▒▒▒
_________▒▒▒▒
_________▒▒▒▒
________▒▒_▒▒
_______▒▒__▒▒
_____ ▒▒___▒▒
_____▒▒___▒▒
____▒▒____▒▒
___▒▒_____▒▒
███____ ▒▒
████____███
█ _███_ _█_███
——————————————————————————女神保佑,代码无bug——————————————————————
多语言对比
- C语言
#include
int main() {
printf("南哥带你装B带你飞");
return 0;
}
- C++语言
#include
using namespace std;
int main() {
cout << "南哥带你装B带你飞" << endl;
return 0;
}
- OC语言
#import
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");
}
}
- 编写了注释的程序
/*
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了
关键字分类
什么是标识符?
- 从字面上理解,就是用来标识某些东西的符号,标识的目的就是为了将这些东西区分开来
- 其实标识符的作用就跟人类的名字差不多,为了区分每个人,就在每个人出生的时候起了个名字
- 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这样的变量名称看上去就像驼峰一样此起彼伏
什么是数据?
- 生活中无时无刻都在跟数据打交道
- 例如:人的体重、身高、收入、性别等数据等
-
在我们使用计算机的过程中,也会接触到各种各样的数据
- 例如: 文档数据、图片数据、视频数据等
数据分类
-
静态的数据
- 静态数据是指一些永久性的数据,一般存储在硬盘中。硬盘的存储空间一般都比较大,现在普通计算机的硬盘都有500G左右,因此硬盘中可以存放一些比较大的文件
- 存储的时长:计算机关闭之后再开启,这些数据依旧还在,只要你不主动删掉或者硬盘没坏,这些数据永远都在
- 哪些是静态数据:静态数据一般是以文件的形式存储在硬盘上,比如文档、照片、视频等。
-
动态的数据
- 动态数据指在程序运行过程中,动态产生的临时数据,一般存储在内存中。内存的存储空间一般都比较小,现在普通计算机的内存只有8G左右,因此要谨慎使用内存,不要占用太多的内存空间
- 存储的时长:计算机关闭之后,这些临时数据就会被清除
- 哪些是动态数据:当运行某个程序(软件)时,整个程序就会被加载到内存中,在程序运行过程中,会产生各种各样的临时数据,这些临时数据都是存储在内存中的。当程序停止运行或者计算机被强制关闭时,这个程序产生的所有临时数据都会被清除。
-
既然硬盘的存储空间这么大,为何不把所有的应用程序加载到硬盘中去执行呢?
- 主要***原因就是内存的访问速度比硬盘快N倍***
- 静态数据和动态数据的相互转换
- 也就是从磁盘加载到内存
- 也就是从磁盘加载到内存
- 动态数据和静态数据的相互转换
- 也就是从内存保存到磁盘
- 也就是从内存保存到磁盘
- 数据的计量单位
- 不管是静态还是动态数据,都是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大类数据类型:基本类型、构造类型、指针类型、空类型
什么是常量?
- "量"表示数据。常量,则表示一些固定的数据,也就是不能改变的数据
- 就好比现实生活中生男生女一样, 生下来是男孩永远都是男孩, 生下来是女孩就永远都是女孩, 所以性别就是现实生活中常量的一种体现
- 不要和江哥吹牛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前后不能有空格
- 以幂的形式表示, 以字母e或字母E后跟一个10为底的幂数
- 小数形式
-
字符常量
- 字符型常量都是用’’(单引号)括起来的。例如:‘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;
}
变量内存分析(简单版)
- 字节和地址
- 为了更好地理解变量在内存中的存储细节,先来认识一下内存中的“字节”和“地址”
- 每一个小格子代表一个字节
- 每个字节都有自己的内存地址
- 内存地址是连续的
- 变量存储占用的空间
- 一个变量所占用的存储空间,和***定义变量时声明的类型***以及***当前编译环境***有关
类型 | 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
int main(){ int number; int value; number = 22; value = 666; printf("&number = %p\n", &number); // 0060FEAC printf("&value = %p\n", &value); // 0060FEA8 }
先不要着急, 刚开始接触C语言, 我先了解这么多就够了. 后面会再次更深入的讲解存储的各种细节。
来自陕西