Hello World
自己从无到有的hexo网站搭建 纯纯的免费
Github真的是好东西
网站目前是这样的 我也会慢慢优化的 加油
一起进步一起学习
编辑软件是Typora
目前是白嫖 后面估计会补票
白嫖链接typora下载和破解(仅供学习) - hackettt - 博客园 (cnblogs.com)
完美结束
markdown使用方法
使用简单的标记语法
一级标题 | #一级标题 |
---|---|
二级标题 | ##二级标题 |
新建表格 | ctrl+T |
区块元素
这是一个区块的内容
这是一个区块中的区块
区块元素 | >这是一个区块的内容 |
---|---|
跳出区块 | 按两下回车键 |
强调元素
强调的内容
强调的内容
加粗的内容
加粗的内容
倾斜 | * * | _ _ |
---|---|---|
加粗 | ** ** | __ __ |
分割线
分割线 | *** | — | ___ |
---|
代码
#include<stdio.h>
int main()
{
printf("This is a C program.\n");
return 0;
}
代码 | ``` |
---|
注意:分割元素之间不能出现内容字符,但是可以出现空格
超链接元素
行内式
[百度](http://www.baidu.com)
参考式
EXIT外部中断
EXIT外部中断
中断:在主程序执行过程中,出现了特定的中断触发条件(中断源),使得CUP暂停当前正在运行的程序,转而去处理中断程序,处理完成后有返回原来被 暂停的位置继续运行
中断优先级:当有多个中断
EXIT可以监测指定GPIO口的电平信号,当其指定的GPIO口产生电平变化时,EXIT将立即向NVIC发出中断申请,经过NVIC裁决后即可中断CPU主程序,使CPU执行EXIT对应的中断程序
TIM定时器(Timer)
C语言基础
- 面向过程编程语言,性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机、嵌入式开发、 Linux/Unix等一般采用面向过程开发,性能是最重要的因素。
- 编译性语言,效率高,灵活性高,可移植性高。
- 第一个程序
#include <stdio.h>
int main()
{
printf("Hello World\n");
return 0;
}
- 打印——-输出
- printf 格式化输出函数 打印文本到屏幕上
- 什么是变量?
- 确定目标和储存的空间
- 变量名:变量名只能是英文字母和数字或者下划线组成,第一个必须是字母或者下划线开头,变量名区分大小写,不能使用关键字符。
- 声明变量的类型,int ,char,float,double
- 变量和常量
- 定义符号常量
#define URL "https://muyeyueyue.github.io/"
#define NAME "muyeyue"
//宏定义
- 字符串常量
- 字符 ‘F’ ‘D’ ‘A’ ‘B’
- 字符串 “Hello World!” 在每一个字符串后编译器会自动加上一个”\0”表示字符串结束 特殊的转义字符
- 数据类型:整数类型int,浮点数类型float double,字符类型char,布尔类型_Bool 用于判断真或者假,枚举类型
- 数组类型,结构类型,联合类型
- sizeof运算符:用于获得数据类型或表达式的长度
#include <stdio.h>
//数据类型所占长度
int main()
{
printf("int = %d\n",sizeof(int));
printf("short int = %d\n",sizeof(short));
printf("_Bool =%d\n",sizeof(_Bool));
return 0;
}
signed 带符号位的整型和unsigned 不带
signed第一位是符号位 0是正数 1是负数
补码
7变-7 的方法
#include <stdio.h>
#include <math.h>
// singned 与 unsigned 正负数区别
int main()
{
unsigned int result = pow(2,32)- 1;
printf("result = %u\n",result);
return 0;
}字符和字符串
#include <stdio.h>
int main()
{
char a = 'C';
printf("%c = %d\n",a,a);
return 0;
}
ASCII字符表 7位二进制数来表示所有的大写和小写字符 ,数字0到9,还有一些特殊控制字符。
字符类型是一种特殊的整型 char 变量名【数量】;
#include <stdio.h>
//字符串的定义和打印
int main()
{
char a[] = "Hello!";
char b[5]={'M','u','y','e','\0'};
char c[] = {"Muye"};
printf("%s\n",a);
printf("%s\n",b);
printf("%s\n",c);
return 0;
}
- 算数运算符:
- 什么是单目和双目:取决于有多少个操作数
- 例子:1(操作数)+(运算符)2(操作数)
- 运算符的优先级和结合性:
#include <stdio.h>
int main()
{
int i, j,k;
i= 1+2;
j= 1+2*3;
k= i+j+ -1+pow(2,3);
printf("i=%d\n",i);
printf("j=%d\n",j);
printf("k=%d\n",k);
return 0;
}
- 类型转换:不同的数据类型相运算的时候 系统默认将数据转换成数据类型较大的一方进行运算
- 例子:1+2.0 == 1.0 +2.0
#include <stdio.h>
//类型转换
int main()
{
printf("整型输出:%d\n", 1+(int)2.0);//强制转换为int型
printf("浮点型输出:%f\n",1+2.0);
return 0;
}
- 分支结构程序设计
- 关系运算符:得到的值为逻辑值 真(1)或者假(0)
代码 | ``` |
---|
#include <stdio.h>
//关系运算符返回值 1或0
int main()
{
int a=5,b=3;
printf("%d\n",1<2);
printf("%d\n",a>b);
printf("%d\n",a<=b+1);
printf("%d\n",'a'+'b'<='c');
printf("%d\n",(a=3)>(b=5));
return 0;
}
- 逻辑运算符:逻辑非 ! 逻辑与&& 逻辑或||
#include <stdio.h>
//逻辑运算
int main()
{
int a = 5, b= 3;
printf("%d\n",3>1 && 1<2);
printf("%d\n",3+1 || 2==0);
printf("%d\n",!(a+b));
printf("%d\n",!0+1<1||!(3+4));
printf("%d\n",'a'- 'b' && 'c');
return 0;
}
短路求值:逻辑与和逻辑或采用短路求值的方式
#include <stdio.h>
//短路取值
int main()
{
int a=3,b=3;
(a=0) && (b=5);
printf("a=%d,b=%d\n",a,b);
(a=1) || (b=5);
printf("a=%d,b=%d\n",a,b);
return 0;
}当逻辑运算符存在时 会优先运算左边的值 如果为真 则不计算右边的值 直接输出
if语句1
#include <stdio.h>
//if 判断语句
int main()
{
int i;
printf("今年多大:");
scanf("%d",&i);
if(i>=18)
{
printf("可以进入网吧!\n");
}
else
{
printf("未成年人不允许进入\n");
}
return 0;
}if语句2
#include <stdio.h>
//if 判断语句2
int main()
{
int i;
printf("输入你的成绩:");
scanf("%d",&i);
if(i>=90)
{
printf("A\n");
}
else if(i>=80 && i<90)
{
printf("B\n");
}
else if (i>=70 && i<80)
{
printf("C\n");
}
else if(i>=60 && i<70)
{
printf("D\n");
}
else
{
printf("E\n");
}
return 0;
}
- switch 语句与分支嵌套
#include <stdio.h>
//SWITCH 语句
int main()
{
char i;
printf("请输入成绩:");
scanf("%c",&i);
switch(i)
{
case 'A':printf("你的成绩在90分以上!\n");
break;
case 'B':printf("你的成绩在80到90之间!\n");
break;
case 'C':printf("你的成绩在70到80之间!\n");
break;
case 'D':printf("你的成绩在60到70之间!\n");
break;
case 'E':printf("你的成绩在60分以下!!!\n");
break;
default: printf("请输入有效的成绩评级\n");
}
return 0;
}
- 分支结构的嵌套
#include <stdio.h>
//if语句的分支嵌套
int main()
{
int a,b,i;
printf("请输入两个数:");
scanf("%d %d",&a,&b);
if(a!=b)
{
if(a>b)
{
i=a-b;
printf("%d > %d\n",a,b);
printf("%d - %d = %d\n",a,b,i);
}
else
{
i=b-a;
printf("%d < %d\n",a,b);
printf("%d - %d = %d\n",b,a,i);
}
}
else
{
printf("%d = %d\n",a,b);
}
return 0;
}
- 悬挂else: else始终与最近的if 相匹配 所以要注意大括号的使用
- 等号问题:C语言中 “=”为赋值号 “==”为等号
代码 | ``` |
---|
whiel 和do while循环
#include <stdio.h>
//从1加到100的和
int main()
{
int i=1,sum=0;
while(i<=100)
{
sum=sum+i;
i=i+1;
}
printf("结果是:%d\n",sum);
return 0;
}
while 循环
#include <stdio.h>
//用户键盘输入字符的数量统计
int main()
{
int count=0;
printf("请输入一串英文字符\n");
while(getchar() != '\n')
{
count=count+1;
}
printf("你总共输入了%d个字符!\n",count);
return 0;
}do while 循环
do 循环体
while(表达式); // 注意 这里是有**”;”**
循环的基本结构:1.初始化计数器 2.循环条件 3.更新计数器
for语句 for(表达式1;表达式2;表达式3)
循环体
#include <stdio.h>
//简单的for循环操作
int main()
{
int count;
for(count=0;count <10 ;count++)
{
printf("Hello Muye!%d次\n",count);
}
return 0;
}
- 练习 写一个程序判断一个数是否为素数
#include <stdio.h>
//判断一个数是否为素数
int main()
{
int i, num;
_Bool flag =1;
printf("请输入一个整数:");
scanf("%d",&num);
for(i=2;i< num/2;i++)
{
if(num % i == 0)
{
flag =0;
}
}
if(flag)
{
printf("%d是一个素数!\n",num);
}
else
{
printf("%d不是一个素数!\n",num);
}
return 0;
}
- for语句的灵活应用
#include <stdio.h>
//for语句的灵活应用
int main()
{
for(int i=0,j=20;i<j;i++,j--)
{
printf("第%d个\n",i);
}
return 0;
}
循环嵌套
先执行内层循环 再执行外层循环
#include <stdio.h>
//9X9乘法表
int main()
{
int i,j;
for(i=1;i<=9;i++)
{
for(j=1;j<=i;j++)
{
printf("%d*%d= %-2d",i,j,i*j);
}
putchar('\n');
}
return 0;
}break语句
#include <stdio.h>
//判断一个数是否为素数 break语句升级版
int main()
{
long long i, num;
_Bool flag =1;
printf("请输入一个整数:");
scanf("%lld",&num);
for(i=2;i< num/2;i++)
{
if(num % i == 0)
{
flag =0;
break;
}
}
if(flag)
{
printf("%lld是一个素数!\n",num);
}
else
{
printf("%lld不是一个素数!\n",num);
}
printf("i=%lld\n",i);
return 0;
}
break例子
#include <stdio.h>
//break 只能跳出当前循环
int main()
{
int i,j;
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
if(j == 3)
{
break;
}
}
}
printf("i=%d, j=%d\n",i,j);
return 0;
}continue语句
跳过本次循环体中余下尚未执行的语句,立即进行下一次的循环条件判定,可以理解为仅结束本次循环。
#include <stdio.h>
//用户输入检测 并消除对应的字符
int main()
{
int ch;
while((ch = getchar()) != '\n')
{
if (ch == 'C')
{
continue;
}
putchar(ch);
}
putchar('\n');
return 0;
}
- 赋值运算符:左边必须是一个变量
- a=a+1 == a + =1
- a= a-2 == a- =1
- 自增自减运算符
- i=i+1 == i++ == ++i
- i=i-1 == i– == –i
代码 | ``` |
---|
-
#include <stdio.h>
//区别 i++ 和 ++i
int main()
{
int i =5, j;
j = ++i;
printf("i = %d, j = %d \n",i ,j);
i=5;
j= i++;
printf("i=%d, j= %d\n",i,j);
return 0;
}
- ++i的效率更高
- j= i++; 相当于先把i赋值给j 然后再加1
- 逗号运算符:int i=1,j=2,k=3;
语法:表达式1,表达式2,。。。。。。。表达式N
- 只要有逗号运算符 表达式都是从左到右计算的
- 条件运算符:
goto语句
#include <stdio.h>
//goto语句的用法
int main()
{
int i=5;
while(i++)
{
if(i>10)
{
goto A;
}
}
A: printf("Here, i = %d\n",i);
return 0;
}
数组
- 类型 数组名[元素个数]
- 例子: int a[6]; char b[5]; double c[3];
- 数组不能被动态定义
- 循环和数组的关系
- 通常使用循环来访问数组:
int a[10]
for(i=0;i<10;i++)
{
a[i]= i;
}
- 数组的经典应用
#include <stdio.h>
//用数组完成统计所有人的成绩 并取平均数
#define NUM 10
int main()
{
int s[NUM];
int i, sum = 0;
for(i=0;i<10;i++)
{
printf("请输入第%i位同学的成绩:",i+1);
scanf("%d",&s[i]);
sum+= s[i];
}
printf("成绩录入完毕,这次考试的平均分是:%.2f",(double)sum/NUM);
return 0;
}
数组的初始化 可以定义特定的值给数组
例子: int a[]={1,2,3,4,5,6};
int a[10]={[3]=5,[6]=6,[7]=8};
#include <stdio.h>
//给第3,6,7位分别赋值5,6,8 其它值系统默认为0
int main()
{
int i;
int a[10]={[3]=5,[6]=6,[7]=8};
for(i=0;i<10;i++)
{
printf("%d\n",a[i]);
}
return 0;
}字符串处理函数
字符串处理函数
#include <stdio.h>
#include <string.h>//字符串处理函数头文件
//sizeof str取的是数组总长度 多一个'\0'
//strlen str 取的是数组长度
int main()
{
char str[] = "I love Stm32 very much!";
printf("sizeof str = %d\n",sizeof(str));
printf("strlen str = %u\n",strlen(str));
return 0;
}
- 获取字符串的长度:strlen str
- 拷贝字符串: strcpy 和 strncpy
#include <stdio.h>
#include <string.h>//字符串处理函数头文件
int main()
{
char str1[] = "Original String";
char str2[] = "New String";
char str3[100];
strcpy(str1,str2);
//将2号位覆盖到1号位 注意:被覆盖的长度一定要比原来的长
strcpy(str3,"Copy Successful");
//将Copy Successful覆盖到数组3中
printf("str1: %s\n",str1);
printf("str2: %s\n",str2);
printf("str3: %s\n",str3);
return 0;
}
- strncpy函数
#include <stdio.h>
#include <string.h>
//strncpy函数的使用
int main()
{
char str1[]= "To be or not to be ";
char str2[40];
strncpy(str2,str1,5);//将str1中的前五个字符覆盖到str2中
//不含有'\0'结束字符
str2[5] = '\0';
printf("str2: %s\n",str2);
return 0;
}
- 连接字符串:strcat和strncat
代码 | ``` |
---|
#include <stdio.h>
#include <string.h>
// 字符串连接函数使用方法 strcat
int main()
{
char str1[] = "I love mu";
char str2[] = "I love yue";
strcat(str1," ");// 将空格符连接在str1后面
strcat(str1,str2);//将str2连接在str1后面
printf("str1: %s\n",str1);
return 0;
}
- 比较字符串 :strcmp和strncmp
- 使用方法:strcmp(str1,str2) 返回值为0 则两个字符串相等
#include <stdio.h>
#include <string.h>
//strcmp字符串对比函数使用方法
int main()
{
char str1[] = " I love Yue";
char str2[] = " I love Yue";
if(!strcmp(str1,str2))
{
printf("str1和str2相等\n");
}
else
{
printf("存在差异\n");
}
return 0;
}
二维数组
- 二维数组的定义
二维数组的访问
数组名【下标】【下标】 防止数组越界
#include <stdio.h>
//二维数组的使用方法
int main()
{
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
//int a[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12};
int i,j;
for(i=0;i<3;i++)
{
for(j=0;j<4;j++)
{
printf("%d ",a[i][j]);
}
printf("\n");
}
return 0;
}
指针
- 指针和指针变量 存放地址的变量
- 定义方法: 类型名 *指针变量名
- char *pa; //定义一个指向字符型的指针变量
- int *pb; //定义一个指向整型的指针变量
指针的基本用法
#include <stdio.h>
//指针的基本用法
int main()
{
char a ='F';
int f = 123;
char *pa = &a;
// 类型是char* pa;
// pa = &a;
int *pb = &f;
printf("%c\n",*pa); //
printf("%d\n",*pb);
*pa = 'C';
*pb += 1;
printf("now,a= %c\n",*pa); //
printf("now,f= %d\n",*pb);
printf("sizeof pa = %d\n",sizeof(pa));//查看有多少个字节
printf("sizeof pb = %d\n",sizeof(pb));
printf("the addr of a is : %p\n",pa);//查看地址
printf("the addr of b is : %p\n",pb);
return 0;
}避免访问未初始化的指针
指针和数组
#include <stdio.h>
//指针代表的含义
int main()
{
int a;
int *p = &a;
printf("请输入一个数:");
scanf("%d",&a);
printf("a = %d\n",a);
printf("请再输入一个整数:");
scanf("%d",p);//p就代表a的地址 *p代表a的值
printf("a = %d\n",a);
return 0;
}
数组名的关系
数组名其实是数组第一个元素的地址
#include <stdio.h>
//数组名是第一个元素的地址
int main()
{
char str[128];
printf("请输入英文姓名:");
scanf("%s",str);
//printf("你的英文姓名是:%s\n",str);
printf("str 的地址是:%p\n",str);//%p是打印地址的
printf("str 的地址是:%p\n",&str[0]);
return 0;
}数组的地址
#include <stdio.h>
//数组在存储中是按顺序放置的
int main()
{
char a[] = "FishC";
int b[5] = {1,2,3,4,5};
float c[5] = {1.1,2.2,3.3,4.4,5.5};
double d[5] = {1.1,2.2,3.3,4.4,5.5};
printf("a[0] ->%p,a[1] ->%p,a[2] ->%p\n",&a[0],&a[1],a[2]);
printf("b[0] ->%p,b[1] ->%p,b[2] ->%p\n",&b[0],&b[1],b[2]);
printf("c[0] ->%p,c[1] ->%p,c[2] ->%p\n",&c[0],&c[1],c[2]);
printf("d[0] ->%p,d[1] ->%p,d[2] ->%p\n",&d[0],&d[1],d[2]);
return 0;
}
指向数组的指针
*p表示变量的值 *(p+1)表示下一个变量的值
#include <stdio.h>
#include <string.h>
int main()
{
char *str = "I love FishC.com!";
int i,length;
length = strlen(str);//strlen函数是获取字符的个数
for(i = 0;i < length;i++)
{
printf("%c",str[i]);
}
printf("\n");
return 0;
}
- 指针数组和数组指针
- 指针和数组的区别
#include <stdio.h>
//数组名和指针的区别
int main()
{
char str[]= "I love FishC.com!";
char *target = str;
int count = 0;
while(*target++ != '\0')
{
count++;
}
printf("总共有%d个字符!",count);
return 0;
}
- 结论:数组名知识一个地址,而指针是一个左值
指针数组:
int *p1[5];
指针数组是一个数组,每一个数组元素存放一个指针变量
#include <stdio.h>
//指针数组
int main()
{
int a = 1;
int b = 2;
int c = 3;
int d = 4;
int e = 5;
int *pl[5] = {&a , &b, &c, &d, &e};
int i;
for(i=0;i< 5;i++)
{
printf("%d\n",*pl[i]);
}
return 0;
}指针数组的用法
#include <stdio.h>
//指针数组是数组
int main()
{
char *pl[5] ={
"让编程更有趣",
"just do it!",
"一切皆有可能!",
"永不止步!",
"一点点 又是一点点!"
};
int i;
for(i=0; i< 5;i++)
{
printf("%s\n",pl[i]);
}
return 0;
}
数组指针
int (*p2)[5];
- 结论:数组指针是一个指针,它指向的是一个数组
代码 | ``` |
---|
#include <stdio.h>
//数组指针是指针
int main()
{
int temp[5] = {1,2,3,4,5};
int (*p2)[5] = &temp;
int i;
for(i=0;i< 5; i++)
{
printf("%d\n",*(*p2+i));//*p2是地址 *(*p2)就是元素值了
}
return 0;
}
- 指针和数组的扩展
#include <stdio.h>
//array数组的数组名其实站了四个位置
int main()
{
int array[4][5] = {0};
printf("sizeof int :%d\n",sizeof(int));
printf("array : %p\n",array);
printf("array + 1 : %p\n",array + 1);
return 0;
}
解引用 *(array +1)
*(array +1) == array[1]
*(array+1)+3 == &array[1] [3]
数组指针和二维数组
定义一个数组指针:int (*p)[3] ;
int (*p)[3] = arrary;
结论:*(arrary+i) == array[i]
void指针
- void是无类型
- void指针为通用指针,就是可以指向任意类型的数据。
#include <stdio.h>
//void指针的应用
int main()
{
int num = 1024;
int *pi = #
char *ps = "FishC";
void *pv;//定义一个无类型的指针
pv = pi;
printf("pi:%p , pv:%p\n",pi,pv);
printf("*pv:%d\n",*(int*)pv);
pv = ps;
printf("ps:%p , pv:%p\n",ps,pv);
printf("*pv: %s\n",(char*)pv);
return 0;
}
- NULL 指针(空指针)
- #define NULL ((void *)0)
#include <stdio.h>
//定义一个指针时可以默认空指针
int main()
{
int *p1;
int *p2 = NULL;
printf("%d\n",*p1);
printf("%d\n",*p2);
return 0;
}
- 不知道指针初始化什么地址的时候,将指针初始化为NULL
- 在对指针解引用时,先要检查指针是否为NULL
指向指针的指针
-
#include <stdio.h>
//相当于无限嵌套 指针
int main()
{
int num = 520;
int *p = #
int **pp = &p;
printf("num: %d\n",num);
printf("*p: %d\n",*p);
printf("**pp :%d\n",**pp);
printf("&p:%p,pp:%p\n",&p,pp);
printf("&num: %p, p: %p, *pp:%p\n",&num,p,*pp);
return 0;
}
指针数组和指向指针的指针
地址 == 地址
值 == 值
#include <stdio.h>
//指向指针的指针的应用
int main()
{
int i;
char *Book[] =
{
"《平凡的世界》",
"《追风筝的人》",
"《三体》",
"《房思琪的初恋乐园》",
"《活着》"
};
char **Scif;
char **muyeloves[4];
Scif = &Book[2];
muyeloves[0] = &Book[0];
muyeloves[1] = &Book[1];
muyeloves[2] = &Book[3];
muyeloves[3] = &Book[4];
printf("muye喜欢的科幻小说:%s\n",*Scif);
printf("muye喜欢的小说:\n");
for(i = 0;i< 4;i++)
{
printf("%s\n",*muyeloves[i]);
}
return 0;
}
数组指针和二维数组
#include <stdio.h>
//
int main()
{
int i;
int arrary1[10] = {0,1,2,3,4,5,6,7,8,9};
int *p = arrary1;
for(i = 0;i<10;i++)
{
printf("%d\n",*(p+i));
}
return 0;
}
常量和指针
- 将变量变成常量 使用const函数
#include <stdio.h>
//
int main()
{
const float pi = 3.14;
printf("%f\n",pi);
return 0;
}