C生万物 | 从浅入深理解指针【第二部分】(二)

简介: C生万物 | 从浅入深理解指针【第二部分】(二)

C生万物 | 从浅入深理解指针【第二部分】(一):https://developer.aliyun.com/article/1426624

4. 冒泡排序

接下来我们就学习一下这个冒泡排序,主要学习两个内容~~

  1. 学习冒泡排序
  2. 学习数组传参
  • 我们给了这样的一个降序数组,我们需要将这个数组排序,排为升序
int main() {
  int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
  //进行排序
  return 0;
}
  • 我们创建一个函数,要排的是谁呢?是arr
int main() {
  int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
  //进行排序
  int sz = sizeof(arr) / sizeof(arr[0]);
  sort(arr,sz);
  return 0;
}
  • 我们这里要讲一种排序,是冒泡排序
  • 冒泡排序的核心思想就是:两两相邻的元素进行比较。

代码如下:

void sort(int arr[], int sz) {
  //确定冒泡排序的趟数~~
  int i = 0;
  for (i = 0; i < sz - 1; i++) {
    //一趟冒泡排序
    int j = 0;
    for (j = 0; j < sz - 1 - i; j++) {
      if (arr[j] > arr[j + 1]) {
        //交换
        int tmp = arr[j];
        arr[j] = arr[j + 1];
        arr[j + 1] = tmp;
      }
    }
  }
}
void print(int arr[], int sz) {
  int i = 0;
  for (i = 0; i < sz; i++) {
    printf("%d ", arr[i]);
  }
}
int main() {
  int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
  //进行排序
  int sz = sizeof(arr) / sizeof(arr[0]);
  sort(arr,sz);
  print(arr, sz);
  return 0;
}
  • 上面的代码也可以指针的形式,还是一样的道理~~
  • 上面的代码还是有优化的空间的,假设我的数组是这样的:
int arr[] = { 9,0,1,2,3,4,5,6,7,8 };
  • 这里我们经过一趟冒泡排序后就已经排好了,但是我们上面的代码一定要进行9趟,我们不进行交换,但还是要执行,效率是比较低的
  • 如果已经排成有序的了,那后面就不用排了,那怎么做呢?
void sort(int arr[], int sz) {
  //确定冒泡排序的趟数~~
  int i = 0;
  for (i = 0; i < sz - 1; i++) {
    //一趟冒泡排序
    int j = 0;
    int flag = 1;//假设数组是有序的
    for (j = 0; j < sz - 1 - i; j++) {
      if (arr[j] > arr[j + 1]) {
        //交换
        int tmp = arr[j];
        arr[j] = arr[j + 1];
        arr[j + 1] = tmp;
        flag = 0;//不是有序
      }
    }
    if (flag = 1) {
      break;
    }
  }
}
  • 这样的写法是不是更好~~

5. 二级指针

  • 指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪里?
  • 我们来看下面的这一段代码~~
#include<stdio.h>
int main() {
  int a = 10;
  int* pa = &a;
  int** ppa = &pa;
  return 0;
}
  • a是整形变量,占用4个字节空间,a是自己的地址,&a拿到的就是a所占4个字节的第一个字节的地址
  • pa是指针变量,占用4/8个字节的空间,p也是有自己的地址,&p就拿到了p的地址,pa是一级指针
  • ppa也是指针变量,ppa是二级指针变量
  • 那么我们能不能&ppa呢?可以啊,ppa也是有自己的地址,&ppa就拿到了ppa的地址,放到一个三级指针–>int*** pppa = &ppa
  • 这些变量都是普通的变量,不要看的很厉害~~
  • 我们可以调试起来画图了解一下~~

对于二级指针的运算有:

*ppa 通过对ppa中的地址进行解引用,这样找到的是pa *ppa 其实访问的就是

int b = 20;
*ppa = &b;//等价于 pa = &b;

**ppa 先通过*ppa 找到pa ,然后对pa 进行解引用操作: *pa ,那找到的是a .

**ppa = 30;
//等价于*pa = 30;
//等价于a = 30;

6. 指针数组

  • 什么是指针数组?

我们类比一下:

  1. 整形数组:存放整形的数组 int arr[10];
  2. 字符数组:存放字符的数组 char ch[5];
  3. 指针数组:存放指针的数组

整形数组和字符数组:

指针数组的每个元素都是用来存放地址(指针)的。

如下图:

指针数组的每个元素是地址,又可以指向一块区域。

比如:

int main() {
  int a = 1;
  int b = 2;
  int c = 3;
  int d = 4;
  int e = 5;
  int* parr[5] = { &a,&b,&c,&d,&e };
  return 0;
}
  • 那我们也是可以打印出来的
int main() {
  int a = 1;
  int b = 2;
  int c = 3;
  int d = 4;
  int e = 5;
  int* parr[5] = { &a,&b,&c,&d,&e };
  int i = 0;
  for (i = 0; i < 5; i++) {
    printf("%d ", *(parr[i]));
  }
  return 0;
}

  • parr[i]找到了每个元素的地址,然后解引用,就找到了,便可以打印出来~~

7. 指针数组模拟二维数组

#include <stdio.h>
int main()
{
  int arr1[] = { 1,2,3,4,5 };
  int arr2[] = { 2,3,4,5,6 };
  int arr3[] = { 3,4,5,6,7 };
  //数组名是数组首元素的地址,类型是int*的,就可以存放在parr数组中
  int* parr[3] = { arr1, arr2, arr3 };
  int i = 0;
  int j = 0;
  for (i = 0; i < 3; i++)
  {
    for (j = 0; j < 5; j++)
    {
      printf("%d ", parr[i][j]);
    }
    printf("\n");
  }
  return 0;
}
  • parr[i]是访问parr数组的元素,parr[i]找到的数组元素指向了整型一维数组,parr[i][j]就是整型一维数组中的元素。
    上述的代码模拟出二维数组的效果,实际上并非完全是二维数组,因为每一行并非是连续的。
  • 如果不懂还可以看下图:


相关文章
C生万物 | 从浅入深理解指针【最后部分】(二)
C生万物 | 从浅入深理解指针【最后部分】(二)
|
3月前
|
存储 C++
C生万物 | 从浅入深理解指针【第三部分】(转移表的实现)
C生万物 | 从浅入深理解指针【第三部分】(转移表的实现)
|
3月前
|
编译器
C生万物 | 从浅入深理解指针【第二部分】(一)
C生万物 | 从浅入深理解指针【第二部分】 前言: 如果没有看过第一部分的话,推荐先看第一部分,然后再来看第二部分~~
|
3月前
|
C语言 C++
C生万物 | 从浅入深理解指针【最后部分】(一)
C生万物 | 从浅入深理解指针【最后部分】(一)
C生万物 | 从浅入深理解指针【第四部分】(qsort的使用和模拟实现)
C生万物 | 从浅入深理解指针【第四部分】(qsort的使用和模拟实现)
|
3月前
|
机器学习/深度学习 安全 程序员
C生万物 | 从浅入深理解指针【第一部分】(二)
C生万物 | 从浅入深理解指针【第一部分】(二)
|
2天前
|
存储 C语言
C语言 — 指针进阶篇(下)
C语言 — 指针进阶篇(下)
3 0
|
2天前
|
存储 C语言 C++
C语言 — 指针进阶篇(上)
C语言 — 指针进阶篇(上)
5 0
|
17天前
|
存储 人工智能 编译器
C语言指针详解
指针运算,指针和数组,二级指针
C语言指针详解
|
17天前
|
存储 C语言
C语言第二十四弹---指针(八)
C语言第二十四弹---指针(八)