常用头文件
stdio.h标准输出输出头文件
#include<stdio.h>
prinft()//标准输出语句
printf("直接字符串输出");
float a =1.2789;
printf("占位符输出 保留两位小数%.2f",a); //1.28
scanf()//标准输入语句
int a,b;
printf("请输入两个数\你");
scanf(" %d %d",&a,&b);
printf("输入的数 a=%d\n输入的数 b=%d",a,b);
/*
输入的数 a=1
输入的数 b=2
*/
putchar(c)//输出单独字符
getchar() //获取单个字符
char a,b;
prinft("请输入两个个字符\你");
a = getchar();
b = getchar();
getchar();
putchar(a);
putchar(b);
math.h C语言数学库
#include<math.h>
常用函数:
sqrt(x) //开平方
double a = sqrt(16);
printf("%.2lf",a); //4.00
pow(2,3) //次方根 二的三次方
double b = pow(2,3);
printf("%.2lf",b);//2.00
round(3.145) //四舍五入
double c = round(3.145);
printf("%.2lf",c);//3.00
double c1 = round(3.545);
printf("%.2lf",c);//4.00
abs(-1); //整数绝对值
int a = abs(-1);
printf("%d",a); // 1
fabs(-1.258); //浮点数绝对值
double d = fabs(-1.258);
printf("%.3lf",d); //1.258
floor(1.258); //向下取整
double e = floor(1.258);
printf("%.3lf",e); //1.000
ceil(1.258); //向上取整
double f = ceil(1.258);
printf("%.3f",f);//2.000
常量PI M_PI
printf("%lf",M_PI);
stdlib.h C语言标准库
#include<stdlib.h>
malloc():动态分配内存
int* arr = (int*)malloc(4 * sizeof(int)); //分配四个 int 单位的内存
free(arr);
calloc():分配已清零的内存
realloc():调整已分配内存大小
free():释放动态内存(防止内存泄露)
string.h 字符
#include <string.h>
选择控制结构:
if 单分支语句
int age = 0;
scanf(" %d",&age);
if(age <18)
{
printf("未成年");
}
if-else if双分支语句
int age = 0;
scanf(" %d",&age);
if(age<18)
{
printf("未成年");
}
else
{
printf("成年人");
}
if-else-if-else if多分支语句
int age = 0;
scanf(" %d",&age);
if(age>=70)
{
printf("老年人");
}else if(age>=40)
{
printf("中年人");
}else if(age>=18)
{
printf("年轻人");
}else{
printf("未成年");
}
switch多分支语句
数字控制案例
int selector = 1;
while(selector != 0){
printf("欢迎使用本系统,请输入操作指令续序号:\n 1:添加用户\n 2:删除用户 \n 0:退出系统\n");
scanf(" %d",&selector);
switch(selector){
case 1:
printf("已执行添加用户\n");
break;
case 2:
printf("已执行删除用户\n");
break;
case 0:
printf("感谢使用!下次见\n");
break;
default:
printf("操作指令错误,请重新输入\n");
}
}
字符控制案例
char selector = 'a';
while(selector != 'q'){
printf("欢迎使用本系统,请输入操作指令续序号:\n a:添加用户\n b:删除用户 \n q:退出系统\n");
selector = getchar();
while(getchar() != '\n');
switch(selector){
case 'a':
printf("已执行 添加用户!\n");
break;
case 'b':
printf("已执行 删除用户\n");
break;
case 'q':
printf("感谢使用,下次见!\n");
break;
default:
printf("指令输入有误,请重新输入\n");
}
}
循环控制语句
for循环 满足条件才循环
for(int i = 1;i<=5;i++){
printf("第%d次",i);
}
continue
结束本次循环(跳过 continue 后面的代码进入下一轮循环【如果有】)
for(int i =0;i<=5;i++){
if(i == 3){
continue;
}
printf("%d",i);//0,1,2,4,5
}
break
终止循环
for(int i =0;i<=5;i++){
if(i == 3){
break;
}
printf("%d\n",i); //0,1,2}
while循环 满足条件才循环
int counter = 1;
while(counter<=5){
printf("第%d次",counter); //1,2,3,4,5
counter++;
}
do-while循环 不关条件是否满足,先执行一次循环 - 满足条件才循环
int counter = 1;
do{
printf("第 %d 次",counter); //1,2,3,4,5
counter++;
}while(counter<=5);
函数
函数的定义
无返回值函数
void sayHello(){
printf("hello\n");
}
带返回值函数
int add(int a,int b){
int sum = a+b;
return sum;
}
递归函数
栈的概念
入栈push -> 出栈pop
先入后出
例子:累加和
求 1-num 的累加和
int sum(int num){
if(num == 1){
return 1; //程序出口 退出条件
}
return num + sum(num-1); //自己调用自己
}
指针:
指向内存地址
间接寻址运算符 *
根据地址找到里面存的值
取地址运算符 &
拿到某变量在内存的地址
int a = 20;
int *p = &a; //此处*表示声明指针
//以下都是一样的意思 (都是修改 a 的值为 10)
a = 10;
printf("%d\n",a); // 10
*p = 10;
printf("%d\n",a); // 10
交换变量例子
全局变量:放置在所有函数的外侧最上方 程序运行结束才销毁
局部变量:放置在单独函数内部包括 main 函数 随之函数运行完成结束而销毁,仅在函数内部可使用
注意 :函数要先声明方可使用,程序是顺序执行 必须先在程序最顶部定义,程序运行时根据顺序执行先读入自定义函数到内存。才可以被主函数查找并调用!
#include <stdio.h>
// 1. 函数声明(写在最顶部!) 或者直接在这里定义好相关的功能
void swap(int *a, int *b);
int main() {
swap(&a, &b); // 2. main 调用,能找到!
return 0;
}
// 3. 函数定义(可以放在 main 后面!)
void swap(int *a, int *b) {
int temp;
temp = *a;
*a = *b;
*b = temp;
}
交换变量函数:
放到主函数的外面的上面
void swap(int *a,int *b){
int temp;
temp = *a;
*a = *b;
*b = temp;
}
主函数内:
int a =0;
int b =0;
scanf(" %d %d",&a,&b);
printf("未交换前的 a=%d;b=%d\n",a,b);
swap(&a,&b);
printf("交换后的 a=%d,b=%d\n",a,b);
指针数组
int a=10,b=20,c=30;
//定义指针数组 存储数的指针地址
int *arr[] = {&a,&b,&c};
//使用间接寻址操作符* 取对应数组索引下指针地址的值
printf("%d\n%d\n%d",*arr[0],*arr[1],*arr[2]); //10 20 30
函数指针
//普通函数
int add(int a,int b){
return a+b;
}
//函数指针
int (*add_ptr)(int,int) = add;
//以下写法代表的是一样的执行
printf("%d\n",add(1,2));
printf("%d\n",add_ptr(1,2));函数指针的应用
回调函数
//mian(外部)函数上面
double calc(double a,double b,double (*func)(double,double)) //double(*func)(double,double)代表一个名为 func 的函数指针
{
return func(a,b);//返回 func 函数的处理结果
}
double div1(double a,double b){
return a/b;
}
double add(double a,double b){
return a+b;
}
//main 函数内
double a = 0.0;
double b = 0.0;
double res = 0.0;
char operation = ' '; //注意字符不能为空 此处使用空格初始化
printf("请输入两个数:\n");
scanf(" %lf %lf",&a,&b);
printf("请输入进行的运算:\n + \n /\n");
scanf(" %c",&operation);
if(operation == '+'){
res = calc(a,b,add); //使用+运算函数处理
printf("%lf",res);
}else if(operation == '/'){
res = calc(a,b,div1); //使用/运算函数处理
printf("%lf",res);
}else{
printf("不支持的操作");
}
动态内存 malloc + 字符指针
固定数组大小
char str[20];动态分配
char *str_ptr = (char*)malloc(20 * sizeof(char));// 开辟 20 个字符长度的 str 指针
char *str1_ptr = (char*)malloc(20);
判断是否申请成功
if(str_ptr == NULL){
return -1;
}
使用:
strcpy(str_ptr,"hello 小胡");
printf("%s",str_ptr);
数组
一维数组
数组的定义
int arr[]={1,2,3,4,5}
数组访问
数组索引 0(第一个元素)设置为 100
arr[0] = 100;
数组指针 指向数组第一个元素(索引 0)的地址
int *arr_ptr = arr;
向函数传递一维数组
void func1(int arr[],int len){};
指针写法
void func2(int *arr,int len){};
带数组大小
void func3(int arr[5]){};
基于数组的常用算法和应用
1.遍历数组
int arr[] = {1,2,3,4,5};
int len =5;
for(int i =0;i<len;i++){
printf("%d",arr[i]);
}
2.求数组最大值
int arr[] = {1,2,3,4,5};
int max = arr[0];//设置第一位为默认最大值
for(int i =0;i<5;i++){
//如果当前索引下的数大于默认值 就把他设置为最大值
if(arr[i]>max){
max = arr[i];
}
}
3.求数组最小值
int arr[] = {1,2,3,4,5};
int min = arr[0];//设置第一位为默认最小值
for(int i=0;i<5;i++){
//如果当前索引下的数小鱼默认值 就把他设置为最小值
if(arr[i]<min){
min = arr[i];
}
}4. 数组求和
int arr[] = {1,2,3,4,5};
int sum = 0;
for(int i =0;i<5;i++){
sum+=arr[i];
}
5.数组反序
int arr[] = {1,2,3,4,5};
int len = 5;
//仅需要循环一半
for(int i =0;i<len/2;i++){
//交换变量 最左边的交换到最右边
int temp = arr[i];
//最右边即 数组长度-1(因为下标从0开始)-i(减去当前下标 可算出跟右侧下标为几的元素交换)
//即 len-1-i 就是右边要交换的元素索引
arr[i] = arr[len-1-i];
arr[len-1-i] = temp;
}
6.查找元素
int arr[] = {1,2,3,4,5};
int len = sizeof(arr)/siziof(int);
int target = 4;
for(int i = 0;i<len;i++){
if(arr[i] == target){
printf("找到啦 你要找的数字%d 的target,位于索引%d",target,i);
}
}
7.冒泡排序
升序版:
int arr[] = {2,1,4,9,3};
int len = sizeof(arr)/sizeof(int);
升序:从小到大排 (升:越来越大)
降序:从大到小排 (降:越来越小)
//无需进行最后一次比较(最后一位会自己排好) 故len-1
for(int i = 0 ;i<len-1;i++)
{
//每次都将本索引位置的元素 跟其他几位索引的元素进行比较
//减去当前索引 i 的位置可以算出需要剩余比较的次数(每一轮少比 i 次)
for(int j = 0;j<len-i-1;j++){
//两两比较 大的后移
if(arr[j]>arr[j+1]){
//交换 arr[j]和 arr[j+1]
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
//输出验证
for(int i = 0;i<len;i++){
printf("%d \t",arr[i]);
}
降序版:
int arr[] = {2,1,6,7,9,8};
int len = sizeof(arr)/sizeof(int);
for(int i = 0;i<len-1;i++){
for(int j = 0;j<len - i -1;j++){
//两两比较小的放后面
// 比较条件 j+1>j j+1 大 j小 j+1 和 j 互换位置
//升序降序仅和 if 的条件判断有关!
if(arr[j+1]>arr[j]){
int temp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = temp;
}
}
}
//输出验证
for(int i = 0;i<len;i++){
printf("%d \t",arr[i]);
}
二维数组
向函数传递二维数组
数组案例
输入输出数组
倒置数组
向函数传递一维数组
c语言字符串
字符串定义与使用
常用的字符串函数
常用排序算法(数组)
一维数组插入 删除 查找
冒泡排序
选择排序
结构体
结构体基本结构定义
struct Student{
char name[20];
int age;
float score;
};
创建结构体实例
struct Student stu; //创建名为 stu 的 Student 结构体
结构体赋值
1.逐个赋值:
strcpy(stu.name,"张三");
stu.age = 18;
stu.score = 99.5;
2.一次赋值
struct Student stu1 = {"Ethan",20,99.9};
访问结构体成员
printf("姓名:%s\n",stu.name);
printf("年龄:%d\n",stu.age);
printf("成绩:%f\n",stu.score);
printf("姓名:%s\n",stu1.name);
printf("年龄%d\n",stu1.age);
printf("成绩:%f\n",stu1.score);
指向结构体的指针
struct Student stu2; //创建 stu2 Student结构体实例
struct Student *stu_ptr = &stu2; //创建 stu_ptr 结构体指针,并赋 stu2 结构体实例 地址给 stu_ptr
strcpy(stu_ptr->name,"小胡");
stu_ptr->age = 21; //通过结构体指针设置 age
stu_ptr->score = 99.8;
printf("%s \t %d \t %f",stu2.name,stu2.age,stu2.score);
结构体指针的应用
1.通过函数修改结构体实例
普通函数变量传参 函数里面变了实际结构体实例为改变(拷贝)
void changeStu(struct Student *stu_ptr,char name[],int age,float score){
strcpy(stu_ptr->name,name);
stu_ptr->age = age;//修改的是实例的参数
stu_ptr->score = score;}
int main() {
struct Student stu; //创建stu结构体实例
struct Student *stu_ptr = &stu;
//调用 changeStu函数修改结构体实例
changeStu(stu_ptr,"小胡",19,99.6);
printf("%s\t %d\t %f",stu_ptr->name,stu_ptr->age,stu_ptr->score);
}
2.节省内存
复杂结构体传参
太大了 使用结构体指针仅需传一个地址
// 调用
changeStu(&stu); // 传地址
否则
需要传入整个结构体
// 调用
changeStu(stu);
3.数据结构 链表,树
struct Node{
int data;
struct Node *next;};
4.动态内存创建结构体
//创建 Student 结构体指针 stu_ptr 并将分配好的内存地址给到结构指针
struct Student stu_ptr = (struct Student )malloc(sizeof(struct Student));
if(stu_ptr == NULL){
printf("内存分配失败!");
return -1;}
strcpy(stu_ptr->name,"小胡");
stu_ptr->age = 20;
stu_ptr->score = 90.0;
printf("%s\t %d \t %.2f",stu_ptr->name,stu_ptr->age,stu_ptr->score);
free(stu_ptr);//使用完成后释放内存
stu_ptr = NULL; //指针回空