目录
一.修炼必备
二.图解递归的执行过程
三.数组
3.1 一维数组
3.2 二维数组
3.3 数组的共同问题
一.修炼必备
1.入门必备:VS2019社区版,下载地址:Visual Studio 较旧的下载 - 2019、2017、2015 和以前的版本 (microsoft.com)
2.趁手武器:印象笔记/有道云笔记
3.修炼秘籍:牛客网 - 找工作神器|笔试题库|面试经验|实习招聘内推,求职就业一站解决_牛客网 (nowcoder.com)
4.雷劫必备:leetcode 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
注:遇到瓶颈怎么办?百度百科_全球领先的中文百科全书 (baidu.com)
二.图解递归的执行过程
1.什么是递归?
——递归是指将复杂的问题转换成简单的问题进行解决,即是”大事化小,小事简单明了“,在编程语言中,常使用在函数进行递归调用(函数自身调用自身)
2.递归的条件
1)递归有限制条件,一旦递归到这个限制条件就停止递归
2)每一次递归都会接近这个限制条件
3)进行设计递归函数的时候注意要设置好限制条件,不然会”死归了“
3.一个小case快速了解递归
1)递归代码
#include <stdio.h>
void printNum(unsigned int num)
{
if (num > 9)
{
printNum(num / 10);//获取下一位
}
printf("%u ", num % 10);//得到个位的数
}
int main()
{
unsigned int num = 0;
scanf("%u", &num);
printNum(num);
return 0;
}
2)图解:
4.图解递归过程
1)求阶乘
#include <stdio.h>
int fac(int n)
{
//n <= 1是限制条件
if (n <= 1)
return 1;
else
return n * fac(n - 1);//每次递归逐渐接近限制条件
}
int main()
{
int n = 0;
scanf("%d", &n);
int res = fac(n);
printf("%d\n", res);
return 0;
}
图解过程:
2)第n个斐波那契数
#include <stdio.h>
int Fib(int n)
{
//n <= 2:限制条件
if (n <= 2)
return 1;
else
return Fib(n - 1) + Fib(n - 2);
}
int main()
{
int n = 0;
scanf("%d", &n);
int fib = Fib(n);
printf("%d\n", fib);
return 0;
}
图解过程:
三.数组
3.1 一维数组
1.什么是数组?
—— 数组是一组相同类型元素的集合
2.数组创建和初始化
1)数组的创建:数据类型 + 数组名 +[]
int arr[10];//整型数组,数据类型:int 数组名:arr
double num[10];//浮点型数组,数据类型:double 数组名:num
char ch[10];//字符数组,数据类型:char 数组名:ch
注:[]中只能是常量表达式(c99之前,c99后可以使用【变长数组:允许使用变量给数组的大小进行指定,但是数组不能进行初始化】
2)数组的初始化:数据类型 数组名[数组的大小] = {初始化值1, 初始化值2, ……};
i.完全初始化:数组完全初始化可不指定数组大小,数组大小是初始化值的个数
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
ii.不完全初始化:数组只初始化部分的数据,剩下部分的值按照数据类型判断默认值:int : 0 double : 0.0 ch : '\0'(本质还是0)
int arr[10] = { 1,2,3 };//0
double num[10] = { 1.0,2.0 };//0.0
char ch[10] = { 'a','b','c' };//'\0'
注:如果数组不想指定大小,那么进行完全初始化,若是不想指定大小又不进行初始化,则会导致程序崩溃
3.请思考以下问题
//请思考以下代码的不同
char ch[] = "abc";
char ch1[3] = { 'a','b','c' };
4.数组的使用
—— 数组是通过下标来进行使用的, 数组的下标可以准确的指定其值(需要使用[]操作符)
#include <stdio.h>
//数组的使用 - 逆序输出数组中的值
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int len = sizeof(arr) / sizeof(arr[0]);//计算数组的大小
int i = 0;
for (i = len-1; i >= 0; i--)
{
printf("%d ", arr[i]);
}
return 0;
}
5.数组的细节讨论
1)数组的下标是从0开始的
#include <stdio.h>
int main()
{
//数组的下标是从0开始的
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("%d\n", arr[0]);//arr[0]是数组的第一个元素
return 0;
}
2)数组在内存中是连续存储的
#include <stdio.h>
//数组在内存中是连续存储的
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int len = sizeof(arr) / sizeof(arr[0]);
int i = 0;
for (i = 0; i < len; i++)
{
printf("&arr[%d] = %p\n", i, &arr[i]);//&arr[i]取出arr[i]的地址
}
return 0;
}
图解:
3.2 二维数组
1.什么是二维数组
—— 二维数组是以一个行和列组成的矩阵,二维数组可以看成两个一位数组的组合
2.二维数组的创建和初始化
1)二维数组的创建:数据类型 数组名[第一维大小][第二维大小];
#include <stdio.h>
int main()
{
//int arr[3][3];//创建二维数组
int arr[3][3] = { {1,2,3},{4,5,6},{7,8,9} };//创建二维数组并初始化
return 0;
}
2)二维数组的初始化
完全初始化:把数组中的所有值都进行初始化
不完全初始化:只进行初始化数组中部分的值,剩下的值是默认值
注:二维数组在已经初始化的情况下,只可以省略第二维,不能省略第一维
#include <stdio.h>
int main()
{
//完全初始化的两种形式
int arr1[3][3] = { 1,2,3,4,5,6,7,8,9 };//形式1:不加{}
int arr2[3][3] = { {1,2,3},{4,5,6},{7,8,9} };//形式2:加{}
//解释:{}代表第一维的长度,arr2中第一维有3个,初始化中有3个{}
//不完全初始化的两种形式
//说明,前面的1,2,3占据了第一维空间,4占据了第二维的第一个内存空间,剩下的是默认值
int arr3[3][3] = { 1,2,3,4 };//形式1
int arr4[3][3] = { {1,2,3}, {4} };//形式2
//不初始化:二维数组中全部是默认值
int arr5[3][3];//全部是默认值:0
//省略第二维
int arr6[][3] = { {1,2,3},{4,5,6},{7,8,9} };
return 0;
}
3.二维数组的使用
——二位数组也是通过下标进行访问数组中的元素
#include <stdio.h>
int main()
{
int arr[3][3];//创建数组
int i, j;
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
scanf("%d", &arr[i][j]);
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
return 0;
}
4.思考以下的问题
1)如何求二维数组的长度
2)如何求二维数组中第一维的长度
3)如何求二维数组中第二维的长度
#include <stdio.h>
int main()
{
//二维数组的长度
int arr[3][4] = { 1,2,3,4,5,6,7,8,9 };
int len1 = sizeof(arr) / sizeof(arr[0][0]);//二维数组的长度
printf("%d\n", len1);//12
//二维数组中第二维的长度
int len2 = sizeof(arr[0]) / sizeof(arr[0][0]);
printf("%d\n", len2);//4
//二维数组中第一维的长度
//int len3 = len1 / len2;//法一
int len3 = sizeof(arr) / sizeof(arr[0]);//法二
printf("%d\n", len3);//3
return 0;
}
5.二维数组在内存中的存储
——跟一维数组一样,二维数组在内存中是连续存储的
#include <stdio.h>
//二维数组在内存中的存储
int main()
{
int arr[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
int i, j;
int len1 = sizeof(arr) / sizeof(arr[0]);//第一维的大小
int len2 = sizeof(arr[0]) / sizeof(arr[0][0]);//第二维的大小
for (i = 0; i < len1; i++)
{
for (j = 0; j < len2; j++)
{
//&:取出对应值的地址
printf("arr[%d][%d] = %p\n", i, j, &arr[i][j]);
}
}
return 0;
}
图解:
3.3 数组的共同问题
1.数组越界
——假设数组有n个元素,其下标的范围是0~n-1,数组的下标是从0开始的,最后一个下标是n-1
#include <stdio.h>
//数组越界
int main()
{
int arr[5] = { 1,2,3,4,5 };
int i = 0;
//错误,数组的下标范围是0-4,而不是0-5
for (i = 0; i <= 5; i++)
{}
return 0;
}
2.数组作为数组参数
1)若是以数组名作为参数,那么则为传址调用
2)若是以数组元素作为参数,看数组元素前面是否有&符合,若是有,则为传址调用,若是没有,则为传值调用
#include <stdio.h>
void PrintNum(int x)
{
x = 11;
printf("%d\n", x);
}
void Print(int* arr, int len)
{
int i = 0;
for (i = 0; i < len; i++)
{
printf("%d ", *(arr + i));
}
printf("\n");
}
void ChangeNum(int* x)
{
*x = 11;
}
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int len = sizeof(arr) / sizeof(arr[0]);
PrintNum(arr[0]);//传值:数组元素作为实参
Print(arr, len);//传址:数组名作为实参
ChangeNum(&arr[0]);//传址:数组元素的地址作为实参
Print(arr, len);//传址:数组名作为实参
return 0;
}
3.冒泡排序
1)思想:将数列中的相邻两个值进行比较,如果顺序有误则交换这两个值的位置,然后再用这个值进行比较,一直比较到最后一个值,得到第一个数中最大/最小的值,在进行下一趟的比较
2)流程详解
3)代码详解
#include <stdio.h>
//冒泡排序
void bubble_sort(int arr[], int len)
{
int i, j;
//趟数
for (i = 0; i < len - 1; i++)
{
//一趟比较的次数
for (j = 0; j < len - i - 1; j++)
{
//比较
if (arr[j] > arr[j + 1])
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
int main()
{
int arr[10] = { 10,5,1,7,3,9,6,4,2,8 };
int len = sizeof(arr) / sizeof(arr[0]);//数组长度
bubble_sort(arr, len);
int i = 0;
for (i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
4)执行结果:
4.数组名详解
1)数组名是数组首元素的地址(两个例外)
2)sizeof(数组名)计算的是整个数组的大小,sizeof内部放数组名,数组名表示整个数组
3)&数组名:取出的是整个数组的地址
#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5 };
//sizeof(数组名)计算的是整个数组的大小
printf("%d\n", sizeof(arr));//40个字节的大小
//数组名是数组首元素的地址(两个例外)
printf("%p\n", arr);
printf("%p\n", &arr[0]);//数组首元素的地址
//& 数组名:取出的是整个数组的地址
printf("%p\n", &arr);
printf("%p\n", &arr + 1);//跳过了40个字节
return 0;
}
图解:
!!!恭喜你,突破至筑基二层!!!
注:由于CSDN中的排本不够美观,若是想要看更美观的排版,请参加有道云笔记:有道云笔记