深度解析指针与数组:探索内存管理的艺术

简介: 深度解析指针与数组:探索内存管理的艺术



1.数组名的理解

我们发现数组名和数组首元素的地址打印出的结果一模一样,数组名就是数组首元素(第一个元素)的地址。

数组名如果是数组首元素的地址,那下面的代码怎么理解呢?

输出的结果是:40,如果arr是数组首元素的地址,那输出应该的应该是4/8才对。

其实数组名就是数组首元素(第一个元素)的地址是对的,但是有两个例外:

sizeof(数组名),sizef中单独放数组名,这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节

&数组名,这里的数组名表示整个数组,取出的是整个数组的地址 (整个数组的地址和数组首元素的地址是有区别的)

除此之外,任何地方使用数组名,数组名都表示首元素的地址。

图解:

2.使用指针访问数组

为什么访问数组的时候可以使用指针呢?

1.数组在内存中是连续存放的

2.指针+-整数运算,方便我们获得每一个元素的地址

int main()
{
  int arr[10] = { 0 };
  //使用指针来访问数组
  int sz = sizeof(arr) / sizeof(arr[0]);
  //输入10个值
  int* p = arr;
  int i = 0;
  for (i = 0; i < sz; i++)
  {
    //输入1个值
    scanf("%d", p+i);//p+i == &arr[i]
  }
  //输出10个值
  for (i = 0; i < sz; i++)
  {
    printf("%d ", i[arr]);//p[i]  arr[i]  *(arr+i)
  }
  return 0;
}

arr[i]==>*(arr+i)等价

1.数组就是数组,是一块连续的空间(数组的大小和数组元素个数和元素类型都有关系)
2.指针(变量)就是指针(变量),是!一个变量(4/8个字节)

数组与指针的联系:

3.数组名是地址,是首元素的地址
4.可是使用指针来访问数组

3.一维数组传参的本质

打印的值为1,是指针变量的大小,不是数组的大小

数组传参的时候,形参是可以写成数组的形式的
但是本质上还是指针变量
void Print(int arr[10])//int* arr
{
  int sz = sizeof(arr) / sizeof(arr[0]);//得不到元素个数的,算出来的是指针变量的大小
  int i = 0;
  for (i = 0; i < sz; i++)
  {
    printf("%d ", arr[i]);
  }
}
void Print(int* p,int sz) //应该是指针
{
  int i = 0;
  for (i = 0; i < sz; i++)
  {
    printf("%d ", *(p + i));
  }
}
int main()
{
  int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
  int sz = sizeof(arr) / sizeof(arr[0]);
  Print(arr, sz);//arr 数组名就是数组首元素的地址
  //sizeof(arr)
  //&arr
  return 0;
}

1. 数组传参的本质是传递了数组首元素的地址,所以形参访问的数组和实参的数组是同一个数组的。

2.形参的数组是不会单独再创建数组空间的,所以形参的数组是可以省略掉数组大小的。

总结:一维数组传参,形参的部分可以写成数组的形式,也可以写成指针的形式。

4 .冒泡排序

冒泡排序的核心思想:就是两两相邻的元素进行比较。

图示:

代码如下

升序
void bubble_sort(int arr[], int sz)
{
  int i = 0;
  //趟数
  for (i = 0; i < sz - 1; i++)
  {
    //假设已经有序了
    int flag = 1;
    //一趟排序的过程
    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;
        flag = 0;
      }
    }
    if (flag == 1)
    {
      break;
    }
  }
}
void print_arr(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]);
  bubble_sort(arr, sz);
  //打印
  print_arr(arr, sz);
  return 0;
}

避免已经排序结束了,但是还在循环

5.二级指针

int main()
{
  int a = 10;
  int* p = &a;//p就是一级指针
  int * * pp = &p;
  int** * ppp = &pp;
  int**** pppp = &ppp;
  //.....
  return 0;
}

解引用

6.指针数组

指针数组是数组还是指针?

是数组!

eg:好孩子,主语是孩子

我们类比一下,整型数组,是存放整型的数组,字符数组是存放字符的数组。
那指针数组呢?是存放指针的数组。

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

并不是真的二维数组,只是模拟出来的

图解:

