【C语言】指针篇-深入探索数组名和指针数组- 必读指南(2/5)

简介: 【C语言】指针篇-深入探索数组名和指针数组- 必读指南(2/5)

一、数组名

在数组篇章,我们得到一个结论:数组名是首元素的地址

验证环节:

#include <stdio.h>
int main()
{
    int nums[]={1,2,3};
    printf("&nums[0] = %p\n", &nums[0]);
  printf("nums = %p\n", nums);
    return 0;
}
结果:
&nums[0] = 00D6F724
 nums[0] = 00D6F724  

问题】:既然数组名是首元素的地址,那么为什么下面输出却不是预想的结果呢?

int main()
{
    int nums[10]={1,2,3};
    printf("%d\n",sizeof(nums));
    return 0;
}
输出结果:40。数组名是数组首元素的地址的话,那么输出的结果为什么不是4/8呢?

解释】:首先数组名是首元素的地址这结论是没错的,但是凡是都有特例

  • sizeof(array_name)sizeof单独放数组名,这里的数组名表示整个数组,计算的是整个数组的大小
  • & array_name这里的数组名表示整个数组,取出的是整个数组的地址(整个数组的地址和数组首元素的地址是有区别的,虽然一开始指向的地址是相同的)
#include <stdio.h>
int main()
{
int nums[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("&nums[0] = %p\n", &nums[0]);
printf("&nums[0]+1 = %p\n", &nums[0]+1);
printf("nums = %p\n", nums);
printf("nums+1 = %p\n", nums+1);
printf("&nums = %p\n", &nums);
printf("&nums+1 = %p\n", &nums+1);
return 0;
}

通过结果得到的结果:

  1. &nums[0]和(nums)&nums[0]+1 和(nums)+1相差了四个字节
  2. &nums&nums+1相差40个字节

理由】:根据上面的结论

  1. &nums[0]和(nums)都是代表首元素的地址,对此+1只跳过一个元素(数组元素)
  2. &nums都是代表整个数组的地址,对此+1只跳过一个元素(整个数组)

1.1 指针访问数组

int nums[]={1,2,3};
int *p=nums;
printf("%d",*(p+1));//p[1]=nums[1]=*(nums+1)

说明】:

本质上nums[i]等价于*(nums+i),在编译器处理时,数组通过下标访问是转换成首元素的地址+偏移量求出元素的地址,再解引用来访问的。

1.2 一维数组传参

问题:将外部函数中数组在调用函数时传参,并在内部函数求数组元素个数是否可行?

void test(int nums[])
{
    int sz=sizeof(nums)/sizeof(nums[0]);;
    printf("%d",sz);//结果为1
}
int main()
{
    int nums[]={1,2,3,4,5};
    test(nums);
    return 0;
}

结果】:在函数内部没有求出正确的数组元素个数。

理由】:因为数组名是数组首元素的地址,那么在数组传参的时候,传过去的不是一整个数组,而是数组名,也是说数组传参的本质是传递数组首元素的地址,地址的大小4/8

结论】:

  • 在求数组元素个数的操作在调用函数前完成
  • 一维数组传参,形参部分可以写成数组的形式(本质是指针),也是可以写成指针的形式
数组形式:void test(int nums[])
指针形式: void test(int *nums)

二、二级指针

问题:指针变量是存放变量的地址,是变量就是有自身的地址,那么指针变量的地址存放在哪里呢?

int *类型存放int 类型地址
int **类型存放int *类型地址 
    依次类推

二级指针:用于存放一级指针的地址,以此类推,N级存放N-1级的地址,但是太高级也是不常用或者直接不用三级以上的

分析】:

2.1 对于二级指针的运算

*pa是通过pa中的地址解引用,找到的是a( * pa通过a的地址找到a)

int a=10;
*pa = &a;//等价pa = &a

**ppa是先通过 *ppa找到pa,然后对pa进行解引用找到a:( *pa,找到a)

** ppa = 10;
//等价* pa = 10;
//等价a = 10


三、指针数组

问题】:指针数组是指针还是数组

整型数组:存放整形的数组
字符数组:存放字符的数组
.....
指针数组:存放指针的数组(每个元素的都是存放地址)(而指针又指向一块空间)
```cpp
int a, b, c=0;
int* arr[5] = {&a, &b, &c};
这里arr先跟[]结合形成数组,意味是指针数组,存放一级指针的数组

顺序问题:先对外层解引用,在到内部解引用

3.1 指针数组模拟二维数组

int main()
{
  int arr1[] = {1,2,3,4,5};
  int arr2[] = {2,3,4,5,6};
  int arr3[] = {3,4,5,6,7}; 
    //[]优先级高于* p先是个数组,所以是数组指针
    //P里面的元素都是地址(指针)
  int* parr[] = { arr1,arr2,arr3};
  for (int i = 0; i < 3; i++)
  {
    for (int j = 0; j < 3; j++)
    {
      printf("%d ", parr[i][j]);
    }
    printf("\n");
  }
  return 0;
}

说明】:parr[i]是访问parr数组的元素{arr1,arr2,arr3},而这些是指针(地址),同时指向一片空间,需要再次解引用找到某指针的某个元素。对于上面parr[i]找到的数组元素指向了整形一维数组,p[i] [j]就是整形一维数组中元素

注意:属于模拟二维数组的效果,二维数组也是连续存放数据的,而这里每一行不是连续存放,不是真正的二维数组


谢谢大家的观看,这里是个人笔记,希望对你学习C有帮助。

如果对指针篇感兴趣可以,点击该链接了解多方面学习指针开篇

相关文章
|
10月前
|
存储 人工智能 程序员
一文彻底搞明白C语言的数组
本文详细介绍了C语言中的数组,包括定义、初始化(静态与动态)、存储方式、访问方法及常用操作,如遍历、修改元素和作为函数参数传递。数组是C语言中最基本的数据结构之一,掌握它对编程至关重要。下篇将介绍二维数组,敬请期待!
515 0
一文彻底搞明白C语言的数组
|
存储 NoSQL 编译器
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
指针是一个变量,它存储另一个变量的内存地址。换句话说,指针“指向”存储在内存中的某个数据。
391 7
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
|
10月前
|
存储 人工智能 Java
一文轻松拿捏C语言的指针的基础使用
本文介绍了C语言中的指针概念,包括直接访问和间接访问内存的方式、指针变量的定义与使用、取址运算符`&`和取值运算符`*`的应用,帮助读者深入理解指针这一C语言的核心概念。君志所向,一往无前!
185 0
|
存储 编译器 C语言
【C语言】指针大小知多少 ?一场探寻C语言深处的冒险 !
在C语言中,指针的大小(即指针变量占用的内存大小)是由计算机的体系结构(例如32位还是64位)和编译器决定的。
1330 9
|
安全 程序员 C语言
【C语言】指针的爱恨纠葛:常量指针vs指向常量的指针
在C语言中,“常量指针”和“指向常量的指针”是两个重要的指针概念。它们在控制指针的行为和数据的可修改性方面发挥着关键作用。理解这两个概念有助于编写更安全、有效的代码。本文将深入探讨这两个概念,包括定义、语法、实际应用、复杂示例、最佳实践以及常见问题。
372 7
|
传感器 算法 安全
【C语言】两个数组比较详解
比较两个数组在C语言中有多种实现方法,选择合适的方法取决于具体的应用场景和性能要求。从逐元素比较到使用`memcmp`函数,再到指针优化,每种方法都有其优点和适用范围。在嵌入式系统中,考虑性能和资源限制尤为重要。通过合理选择和优化,可以有效提高程序的运行效率和可靠性。
882 6
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
359 5
|
存储 算法 程序员
C 语言指针详解 —— 内存操控的魔法棒
《C 语言指针详解》深入浅出地讲解了指针的概念、使用方法及其在内存操作中的重要作用,被誉为程序员手中的“内存操控魔法棒”。本书适合C语言初学者及希望深化理解指针机制的开发者阅读。
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
算法 C语言
C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项
本文深入讲解了C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项,通过实例演示了文件操作的基本流程,帮助读者掌握这一重要技能,提升程序开发能力。
733 3