前言
学习笔记,参考各路大佬所记录,若有侵犯,请告知删改(我要30天学完!)
参考:二十万字带你入门C语言-史上最强C语言教程(汇总篇)-优快云博客
C 语言教程 | 菜鸟教程
C语言程序设计从入门到进阶【比特鹏哥c语言2024完整版视频教程】(c语言基础入门c语言软件安装C语言指针c语言考研C语言专升本C语言期末计算机二级C语言c语言_哔哩哔哩_bilibili
1.认识C语言(-------Day1--------+)
C 语言是一种通用的、面向过程式的计算机程序设计语言,广泛应用于底层开发。1972 年,为了移植与开发 UNIX 操作系统,丹尼斯·里奇在贝尔电话实验室设计开发了 C 语言。为了避免各开发厂商用的C语言语法产生差异,由美国国家标准局为C语言制定了一套完整的美国国家标准语法,称为ANSIC,作为C语言最初的标准。当前最新的 C 语言标准为 C18 ,在它之前的 C 语言标准有 C17、C11...C99 等。它是一种编译型语言,.c文件首先需要经过编译再链接最后才能输出可执行的.exe文件, 其编译器主要有Clang、GCC、WIN-TC SUBLIME、MSVC、Turbo C等。(python是解释性语言)
2.第一个C语言项目
#include <stdio.h> //--1.(包含)头文件 调用C语言库,使用其中的printf函数
/*---这是注释, /*注释内容*/或者//注释内容
#include 告诉预处理器将指定头文件的内容插入到预处理器命令的相应位导入头文件的预编译指令
stdio 表示系统文件库, 也可以声明其它的.h 表示头文件,因为这些文件都是放在程序各文件的开头
<> 表示系统自带的库,也可以写成" "表示用户自定义的库并且自定义的库里面没有这个文件系统会自动查找自带的库,如果还是没有报错*//* int 表示数据格式,返回一个int类型数据
main()主函数 表示程序的入口 一个工程有且只能有一个main函数的存在 */int main() //--2.主函数 程序的入口
{ //程序从这里开始运行printf("Hello World!\n"); //--3.语句 打印Hello World!\n,\n表示换行,转义字符后面会讲
return 0; //--4.返回值 返回一个整数0,因为它是int类型,所以只能返回整数
} //程序从这里结束
输出:
3.数据类型
在计算机中,最小存储单位:位 bit (比特)(Binary Digits):存放一位二进制数,即 0 或 1,最小的存储单位。
基本单位字节:字节 byte 8 个二进制位(bit)为一个字节(B),最常用的单位。 (我也常说一个字节占 8 位)
换算关系:
1B(Byte 字节)=8bit
1KB (Kilobyte 千字节)=1024B
1MB (Megabyte 兆字节 简称“兆”)=1024KB
1GB (Gigabyte 吉字节 又称“千兆”)=1024MB
1TB (Trillionbyte 万亿字节 太字节)=1024GB,其中 1024=2^10 ( 2 的 10 次方)
1PB(Petabyte 千万亿字节 拍字节)=1024TB
1EB(Exabyte 百亿亿字节 艾字节)=1024PB
1ZB (Zettabyte 十万亿亿字节 泽字节)= 1024 EB
1YB (Yottabyte 一亿亿亿字节 尧字节)= 1024 ZB
1BB (Brontobyte 一千亿亿亿字节)= 1024 YB变量的类型决定了变量存储占用的空间,以及如何解释存储的位的模式。
- char //字符数据类型8bit,用单引号 ' ' 引出,'0'不是数字0,它在计算机中通常是0x48
- short //短整型 16bit
- int //整形 32bit
- long //长整型 32bit
- long long //更长的整形 64bit
- float //单精度浮点数 32bit
- double //双精度浮点数 64bit
- long double //长双精度浮点数 64bit
可以通过sizeof关键字来输出数据类型长度,%zu为其输出的标志格式,图中使用printf函数%d也可以(后续说明printf的用法),单位为字节,1字节byte = 8 比特bit (貌似x64和x86下输出不一致,但是我的是一致的)
C语言本身并没有字符串类型,我们在C语言程序中使用的字符串实际上是字符数组,即多个字符构成的就是字符串!(后续展开)
下面是字符串的两种定义方式:
#include<stdio.h>
int main()
{
char string1[] = "abc";
char string2[] = { 'a','b','c' };
return 0;}
那么如何使用数据类型呢,这就到下面变量中探索了...
4.变量和常量
如何描述变量呢,自然是需要用到刚刚讲的数据类型了
4.1定义变量
基本方法: 数据类型 [空格] 变量名 = 值;
eg:
short age = 18;
int high = 190;
float P = 3.1415927;
命名规则:
- 大小写字母、数字、下划线组成,不可以数字开头,不能有特殊字符
- 不能与关键字重名
- 区分大小写
4.2变量的分类
(1)局部变量:{ }内部的前面定义的,作用于{ }内
(2)全局变量 :{ }外部的前面定义的变量,通常作用于整个.c文件
注意:局部优先原则,即局部变量和全局变量同名的时候(不建议),局部变量优先使用
4.3变量的输入
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int num1 = 0;
int num2 = 0;printf("请输入两个数英文逗号隔开:");
scanf("%d,%d", &num1,&num2);//通过键盘输入修改num地址下的内容
printf("求和为sum = %d", num1 + num2);
return 0;
}
printf()函数:输出函数。在双引号内的将进行输出,而%就是控制变量的输出格式,即起到了格式控制以及占位的作用,比如%d就是将变量以整型的形式进行打印输出到屏幕上来,%c则是以字符型的形式进行打印输出!在逗号后面的就是我们想要输出的变量,可以使用多个输出格式结合多个变量逗号隔开,在这个地方需要大家进行注意,%格式控制一定要与后面的变量进行意义对应!
scanf()函数:输入函数。%也是进行格式控制以及占位,不过此处与前面的区别就是此处是进行输入的格式控制,比如%d,就是将我们的输入的内容以整型的形式存储到我们的变量地址中,此处与前面也一样,都要与逗号后面的变量进行严格的对应,但此处仍然有一个需要大家进行注意的点,比如我们在输入时,我们在%d %d两个%d中间有一个空格进行分隔,那么我们在通过键盘进行输入的时候也要在两个变量中间进行分隔,即我们的输入要与双引号之间的内容进行严格第对应!
报错:使用scanf函数报错C6031,#define _CRT_SECURE_NO_WARNINGS 为解决 scanf 安全性报错,只会在 VS 中产生
解决方法:
偶尔:每次代码最前加入:#define _CRT_SECURE_NO_WARNING
永久性:在 VS 创建新文件的时候都是拷贝 newc++file.cpp 这个文件,只需要找到它,把它复制到桌面,修改桌面上的它,第一行输入#define _CRT_SECURE_NO_WARNING 保存,拖拽回去,覆盖原文件即可。
4.4变量的作用域与生命周期
(1)作用域
作用域(scope)是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/可用 的,而限定这个名字的可用性的代码范围就是这个名字的作用域。
1. 局部变量的作用域是变量所在的局部范围,在变量声明的{ }范围内。
2. 全局变量的作用域是整个工程,不只是main.c中,在别的.c文件中定义,在main文件中extern 声明 来自外部即可,只不过一个工程只能有一个主函数int main()执行
( 输出结果为:10)
(2)生命周期变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段
1. 局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。
2. 全局变量的生命周期是:整个程序的生命周期。
4.5常量
描述不变的量,C语言中的常量分为以下以下几种:
- 字面常量
- const 修饰的常变量
- #define 定义的标识符常量
- enum枚举常量,创建了一个类似数据类型,它的数值是可穷举的常量
//**#define 名称 数值,定义的标识符常量,没有数据类型
#define MAX 100
#define STR "abcdfe"//**enum枚举常量
enum Colar
{
RED,
GREEN,
BLUE
};
int main()
{
//**字面常量**
10;
3.14;
"a";
'abc';//**const修饰的常变量**
const int a = 10; //a不可再被修改
//a = 10; //报错,不可再修改
//int arr[a]={0}; //报错,数组中只能定义为常量enum Colar A = RED; //定义常量数值,实际上是等于定义了一种数据类型,且取值固定
//A = a; //报错,常量不可修改
return 0;
}
5.字符串和转义字符
5.1字符串
由双引号(Double Quote)引起来的一串字符称为字符串字面值(String Literal),或者简称字符串。eg:"hello world.\n"C
注意:
(1)C语言中没有字符串这个数据类型
(2)字符串的结束标志是一个 \0 的转义字符。在计算字符串长度的时候 \0 是结束标志,不算作字符串的内容,不计入长度。
C语言中没有字符串这个数据类型,那么如何定义字符串变量呢?
可以定义字符数组,将字符串中的每个字符存储在连续的几个数据单元char arr[10] = "abvdsad"; //自定长度,长度大于字符串长度,默认在多的空间附'\0'
char arr[ ] = "adadwddsfaasdsas"; //自动确定长度
char arr[ ] = {'a', 'b', 'c','\0'}; //字符拼接
按下F10,点击“调试”选项,选择“窗口”,打开“监视”,输入想要监视的数值即可查看数组内容,可以发现arr1数组定义过长有多个'\0',不完全初始化补'\0',,arr2数组多了一个第9位'\0',而arr3没有'\0'作为字符串的结束位,打印时乱码,直到找到'\0'为止。类似的,若定义字符串时直接包含了'\0',那么'\0'后面的内容不计入字符串中。
strlen()函数求字符串长度,返回整数,'\0'不计入长度,而且多定义的也不计入长度,只计入'\0'前面的,后面的忽略
5.2转义字符
\数字数字数字,d 表示 1~3 位八进制数(数值不可大于8),代表 ASCII 字符(\d,\dd也成立)
\x 数字数字,hh 指两位十六进制数,使用前要加\x,代表的 ASCII 字符
eg:printf("%c\n",'\x60') 输出为 a
eg:printf("%d\n", strlen("c:\test\628\test.c"));输出是多少??? 14
解释:\数字 表示的是八进制,0-7 不能大于等于8,\62 也就是十进制的50十六进制的32,查ASCII表表示的是字符2,而且\t 制表符占用一个字符长度,但是效果相当于四个字符(易错)
6.注释
注释是对代码的说明,编译器会忽略注释,也就是说,注释对实际代码没有影响。便于阅读!!!
- C++风格 // 注释的内容,可以注释一行也可以注释多行
- C风格 /* 注释的内容,不适用于嵌套 */
7.选择语句(--------Day2--------)
C语言是结构化的程序设计语言,包括顺序结构、 选择结构、循环结构
故名思意,选择1 做A,选择2做B...
if (条件语句1,非0即1)
{条件成立时,执行语句1;} //非必要,
else if (条件语句2,非0即1) //非必要,若成立,不再判断后面的if和else
{条件成立,执行语句2;}
else if (条件语句3,非0即1) //非必要
{条件成立,执行语句3;}
...
else //非必要
{上述条件都不成立,执行语句n;}
并且若执行语句只有一句则{ }大括号也可以省略哦
在if 和多else if语句中,若有一个条件成立了其中一个便不再判断执行后面的if和else,会在下一次循环中进行判断,若想都判断一遍建议使用多个if
switch和if嵌套等后期再说
8.循环语句
C语言中有三种循环语句
- while语句
- for语句(后期讲)
- do ... while语句(后期讲)
- 结束循环和跳出本次循环(后期讲)
while (循环条件非0即1)
{条件成立为1时,循环执行,直到条件不成立}
9.函数
函数的特点就是简化代码,代码复用(1)函数定义
返回值的数据类型 函数名称(形参数据类型1 形参1,形参数据类型2 形参2 ...)
{
语句;
return 返回值;
}
(2)函数的调用有返回值就利用变量 = 函数名称(实际参数1,实际参数2 ...);
图中直接return a+b;也可以在其中定义一个局部变量int sum = a+b;再进行返回return
10.数组
10.1数组的定义
格式: 数据类型 变量名称[ 常量长度 ] = { 内容1, 内容2, ... 内容n}; 内容的数据类型需一致
int arr[5] = {1,2,3,4,5};//定义一个整形数组,[ ]中括号内的常量数字用于定义数组长度,可以不定义,自动确定长度拓展:若使用sizeof 单目操作符计算整个数组的大小,其数值 = 数组的数据类型 * 常量长度,所以有一种便捷的求数组长度的方法 就是 sizeof(arr)/sizeof(arr[0])
10.2数组的下标
C 语言规定:数组的每个元素都有一个下标,下标是从 0开始的。数组可以通过下标来访问的。
6个元素,下标为0到5
10.3数组的使用
可以使用for循环按照下标将数组打印出来,并且数组可以直接通过下标修改
11.操作符
(1)算术操作符
- + 加
- - 减
- * 乘
- / 除,分为整数除法(四舍五入),和浮点数除法,需要用对应的变量接收
- % 取余(取模),该操作两边必须是整数
(2)移位操作符
<< >>(3)位操作符
& ^ | 按位与 按位异或 按位或(4)赋值操作符= += -= *= /= &= ^ = |= >>= <<=int a = 0;//定义aa = 2;//赋值a + = 3; //等价于 a = a + 3;a - = 3; //等价于 a = a - 3;(5)单目操作符(只有一个操作数)! 逻辑反操作,真的1变成假的0假的0变成真的1- 负值+ 正值& 取地址,scanf函数就是需要,后面指针操作sizeof 操作数的类型长度(以字节为单位),sizeof不是函数,可以不加( ) !!!~ 对一个数的二进制按位取反-- 前置、后置--(前置:先+1或-1后使用其数值,后置:先使用数值后+1或-1其数值)++ 前置、后置++,常用于跳出循环或计数* 间接访问操作符(解引用操作符),后面指针操作(类型) 强制类型转换 eg: int a = (int)3.14 ,a的数值等于3, 直接删除小数点,非四舍五入(6)关系操作符,非0 即1,作为判断条件
>>=<<=!= 用于测试 “ 不相等 ”== 用于测试 “ 相等(7) 逻辑操作符 作为多条件判断&& 逻辑与|| 逻辑或(8)条件操作符(三目运算符)exp1 ? exp2 : exp3;解释:若表达式1为真则运算表达式2;若表达式1为假,则运算表达式3(9) 逗号表达式exp1 , exp2... expN;从左往右依次执行计算,取最后一个为表达式结果(10)下标引用、函数调用和结构体符号[ ] 下标引用操作符( ) 函数调用操作符. 结构体成员访问-> 结构体成员访问 难 后续再说
12.常见的关键字(------Day3------)
auto(所有变量都有,可省略)char(等,数据类型)unsigned (数据类型)void(数据类型)double(数据类型)float(数据类型)int(数据类型)long(数据类型)short(数据类型)signed(数据类型)const(常属性)extern(声明外部属性)enum(枚举)typedef(类型重定义)struct(结构体 )union(联合体)sizeof(计算大小)while(循环)for(循环)do(do while循环)break(跳出循环)continue(跳出当前次循环)
if(条件语句)else(条件语句)switch(选择语句)case(switch选择语句)default(switch语句)register(寄存器区)static(静态区)goto(跳转语句)return(函数返回值)volatile(无、空)
12.1关键字 typedef
typedef 顾名思义是类型定义,这里应该理解为类型重命名。
使用方法: typedef 数据类型/结构体 别名;
typedef unsigned int uint_32;//将数据类型unsigned int取新的别名为uint_32(无符号整型)
typedef struct Node //结构体变量取别名
{
int data;
struct Node* next;
}Node;
int main()
{
//观察num1和num2,这两个变量的类型是一样的
unsigned int num1 = 0;
uint_32 num2 = 0;Struct Node n1;
Node n2;
return 0;}
12.2 static关键字
在C语言中: static是用来修饰变量和函数的使用方法:static 数据类型 变量名称1. 修饰局部变量-称为静态局部变量,使得其出了作用域也不销毁其数值,改变了其存储区域
自行体会图中效果,静态区的b没有被销毁,而变量a每次执行时都会重新初始化为1
2. 修饰全局变量-称为静态全局变量(本来就放在静态区)
3. 修饰函数-称为静态函数函数如同全局变量一样,也有外部链接属性。使用static 修饰函数,同理限制函数的使用范围,只能在本.C 文件中使用,没有外部链接属性
12.3 register寄存器
电脑存储设备:寄存器 > 高速缓存 > 内存 > 硬盘
13.#define宏定义
#define是预处理指令不是关键字!
-
define 定义标识符常量(前面讲过)#define MAX 100(不用;分号,不用数据类型)
-
define 定义宏
#define ADD(x, y) ((x)+(y))
使用方法:#define 宏名称(宏变量1,宏变量2,...) (语句含(变量)) //语句只能有一句

