文章目录:
A:学习视频
B:考点范围
C:C语言学习教程
D:补充知识
E:题库
F:其他资源
1.printf()和scanf()
1.1 printf()
1.2 scanf()
2.if 的常见问题解析
3.数组的常见问题解析
4.动态分配内存
5.定义结构体struct
6.共用体union
7.枚举enum
8.return的用法
9.break和continue
10.指针数组和数组指针的内存布局
11.野指针
12.typedef与#define的区别
13.文件操作
14:位运算计算
15:字符串函数运用
16:函数
17:数组
18:指针
A:学习视频
《郝斌C语言自学教程》180集:470万播放量 推荐学习-40小时
【C语言】《带你学C带你飞》(小甲鱼)61集:380万播放量 入门前学习-18小时 760万播放量地址2
2020年视频-播放量910万-习题比较多 100万播放量地址2时间比较长
B:考点范围
C基础知识、选择结构程序设计、理解分支结构的流程图表示、循环控制、数组的使用、函数的使用、指针的使用、结构体、文件操作
C:C语言学习教程
笔记参考 参考文档
参考地址1
鱼C工作室
N诺C语言复习攻略
C语言学习笔记知识点齐全——新手入门必看【建议收藏】
菜鸟教程C语言
C语言网教程
易百教程C语言教程
简单教程C 语言基础教程
C语言技术网C语言教程
Linux公社C语言
D:补充知识
C语言——数据类型
C语言——运算符优先级
C语言——六大运算符
C语言——| 和 ||——& 和 && 的区别用法
搞懂C语言指针,看这篇就够了!
E:题库
C语言——经典200道实例【基础例题100道——进阶例题100道】
C语言——题库汇总
C语言——练习题_200题【选择题-判断-填空-程序设计】
c语言——试题库编程题_[经典例题——60道]
大学C语言各章节练习题_及答案合集【350题】《选择题- 判断-程序填空-程序设计》
F:其他资源
C语言——BOOK
C语言——上课重点知识截图_课堂练习
指针-预处理-结构体-共用体-枚举-文件-位运算
C语言——printf&scanf格式字符串【占位符】
C语言——输入【getchar-scanf-gets】输出【putchar-printf-puts】用法区别
四种用法:printf(“字符串\n”);printf(“输出控制符”, 输出参数);printf("输出控制符1 输出控制符2 输出控制符3 ", 输出参数1, 输出参数2, 输出参数3… ); // 输出控制符和输出参数个数必须一一对应。printf("输出控制符 非输出控制符 ", 输出参数);
输出控制符 数据类型 %d int %ld long int %c char %f float %lf double %x(或%X, #x %#X)
2f 2F 0x2f 0X2F
int 或 long int 或 short int %s 字符串
两种用法:用法一:scanf(“输入控制符”, &输入参数);功能:将从键盘输入的字符转化为输入控制符所规定格式的数据,然后存入以输入参数的值为地址的变量中。用法二:scanf(“非输入控制符”, &输入参数);功能:将从键盘输入的字符转化为输入控制符所规定格式的数据,然后存入以输入参数的值为地址的变量中。非输入控制符必须原样输入。scanf("m%d", &i); // m123 合法的输入, 123是非法的输入scanf("%d", &j);printf("j = %d\n", j);printf("%d/%f = %f\n", i, n, i/n);
1. 空语句问题 if (3 > 2); 等价于 if (3 > 2) ; // 这是一个空语句 2. if...else... if (表达式) 语句A; else: 语句B; 这是正确的。而: if (表达式); // 这里多了个 ';',形成了空语句 语句A; else // 这个 else 没有 if 配对 语句B; 是错误的。3. if...else if...elseif (表达式1)语句A;else if (表达式2)语句B;else if (表达式3)语句C;else语句D;
即便表达式1/2/3都成立,也只会执行A语句.4. if...else if...if (表达式1)语句A;else if (表达式2)语句B;else if (表达式3)语句C;这么写语法没有错,但是逻辑上有漏洞。5. if...else if...elseif (表达式1)语句A;else if (表达式2)语句B;else if (表达式3)语句C;else (表达式4) // 7行语句D;
这样写是错误的,正确的写法是:
要么去掉7行的(表达式4);要么在7行的 else 后面加 if 。6. if...else if...else
if (表达式1)语句A;
else if (表达式2)语句B;
else if (表达式3)语句C;
else (表达式4); // 注意这里有个 ; ,跟5不一样语句D;
这样写语法不会出错,但逻辑上是错误的。else (表达式4);语句D;等价于else(表达式4);语句D;
错误示例 1int a[5];a[5] = {1, 2, 3, 4, 5};
解释:只有在定义数组的同时才可以整体赋值,其他情况整体赋值都是错误的。这里 a[5] 表示的是数组 a 的第 6 个元素,明显超出了定义的范围,所以错误。 a 数组最多取到 a[4],即第 5 个元素。错误示例 2int a[5] = {1, 2, 3, 4, 5};a[5] = 100;
解释:错误, 因为没有数组 a 没有 a[5] 这个元素,最多是 a[4]错误示例 3
功能:实现把 a 数组中的值全部复制给 b 数组。
错误的写法int a[5] = {1, 2, 3, 4, 5};int b[5];b = a; // error
正确的写法&#xff1a;for (i&#61;0; i<5; &#43;&#43;i)b[i] &#61; a[i];
int * p &#61; (int *)malloc(int len);1.本语句一共分配了两块内存&#xff0c;一块是动态分配的&#xff0c;总共 len 个字节&#xff0c;一个是静态分配的是 4 个字节&#xff0c;即变量 p 本身所占的内存。2.malloc() 只有一个 int 型的形参&#xff0c;表示要求系统分配的字节数。3.malloc() 函数的功能是请求系统分配 len 个字节的内存空间如果请求分配成功&#xff0c;则返回第一个字节的地址&#xff0c;如果分配不成功&#xff0c;则返回 NULL。4.malloc() 函数只能返回第一个字节的地址所以我们需要把这个无任何实际意义的第一个字节的地址(俗称干地址)转化成一个有实际意义的地址因此 malloc 前面必须加 (数据类型 *)&#xff0c;表示把这个无实际意义的第一个字节的地址转化为相应类型的地址freep(p);表示将 p 所指向的内存给释放掉&#xff0c;p 本身的内存是静态的。不能由程序员手动释放&#xff0c;p 本身的内存只能在 p 变量所在的函数运行终止时由系统自动释放
如&#xff1a;
int * p &#61; (int *)malloc(5);表示将系统分配好的50个字节的第一个字节的地址转化为 int * 型的地址更准确的说是把第一个字节的地址转化为 4 个字节的地址这样 p 就指向了第一个的 4 个字节&#xff0c; p&#43;1 就指向了第二个的 4 个字节&#xff0c;p&#43;i 就指向了第 i&#43;1 个的 4 个字节p[0] 就是第一个元素&#xff0c; p[i] 就是第 i&#43;1 个元素。double * p &#61; (double *)malloc(80);表示将系统分配好的80个字节的第一个字节的地址转化为 double * 型的地址更准确的说是把第一个字节的地址转化为 8 字节的地址这样 p 就指向了第一个的 8 个字节&#xff0c; p&#43;1 就指向了第二个的 8 个字节&#xff0c;p&#43;i 就指向了第 i&#43;1 个的 8 个字节p[0] 就是第一个元素&#xff0c; p[i] 就是第 i&#43;1 个元素。
函数原型为void *malloc(unsigned int size);其作用是在内存的动态存储区中分配一个长度为size的连续空间&#xff08;size是一个无符号数&#xff09;。此函数的返回值是一个指向分配域起始地址的指针&#xff08;类型为void&#xff09;。如果此函数未能成功地执行&#xff08;例如内存空间不足&#xff09;&#xff0c;则返回空指针(NULL)。
补充&#xff1a;calloc函数
void *calloc&#xff08;unsigned n, unsigned size&#xff09;;其作用是在内存的动态存储区中分配&#xff4e;个长度为size的连续空间。函数返回一个指向分配域起始地址的指针&#xff1b;如果分配不成功&#xff0c;返回NULL。用calloc函数可以为一维数组开辟动态存储空间&#xff0c;n为数组元素个数&#xff0c;每个元素长度为size
C 结构体地址1 C 结构体地址2
C复合结构——结构体struct
C复合结构——共用体union
C语言——enum(枚举)
把事物所有可能的取值一一列举出来
使用枚举可以限制用户的输入&#xff0c;使得代码更安全enum weekday{ sun,mou,tue,wed,thu,fri,sat };enum weekday a, b, c;或者为&#xff1a;enum weekday{ sun,mou,tue,wed,thu,fri,sat }a, b, c;或者为&#xff1a;enum { sun,mou,tue,wed,thu,fri,sat }a, b, c“枚举”类型的变量取值不能超过定义的范围
枚举类型是一种基本数据类型&#xff0c;而不是一种构造类型&#xff0c;因为它不能再分解为任何基本类型
在枚举值表中应罗列出所有可用值。这些值也称为枚举元素
在&#xff23;编译中&#xff0c;对枚举元素按常量处理&#xff0c;故称枚举常量。它们不是变量&#xff0c;不能对它们赋值
枚举元素作为常量&#xff0c;它们是有值的&#xff0c;&#xff23;语言编译按定义时的顺序使它们的值为&#xff10;&#xff0c;&#xff11;&#xff0c;&#xff12;…
枚举值可以用来作判断比较
一个整数不能直接赋给一个枚举变量
#include
enum DAY
{MON&#61;1, TUE, WED, THU, FRI, SAT, SUN
};int main()
{enum DAY day;day &#61; WED;printf("%d",day);return 0;
}以上实例输出结果为&#xff1a;3
1>终止被调函数&#xff0c;向主调函数返回表达式的值
2>如果表达式为空&#xff0c;则只终止函数&#xff0c;不向主调函数返回任何值
3> break是用来终止循环和switch的&#xff0c;return是用来终止函数的void f(){return; //return只用来终止函数&#xff0c;不向主调函数返回任何值
}int f0{return 10; //第一:终止函数,第二:向主调函数返回10
}int f({
return 10.5;1 //因为函数的返回值类型是int//所以最终f返回的是10而不是10.5
}
breakbreak如果用于循环是用来终止循环break如果用于switch,则是用于终止switchbreak不能直接用于if,除非if属于循环内部的一个子句continue用于跳过本次循环余下的语句,转去判断是否需要执行下次循环
指针数组&#xff1a;首先它是一个数组&#xff0c;数组的元素都是指针&#xff0c;数组占多少个字节由数组本身决定。它是“储存指针的数组”的简称。数组指针&#xff1a;首先它是一个指针&#xff0c;它指向一个数组。在32 位系统下永远是占4 个字节&#xff0c;至于它指向的数组占多少字节&#xff0c;不知道。它
是“指向数组的指针”的简称。指针数组&#xff1a;int *p1[10];
这里需要明白一个符号之间的优先级问题。“[]”的优先级比“*”要高。只要看到int * 就首先认为他两个是结合在一起的。
p1 与“[]”结合&#xff0c;构成一个数组的定义&#xff0c;数组名为p1&#xff0c;int *修饰的是数组的内容&#xff0c;即数组的每个元素。那现在我们清楚&#xff0c;这是一个
数组&#xff0c;其包含10 个指向int 类型数据的指针&#xff0c;即指针数组。数组指针&#xff1a;int (*p2)[10];
在这里“&#xff08;&#xff09;”的优先级比“[]”高&#xff0c;“*”号和p2 构成一个指针的定义&#xff0c;指针变量名为p2&#xff0c;int 修饰的是数组的内容&#xff0c;即数组的每
个元素。数组在这里并没有名字&#xff0c;是个匿名数组。那现在我们清楚p2 是一个指针&#xff0c;它指向一个包含10 个int 类型数据的数组&#xff0c;即数
组指针。
野指针&#xff1a;不守规矩乱跑的指针&#xff0c;最好把它拴住。栓“野指针”的链子就是这个“NULL”&#xff0c;定义指针变量的同时最好初始化为NULL&#xff0c;用完指针之后也将指针变量的值设置为
NULL。也就是说除了在使用时&#xff0c;别的时间都把指针“栓”到0 地址处。这样它就老实了。
C语言——typedef &define的区别用法
1.执行时间不同
关键字typedef在编译阶段有效&#xff0c;由于是在编译阶段&#xff0c;因此typedef有类型检查的功能。
#define则是宏定义&#xff0c;发生在预处理阶段&#xff0c;也就是编译之前&#xff0c;它只进行简单而机械的字符串替换&#xff0c;而不进行任何检查。2.对指针的操作
typedef (int*) p1;
和
#define p2 int*
另外注意&#xff0c;一个有分号&#xff0c;一个没有分号&#xff01;typedef int * pint;
#define PIN T int *int i1 &#61; 1, i2 &#61; 2;const pint p1 &#61; & i1; //p不可更改&#xff0c;p指向的内容可以更改&#xff0c;相当于 int * const p;const PIN T p2 &#61; & i2; //p可以更改&#xff0c;p指向的内容不能更改&#xff0c;相当于 const int *p&#xff1b;或 int const *p&#xff1b;
pint s1, s2; //s1和s2都是int型指针
PIN T s3, s4; //相当于int * s3&#xff0c;s4&#xff1b;只有一个s3是指针
鱼C工作室 参考地址1
分类 函数名 功能
打开文件 fopen() 打开文件
关闭文件 fclose() 关闭文件
文件定位 fseek() 改变文件位置指针的位置
rewind() 使文件位置指针重新至于文件开头
ftell() 返回文件位置指针的当前值
文件状态 feof() 若到文件末尾&#xff0c;函数值为真
ferror() 若对文件操作出错&#xff0c;函数值为真
clearerr() 使ferror和feof()函数值置零
文件读写 fgetc(),getc()从指定文件取得一个字符
fputc(),putc()把字符输出到指定文件
fgets()从指定文件读取字符串
fputs()把字符串输出到指定文件
getw()从指定文件读取一个字&#xff08;int型&#xff09;
putw()把一个字输出到指定文件
fread()从指定文件中读取数据项
fwrite()把数据项写到指定文件中
fscanf()从指定文件按格式输入数据
fprintf()按指定格式将数据写到指定文件中
C位运算&#xff1c;&#xff1c; &#xff1e;&#xff1e; ~ & | ^&#xff08;以数值的二进制位为单位进行操作的&#xff09;
C字符串函数运用&#xff08;strlen-strcpy-strcat-strncat-strcmp-strrev-strlwr-strupr-strchr-strstr&#xff09;
函数
调用类型 描述 传值调用 该方法把参数的实际值复制给函数的形式参数。在这种情况下&#xff0c;修改函数内的形式参数不会影响实际参数。 引用调用 通过指针传递方式&#xff0c;形参为指向实参地址的指针&#xff0c;当对形参的指向操作时&#xff0c;就相当于对实参本身进行的操作。
数组
概念 描述 多维数组 C 支持多维数组。多维数组最简单的形式是二维数组。 传递数组给函数 您可以通过指定不带索引的数组名称来给函数传递一个指向数组的指针。 从函数返回数组 C 允许从函数返回数组。 指向数组的指针 您可以通过指定不带索引的数组名称来生成一个指向数组中第一个元素的指针。
指针
概念 描述 指针的算术运算 可以对指针进行四种算术运算&#xff1a;&#43;&#43;、--、&#43;、- 指针数组 可以定义用来存储指针的数组。 指向指针的指针 C 允许指向指针的指针。 传递指针给函数 通过引用或地址传递参数&#xff0c;使传递的参数在调用函数中被改变。 从函数返回指针 C 允许函数返回指针到局部变量、静态变量和动态内存分配。