- int main()
- {
- // 待排序数组
- int nums[5] = {3, 1, 2, 0, 3};
- // 用于排序数组
- int newNums[4] = {0};
- // 计算待排序数组长度
- int len = sizeof(nums) / sizeof(nums[0]);
- // 遍历待排序数组
- for(int i = 0; i < len; i++){
- // 取出待排序数组当前值
- int index = nums[i];
- // 将待排序数组当前值作为排序数组索引
- // 将用于排序数组对应索引原有值+1
- newNums[index] = newNums[index] +1;
- }
-
- // 计算待排序数组长度
- int len2 = sizeof(newNums) / sizeof(newNums[0]);
- // 输出排序数组索引, 就是排序之后结果
- for(int i = 0; i < len2; i++){
- for(int j = 0; j < newNums[i]; j++){
- printf("%i\n", i);
- }
- }
- /*
- // 计算待排序数组长度
- int len2 = sizeof(newNums) / sizeof(newNums[0]);
- // 还原排序结果到待排序数组
- for(int i = 0; i < len2; i++){
- int index = 0;
- for(int i = 0; i < len; i++){
- for(int j = 0; j < newNums[i]; j++){
- nums[index++] = i;
- }
- }
- }
- */
- return 0;
- }
-
选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到排序序列末尾。以此类推,直到所有元素均排序完毕。
- // 选择排序
- void selectSort(int numbers[], int length) { // 外循环为什么要-1?
- // 最后一位不用比较, 也没有下一位和它比较, 否则会出现错误访问
- for (int i = 0; i < length; i++) {
- for (int j = i; j < length - 1; j++) { // 1.用当前元素和后续所有元素比较
- if (numbers[i] < numbers[j + 1]) { // 2.一旦发现小于就交换位置
- swapEle(numbers, i, j + 1);
- }
- }
- }
- }
-
- // 交换两个元素的值, i/j需要交换的索引
- void swapEle(int array[], int i, int j) {
- int temp = array[i];
- array[i] = array[j];
- array[j] = temp;
- }
-
- // 冒泡排序
- void bubbleSort(int numbers[], int length) {
- for (int i = 0; i < length; i++) {
- // -1防止`角标越界`: 访问到了不属于自己的索引
- for (int j = 0; j < length - i - 1; j++) {
- // 1.用当前元素和相邻元素比较
- if (numbers[j] < numbers[j + 1]) {
- // 2.一旦发现小于就交换位置
- swapEle(numbers, j, j + 1);
- }
- }
- }
- }
- // 交换两个元素的值, i/j需要交换的索引
- void swapEle(int array[], int i, int j) {
- int temp = array[i];
- array[i] = array[j];
- array[j] = temp;
- }
-
- int main()
- {
- // 待排序数组
- int nums[5] = {3, 1, 2, 0, 3};
- // 0.计算待排序数组长度
- int len = sizeof(nums) / sizeof(nums[0]);
-
- // 1.从第一个元素开始依次取出所有用于比较元素
- for (int i = 1; i < len; i++)
- {
- // 2.取出用于比较元素
- int temp = nums[i];
- int j = i;
- while(j > 0){
- // 3.判断元素是否小于前一个元素
- if(temp < nums[j - 1]){
- // 4.让前一个元素向后移动一位
- nums[j] = nums[j - 1];
- }else{
- break;
- }
- j--;
- }
- // 5.将元素插入到空出来的位置
- nums[j] = temp;
- }
- }
-
- int main()
- {
- // 待排序数组
- int nums[5] = {3, 1, 2, 0, 3};
- // 0.计算待排序数组长度
- int len = sizeof(nums) / sizeof(nums[0]);
-
- // 1.从第一个元素开始依次取出所有用于比较元素
- for (int i = 1; i < len; i++)
- {
- // 2.遍历取出前面元素进行比较
- for(int j = i; j > 0; j--)
- {
- // 3.如果前面一个元素大于当前元素,就交换位置
- if(nums[j-1] > nums[j]){
- int temp = nums[j];
- nums[j] = nums[j - 1];
- nums[j - 1] = temp;
- }else{
- break;
- }
- }
- }
- }
-
- int main(){ // 待排序数组
- int nums[5] = {3, 1, 2, 0, 3}; // 0.计算待排序数组长度
- int len = sizeof(nums) / sizeof(nums[0]);// 2.计算步长
- int gap = len / 2;
- do{ // 1.从第一个元素开始依次取出所有用于比较元素
- for (int i = gap; i < len; i++)
- { // 2.遍历取出前面元素进行比较
- int j = i;
- while((j - gap) >= 0)
- {
- printf("%i > %i\n", nums[j - gap], nums[j]); // 3.如果前面一个元素大于当前元素,就交换位置
- if(nums[j - gap] > nums[j]){
- int temp = nums[j];
- nums[j] = nums[j - gap];
- nums[j - gap] = temp;
- }else{
- break;
- }
- j--;
- }
- } // 每个小数组排序完成, 重新计算步长
- gap = gap / 2;
- }
- while(gap >= 1);
- }
江哥提示: 对于初学者而言, 排序算法一次不易于学习太多, 咋们先来5个玩一玩, 后续继续讲解其它5个 公众号代码情缘欢迎关注
- int findKey(int values[], int length, int key) {
- // 定义一个变量记录最小索引
- int min = 0;
- // 定义一个变量记录最大索引
- int max = length - 1;
- // 定义一个变量记录中间索引
- int mid = (min + max) * 0.5;
-
- while (min <= max) {
- // 如果mid对应的值 大于 key, 那么max要变小
- if (values[mid] > key) {
- max = mid - 1;
- // 如果mid对应的值 小于 key, 那么min要变
- }else if (values[mid] < key) {
- min = mid + 1;
- }else {
- return mid;
- }
- // 修改完min/max之后, 重新计算mid的值
- mid = (min + max) * 0.5;
- }
- return -1;
- }
-
- #include <stdio.h>
- void toBinary(int num)
- {
- total(num, 1, 1);
- }
- void toOct(int num)
- {
- total(num, 7, 3);
- }
- void toHex(int num)
- {
- total(num, 15, 4);
- }
-
- void total(int num , int base, int offset)
- {
- // 1.定义表用于查询结果
- char cs[] = {
- '0', '1', '2', '3', '4', '5',
- '6', '7', '8', '9', 'a', 'b',
- 'c', 'd', 'e', 'f'
- };
- // 2.定义保存结果的数组
- char rs[32];
- // 计算最大的角标位置
- int length = sizeof(rs)/sizeof(char);
- int pos = length;//8
-
- while (num != 0) {
- int index = num & base;
- rs[--pos] = cs[index];
- num = num >> offset;
- }
-
- for (int i = pos; i < length; i++) {
- printf("%c", rs[i]);
- }
- printf("\n");
- }
- int main()
- {
- toBinary(9);
- return 0;
- }
-
- int a[2][3]={ {80,75,92}, {61,65,71}};
-
- int a[2][3];
- a[0][0] = 80;
- a[0][1] = 75;
- a[0][2] = 92;
- a[1][0] = 61;
- a[1][1] = 65;
- a[1][2] = 71;
-
- int a[2][3]={ {80,75,92}, {61,65,71}};
-
- int a[2][3]={ 80,75,92,61,65,71};
-
- int a[][3]={{1,2,3},{4,5,6}};int a[][3]={1,2,3,4,5,6};
-
- int a[][3]={{1},{4,5}};int a[][3]={1,2,3,4};
-
- 注意: 有些人可能想不明白,为什么可以省略行数,但不可以省略列数。也有人可能会问,可不可以只指定行数,但是省略列数?其实这个问题很简单,如果我们这样写:int a[2][] = {1, 2, 3, 4, 5, 6}; // 错误写法 大家都知道,二维数组会先存放第1行的元素,由于不确定列数,也就是不确定第1行要存放多少个元素,所以这里会产生很多种情况,可能1、2是属于第1行的,也可能1、2、3、4是第一行的,甚至1、2、3、4、5、6全部都是属于第1行的
- int a[2][3]={[1][2]=10};int a[2][3]={[1]={1,2,3}}
-
- char cs[2][3] = {
- {'a', 'b', 'c'},
- {'d', 'e', 'f'}
- };
- printf("%c", cs[0][0]);// 第一个[0]取出一维数组, 第二个[0]取出一维数组中对应的元素
-
- char cs[2][3] = {
- {'a', 'b', 'c'},
- {'d', 'e', 'f'}
- };
- for (int i = 0; i < 2; i++) { // 外循环取出一维数组
- // i
- for (int j = 0; j < 3; j++) {// 内循环取出一维数组的每个元素
- printf("%c", cs[i][j]);
- }
- printf("\n");
- }
-
注意: 必须强调的是,a[0],a[1],a[2]不能当作下标变量使用,它们是数组名,不是一个单纯的下标变量
- #include <stdio.h>
- int main()
- {
- char cs[2][3] = {
- {'a', 'b', 'c'},
- {'d', 'e', 'f'}
- };
- // cs == &cs == &cs[0] == &cs[0][0]
- printf("cs = %p\n", cs); // 0060FEAA
- printf("&cs = %p\n", &cs); // 0060FEAA
- printf("&cs[0] = %p\n", &cs[0]); // 0060FEAA
- printf("&cs[0][0] = %p\n", &cs[0][0]); // 0060FEAA
- return 0;
- }
-
- #include <stdio.h>
-
- // 和一位数组一样, 只看形参是基本类型还是数组类型
- // 如果是基本类型在函数中修改形参不会影响实参
- void change(char ch){
- ch = 'n';
- }
- int main()
- {
- char cs[2][3] = {
- {'a', 'b', 'c'},
- {'d', 'e', 'f'}
- };
- printf("cs[0][0] = %c\n", cs[0][0]); // a
- change(cs[0][0]);
- printf("cs[0][0] = %c\n", cs[0][0]); // a
- return 0;
- }
-
- #include <stdio.h>
-
- // 和一位数组一样, 只看形参是基本类型还是数组类型
- // 如果是数组类型在函数中修改形参会影响实参
- void change(char ch[]){
- ch[0] = 'n';
- }
- int main()
- {
- char cs[2][3] = {
- {'a', 'b', 'c'},
- {'d', 'e', 'f'}
- };
- printf("cs[0][0] = %c\n", cs[0][0]); // a
- change(cs[0]);
- printf("cs[0][0] = %c\n", cs[0][0]); // n
- return 0;
- }
-
- #include <stdio.h>
-
- // 和一位数组一样, 只看形参是基本类型还是数组类型
- // 如果是数组类型在函数中修改形参会影响实参
- void change(char ch[][3]){
- ch[0][0] = 'n';
- }
- int main()
- {
- char cs[2][3] = {
- {'a', 'b', 'c'},
- {'d', 'e', 'f'}
- };
- printf("cs[0][0] = %c\n", cs[0][0]); // a
- change(cs);
- printf("cs[0][0] = %c\n", cs[0][0]); // n
- return 0;
- }
-
- void test(char cs[2][]) // 错误写法
- {
- printf("我被执行了\n");
- }
-
- void test(char cs[2][3]) // 正确写法
- {
- printf("我被执行了\n");
- }
-
- void test(char cs[][3]) // 正确写法
- {
- printf("我被执行了\n");
- }
-
- void test(char cs[2][3])
- {
- int row = sizeof(cs); // 输出4或8
- printf("row = %zu\n", row);
- }
-
- void test(char cs[2][3])
- {
- size_t col = sizeof(cs[0]); // 输出3
- printf("col = %zd\n", col);
- }
-
- ######
- #O #
- # ## #
- # # #
- ## #
- ######
-
- char name[9] = "lnj"; //在内存中以“\0”结束, \0ASCII码值是0
- char name1[9] = {'l','n','j','\0'};
- char name2[9] = {'l','n','j',0};
- // 当数组元素个数大于存储字符内容时, 未被初始化的部分默认值是0, 所以下面也可以看做是一个字符串
- char name3[9] = {'l','n','j'};
-
- //省略元素个数时, 不能省略末尾的\n
- // 不正确地写法,结尾没有\0 ,只是普通的字符数组
- char name4[] = {'l','n','j'};
-
- // "中间不能包含\0", 因为\0是字符串的结束标志
- // \0的作用:字符串结束的标志
- char name[] = "c\0ool";
- printf("name = %s\n",name);
- 输出结果: c
-
- char chs[] = "lnj";
- printf("%s\n", chs);
-
- char name[] = {'c', 'o', 'o', 'l' , '\0'};
- char name2[] = {'l', 'n', 'j'};
- printf("name2 = %s\n", name2); // 输出结果: lnjcool
-
- char ch[10];
- scanf("%s",ch);
-
- char ch[] = "lnj";
- puts(ch); //输出结果: lnj
-
- puts函数完全可以由printf函数取代。当需要按一定格式输出时,通常使用printf函数
- char ch[30];
- gets(ch); // 输入:lnj
- puts(ch); // 输出:lnj
-
- 可以看出当输入的字符串中含有空格时,输出仍为全部字符串。说明gets函数并不以空格作为字符串输入结束的标志,而只以回车作为输入结束。这是与scanf函数不同的。
- 注意gets很容易导致数组下标越界,是一个不安全的字符串操作函数
- char name[] = "it666";
- int size = sizeof(name);// 包含\0
- printf("size = %d\n", size); //输出结果:6
-
- char name[] = "it666";
- size_t len = strlen(name2);
- printf("len = %lu\n", len); //输出结果:5
-
- /**
- * 自定义方法计算字符串的长度
- * @param name 需要计算的字符串
- * @return 不包含\0的长度
- */
- int myStrlen2(char str[])
- {
- // 1.定义变量保存字符串的长度
- int length = 0;
- while (str[length] != '\0')
- {
- length++;//1 2 3 4
- }
- return length;
- }
- /**
- * 自定义方法计算字符串的长度
- * @param name 需要计算的字符串
- * @param count 字符串的总长度
- * @return 不包含\0的长度
- */
- int myStrlen(char str[], int count)
- {
- // 1.定义变量保存字符串的长度
- int length = 0;
- // 2.通过遍历取出字符串中的所有字符逐个比较
- for (int i = 0; i < count; i++) {
- // 3.判断是否是字符串结尾
- if (str[i] == '\0') {
- return length;
- }
- length++;
- }
- return length;
- }
-
- char oldStr[100] = "welcome to";
- char newStr[20] = " lnj";
- strcat(oldStr, newStr);
- puts(oldStr); //输出: welcome to lnj"
-
- 本程序把初始化赋值的字符数组与动态赋值的字符串连接起来。要注意的是,字符数组1应定义足 够的长度,否则不能全部装入被连接的字符串。
- char oldStr[100] = "welcome to";
- char newStr[50] = " lnj";
- strcpy(oldStr, newStr);
- puts(oldStr); // 输出结果: lnj // 原有数据会被覆盖
-
- 本函数要求字符数组1应有足够的长度,否则不能全部装入所拷贝的字符串。
- char oldStr[100] = "0";
- char newStr[50] = "1";
- printf("%d", strcmp(oldStr, newStr)); //输出结果:-1
- char oldStr[100] = "1";
- char newStr[50] = "1";
- printf("%d", strcmp(oldStr, newStr)); //输出结果:0
- char oldStr[100] = "1";
- char newStr[50] = "0";
- printf("%d", strcmp(oldStr, newStr)); //输出结果:1
-
- char names[2][10] = { {'l','n','j','\0'}, {'l','y','h','\0'} };
- char names2[2][10] = { {"lnj"}, {"lyh"} };
- char names3[2][10] = { "lnj", "lyh" };
-
- int num = 6; // 占用4个字节
- //那么变量num的地址为: 0ff06
-
- char c = 'a'; // 占用1个字节
- //那么变量c的地址为:0ff05
-
- int age;// 定义一个普通变量
- num = 10;
- int *pnAge; // 定义一个指针变量
- pnAge = &age;
-
- char ch = 'a';
- char *p; // 一个用于指向字符型变量的指针
- p = &ch;
- int num = 666;
- int *q; // 一个用于指向整型变量的指针
- q = #
-
- 其中,*表示这是一个指针变量
- 变量名即为定义的指针变量名
- 类型说明符表示本指针变量所指向的变量的数据类型
- int a = 5;
- int *p = &a;
-
- int a = 5;
- int *p;
- p=&a;
-
- int *p=NULL;
- int *q=0;
-
- int *p;
- p = 250; // 错误写法
-
- int *p;
- *p=&a; //错误写法
-
- int a = 5;
- int *p = &a;
- int b = 10;
- p = &b; // 修改指针指向
-