14.指针
14.1指针的概念
内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的.所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1 个字节。 为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地 址 。
变量是创建在内存中的(在内存中分配空间的),每个内存单元都有地址,所以变量也是有地址的。如何取地址呢,这就要用到我们之前使用过的&取地址符号。有了地址如何存放呢,这又不得不说 * 间接访问操作符(解引用操作符)。

int a = 6;表示着向内存(任意分配首地址)申请四个连续的字节,用于存放整型数据a,a的地址是四个字节中的首地址(第一个字节的地址)
p
称为指针变量(Pointer Variable),它存储的是另一个变量的内存地址。
*p
称为解引用指针(Dereferenced Pointer)或指针指向的值。通过*p
可以访问或修改指针p
指向的内存地址中存储的数据。p 是指针变量,它的数据类型为int *,它用于存放地址,它的内容p = &a也就是指针p指向a的地址。*p 是指针,数据类型是int,它对p指向的地址下的内容进行访问,对*p进行赋值同时会修改a的内容
应该使用%p输出指针
,以十六进制显示,%d范围小且是十进制显示的(进制转换自行了解哦)注意:int *p1 , p2, p3;只有p1是指针,而int *p1, *p2, *p3;才是三个都是指针
可以以整形指针举例,可以推广到其他类型,这里就不演示了。
14.2指针变量的大小
指针变量的大小:32位平台是4个字节,64位平台是8个字节
15.结构体
之前讲述的数据类型太过单一,即使数组类型能存储一组相同类型的元素,但是依然不能描述多种数据类型的集合。这里引出结构体这个类型,它使得C语言有能力描述复杂类型,我们可以用它创建变量,非常重要!
格式
定义:struct 结构体名称
{
数据类型1 成员变量1;
数据类型2 成员变量2;
...
}
使用方式1:(使用.操作符访问结构体成员)
首先先定义结构体变量: struct 结构体名称 变量名称= { "成员常量1","成员常量2"... };
然后再调用: 结构体变量名称.成员常量n
使用方式2:(利用指针变量和->访问)
定义结构体指针变量:struct 结构体名称 指针*ps = &s;//s是结构体变量(struct 结构体名称 指针*ps 常用于当作函数的形参)
再调用: (结构体指针*ps).成员常量n 或者:指针变量ps->成员常量n
eg://学生
//1.定义结构体类型
struct Stu
{
//成员
char name[20];
int age;
char sex[10];
char tale[12];
}; //有分号
//2.利用结构体类型声明变量s
struct Stu s = {"zhangshan", 18, "man", "1234546848"};
printf("%s %d %s %s",s.name,s.age,s.sex,s.tale);
16.作业题
C
D
1
小飞机__牛客网(在线OJ)![]()
#include<stdio.h>
int main()
{
printf(" ** \n ** \n************\n************\n * * \n * * \n");
return 0;
}解题关键:数空格和换行
#include <stdio.h>
int main() {
printf("Name Age Gender\n");
for(int i = 0; i < 21; i++)
{
printf("-");
}
printf("\nJack 18 man\n");
return 0;
}
C
![]()
B
7
C
未定义数组长度且没有'\0'停止位,输出随机值+
B C99标准之前,数组的大小都是用常量或者常量表达式表示
C99标准之后,支持了变长数组,但是不可以初始化赋值,只能对位操作(vs2022不支持)
B
A(超纲一点)
C define是预处理指令
#include <stdio.h>
int main()
{
int a, b;
while(1)
{
scanf("%d %d", &a, &b);
if(b==0)//实际上没那么严格,可以不使用if
{
printf("除数不能为0,请重新输入");
continue;
}
else
break;
}
printf("%d %d", a/b, a%b);
return 0;
}
#include <stdio.h>
int main() {
char a[] = { 73, 32, 99, 97, 110, 32, 100, 111, 32, 105, 116 , 33 };
int i = 0;
int length = sizeof(a) / sizeof(a[0]); //计算数组长度,前面讲过
while (i < length) {
printf("%c", a[i]);
i++;
} //循环输出
return 0;
}
#include <stdio.h>
int main()
{
int y,m,d;
scanf("%4d%2d%2d",&y,&m,&d);//利用%数字定长,若连续三个%d的话会省略掉m和d
if(y>=1990&&y<=2015&&m>=1&&m<=12&&d>=1&&d<=30)
{
printf("year=%d\nmonth=%02d\ndate=%02d",y,m,d);//利用%0数字补充0和定长
}
return 0;
}
17.Visual Studio2022 快捷键
Ctrl + F5 执行调试
F10 进入调试模式,逐过程运行
Ctrl + C不用选中,放在哪行就能直接复制
Ctrl + K + D 快速美观代码编写格式
按住Ctrl+滚轮快速放大缩小字体Ctrl + K + C 快速注释
Ctrl + K + U快速取消注释
Shift + Tab 前向缩进