parr[]是访问parr数组的元素,parr[i]找到的数组元素指向了整型一维数组,parr[i][j]就是整型一维数组中的素。

上述的代码模拟出二维数组的效果,实际上并非完全是二维数组,因为每一行并非是连续的。

希望对你有帮助!加油各位!!

每一次努力都是不凡的历练,每一点进步都是值得庆祝的胜利。你正在创造属于自己的辉煌,相信自己,一切皆有可能。

目录
相关文章
|
18天前
|
C语言
C语言:数组和指针笔试题解析(包括一些容易混淆的指针题目)
C语言:数组和指针笔试题解析(包括一些容易混淆的指针题目)
|
3天前
|
机器学习/深度学习 算法 Linux
xenomai内核解析--实时内存管理--xnheap
Xenomai是一个实时操作系统(RTOS)层,用于Linux,旨在提供确定性的任务调度和服务。其内存管理机制包括一个名为xnheap的内存池,确保内存分配和释放的时间确定性,以满足硬实时系统的严格需求。
11 0
xenomai内核解析--实时内存管理--xnheap
|
3天前
|
Java
解析java中的数组
解析java中的数组
10 3
|
4天前
|
缓存 Java 编译器
JMM内存模型 volatile关键字解析
JMM内存模型 volatile关键字解析
10 0
|
11天前
3.默认值不一样【重点】 局部变量:没有默认值,如果要想使用,必须手动进行赋值 成员变量:如果没有赋值,会有默认值,规则和数组一样 4.内存的位置不一样(了解) 局部变量:位于栈内存 成员变量:位于堆内存 5生命周期不一样(了解)
3.默认值不一样【重点】 局部变量:没有默认值,如果要想使用,必须手动进行赋值 成员变量:如果没有赋值,会有默认值,规则和数组一样 4.内存的位置不一样(了解) 局部变量:位于栈内存 成员变量:位于堆内存 5生命周期不一样(了解)
17 0
|
12天前
|
存储 程序员 C语言
【C 言专栏】C 语言指针的深度解析
【4月更文挑战第30天】C 语言中的指针是程序设计的关键,它如同一把钥匙,提供直接内存操作的途径。指针是存储其他变量地址的变量,通过声明如`int *ptr`来使用。它们在动态内存分配、函数参数传递及数组操作中发挥重要作用。然而,误用指针可能导致错误,如空指针引用和内存泄漏。理解指针的运算、与数组和函数的关系,以及在结构体中的应用,是成为熟练 C 语言程序员的必经之路。虽然挑战重重,但掌握指针将增强编程效率和灵活性。不断实践和学习,我们将驾驭指针,探索更广阔的编程世界。
|
13天前
|
Java Go 区块链
【Go语言专栏】Go语言中的指针与内存管理
【4月更文挑战第30天】Go语言,由Google开发,是一种静态强类型、编译型、并发型语言,具有垃圾回收功能,常用于云计算、微服务、区块链等领域。本文聚焦Go中的指针和内存管理。指针表示变量内存地址,可用于直接访问和修改变量,如示例代码所示。指针运算有限制,仅支持相同类型变量和数组元素访问。内存管理由Go运行时的垃圾回收机制处理,自动回收无引用对象,简化管理但引入性能开销。可通过`runtime.GC()`手动触发垃圾回收。
|
13天前
|
算法 安全 Linux
深度解析:Linux内核内存管理机制
【4月更文挑战第30天】 在操作系统领域,内存管理是核心功能之一,尤其对于多任务操作系统来说更是如此。本文将深入探讨Linux操作系统的内核内存管理机制,包括物理内存的分配与回收、虚拟内存的映射以及页面替换算法等关键技术。通过对这些技术的详细剖析,我们不仅能够理解操作系统如何高效地利用有限的硬件资源,还能领会到系统设计中的性能与复杂度之间的权衡。
|
13天前
|
存储 机器学习/深度学习 Java
【Java探索之旅】数组使用 初探JVM内存布局
【Java探索之旅】数组使用 初探JVM内存布局
26 0
|
18天前
|
存储 C语言
指针深入解析(C语言基础)带你走进指针,了解指针
指针深入解析(C语言基础)带你走进指针,了解指针

推荐镜像

更多