一、C语言概述
一、scanf——常用的输入函数
scanf()在输入数据时 读到空格(space),制表符(\t),换行符(\n)会停止!
类比:
strlen() 特点:仅以’\0’为结束判断,且不将’\0’算入内;
sizeof(计算字符串内存大小) 和 strlen(计算字符串长度) 返回类型: %zd
scanf()函数的返回值:1.scanf的返回值是 成功读取的数据项数
2.读取两个数据,如果两个都成功则返回2;
读取一个数据,如果成功,则返回1;
若一个都没成功则返回-1;
如果遇到文件的末尾,则返回EOF。
实际应用1:往数组里面存储未定个数的数据(有边界)
int i=0
while(scanf("%d",&x)==1)//成功读取每一个数据。
arr[i++]=x;
二、字符串的输出
定义:字符串(character string)是一个或多个字符的序列,空字符 \0 标记字符串的结束
字符串以数组(array)存储,也就是以空字符(\0)结尾的 **char 类型数组**——————————字符串本身是一个数组!!
输出:用 %s 转换说明来处理字符串的输入和输出
输入和输出必须给出**字符串的首地址**,可以直接是字符串常量、字符数组名、字符指针变量名。
如何判断是否为字符串?
1.逐个赋值
char str1[5]={'a','b','c','d','e'}; //不是字符串
char str2[5]={'a','b','c'}; //未赋值的元素为'\0',因此是字符串
char str3[]={'a','b','c','d','e'}; //省略数组长度赋值,长度根据字符的个数确定,不会自动补充'\0',因此不是字符串
2.整体赋值
char str4[5]={"abcde"}; //不是字符串!'\0'也算一个字符串,但是数组长度仅5.
char str5[]={"abcde"};//是字符串!长度根据字符的个数确定,字符串长度应该为6(含有‘\0’)
总结:用字符集合的方式赋值时,养成习惯在末尾补充’\0’否则不是字符串
如何找到一个字符串的末尾下标?
1.将字符串放在数组中 char a[MAX]="hello world!";//有时候#define MAX=100+10;这里的10是保护数组不越界而故意设置的。
2.while实现:
int len=0;
while(a[len])
len++; //注意!![while的性质]while遇到空格并不会停止循环,而是遇到‘\0’、0 会停止循环!!!!
//这一段运行结束后,下标指向‘\0’,即为被“拦截”的下标。
三、题目讲解(以记忆为主)
1.结构化程序
三种结构:顺序、选择(分支)、循环 (重复)
2.关键字
关键字是使C语言编写变得流畅的关键!
关键字的分类:类型(数据类型、结构体类型)、分支、循环、跳转...等等常见的。
3.
4.后缀
5.知识点:C程序的基本组成单位是 函数 !!!
6.预处理
7.编译型语言
8.软件调试
9.杂项
二、数据类型
1.
2.优先级问题
e.g. *(a+0)[1] 看似访问的是a[0][1]吧?
实际上由于[]的优先级大于* 所以[]先和()结合
附上优先级表:
口诀: 单目右、单目左、算术、关系、逻辑单、逻辑双、逻辑三、赋值、逗号。
改编版口诀:一只眼的VZS 右手掏出手机和左手一起算数,算男男男关系,一个男生单眼皮,一个男生双眼皮,还有一个男生三眼皮,一波操作把老夫子(赋值)逗(逗号)笑了。
3.unsigned类型被赋值了一个负数,会输出什么值呢?
unsigned int a,b,c;
a=-1;b=-2;c=-3;
结果:a:2^32-1 b:2^32-2 c:2^32-3
涉及到原码、反码、补码相关知识
原理解释:计算机内数值都是以补码的形式存在的,以a=-1为例:
-1原码:1000 0000 0000 0001
反码: 1111 1111 1111 1110
补码: 1111 1111 1111 1111(补码=反码+1)
用个不恰当但是形象的角度解释,补码满秩! 也就是说存储着无符号整型的最大数据!
用二进制转十进制:2^0+2^1+.....+2^31=2^32-1 !!!(等比数列求和)
over!!
三、分支结构
1.switch和if和while
switch(i++) 不等价于 switch(++i)
if(i++) 如果i=0,那么不执行;
while(i++) 不等价于 while(++i)
综上所述:三者内如果有自增运算符,那么都遵循自增的规则。
e.g.
--i; 先自减再参与运算
i--; 先参与运算再自减
2.switch&case
()内只能是整型或者字符表达式(ASCII),不能为实型 (浮点型)
case后只能是常量或常量表达式,不能是变量!(条件不可变)
3.switch
四、 循环结构
五、 数组
1.
2.strcpy()
char * strcpy ( char * destination, const char * source );
destination表示目标字符串的地址。
source表示源字符串的地址。
函数的返回值为目标字符串的地址。
**使用strcpy的基本步骤:
1.确保目标字符串dest有*足够的空间*来存储源字符串src的内容。
2.调用strcpy函数,将源字符串src的内容*(包括'\0')*复制到目标字符串dest中。
3.返回目标字符串dest的地址。
注意事项:
1.目标字符串必须有足够的空间来存储源字符串src的内容,否则可能会发生缓冲区溢出的问题。
#include <stdio.h>
#include <string.h>
int main()
{
char dest[5] = "*****";
char src[] = "Hello world!";
strcpy(dest, src);
printf("复制后的字符串为:%s\n", dest);
return 0;
}//error dest周围的堆栈已损坏!
2.在使用strcpy函数时,应确保源字符串src以'\0'结尾,负责可能会导致复制结果不正确。
#include <stdio.h>
#include <string.h>
int main()
{
char dest[5] = "*****";
char src[] = { 'a', 'b', 'c' };//没有'\0'
strcpy(dest, src);
printf("复制后的字符串为:%s\n", dest);
return 0;
}//程序最终崩溃,因为src数组所在的内存空间后面存储的内容未知,
strcpy函数不遇到'\0'拷贝就不会停止,
这就会导致越界访问,出现BUG。
3.目标空间必须可变
int main()
{
char* dest = "Hello world!";//目标空间是一个常量字符串,意味着不可以被修改!!
char src[5] = { "abcde" };
strcpy(dest, src);
printf("复制后的字符串为:%s\n", dest);
return 0;
}
3.数组传参降阶为指针
void max(char a[100])
&
void max(char *p)//二者实际上是等价的,不要以为前者数组开辟了100的空间
实际上都是传输了首元素的地址。数组名传参,形参自动降阶成指针
3.背下来!
4.程序设计题(字符指针)
WP:
void fun(char*a,char*p)
{
char*t=a; //用指针变量t模拟一下a
for(t=a;t<=p;t++)
if(*t!='*')
*(a++)=*t; //把最后一个字母前的非*量保留下来存入a中
for(;*t!='\0';t++)//此前t已经指向了最后一个字母
*(a++)=*t;
*a='\0';//因为是字符串,记得在末尾添加'\0'
}
5.二维数组----特殊的一维数组
6.数组长度只能是常量或常量表达式
六 、函数
1.分析函数功能
易错点:容易认为strcmp是比较字符串长度的,实际上是把两个字符串每一位拎出来,自左向右逐个比对 ASCII值直到出现不同的字符。
2.形参分配空间问题
3.
4.
5.函数功能
6.函数功能
7.函数声明 类型+函数名+()或者类型+函数名+(类型,类型,...)
七、指针
1.
2.混合函数知识
3.二维指针&指针之间恰当的赋值
看看这道题捏[可爱]
char *k[3] 是一个指针数组;char * p是一个指针变量 二者不能赋值!!
4.字符数组赋值
字符数组别和字符串长度混淆了!!!!!!
5.数组元素引用
6.malloc()
7.
8.
9.指针数组
10.指针赋值
11.函数功能的理解&while遇到'\0'停止
12.
13.
14.
15.
16.
17.
18.
19.独特的指针引用
20.
21.函数功能
22.strcmp()
23.字符串的指针赋值
24.字符串的输出
25.数组指针
26.函数功能
27.
28.优先级问题
29.
30.字符串输出
31.
32.函数功能
33.
34.
35.
36.
37.
38.
39.
八、结构体与宏
九、文件
见12.19发布的博客:C语言学习通作业解析(文件)-CSDN博客