首先,大家先需知道一个关于基类型的概念

基类型:组成一个新类型的基础类型

这句话是什么意思呢?举个例子:

int a[3] = {1,2,3};

上面是由三个int类型的数组成一个新的类型也就是数组,所以基类型是int

int a[2][2] = {{1,2},{3,4}};

上面是由两个一维数组类型组成一个二维数组,所以基类型是一维数组

有了上面两个例子,相信大家能知道基类型是啥意思。

接下来先说说一维数组和一级指针关系

首先指针说白了就是存放地址,把变量地址赋予指针

取出该变量的数值应该用*号取出指针所指变量地址里面的值,如下

如果我们想把一个数组的地址赋值给指针,如下

程序里的a表达的是数组的首地址,则我们可以得到int *p = a的关系

如果我们想输出数组第二个元素的地址呢,是不是得把指向首地址的指针移到数组第二个数的地址

指针p存储首地址,也就是指向数组的第一个元素,+1后相当于指向数组第二个元素,指针往右移动1个基类型,也就是一个int型长度,所以地址与首地址相差4个字节,因为int数据类型长度为4个字节。

我们用 * 号取后数值为1,说明正是指向数组第二个元素。

突发奇想,指针 p = a,那我可以把p改作a执行上面操作吗?

想法被确定了,在某种情况下,数组的确和指针用法一样。

接下来是二维数组和数组指针关系

数组指针:本质是个指针, 指向 数组的指针

有人可能会问,那可以指向一维数组吗,先不说,看到下面应该就能理解

可以看出,p存放二维数组首地址,如果我们想要到a[1][0]的地址呢

指针p存储首地址,上面我们已经说过二维数组由一维数组构成,基类型为一维数组,+1后相当于指向二维数组第二个元素也就是第二个一维数组,指针往右移动1个基类型,也就是一个一维数组型长度(包含两个int型),所以地址与首地址相差8个字节。

如果想要a[1][0]的数值呢

有人可能会被不知道为什么需要两个 * 号才能取出数值

这是因为我们一开始时p+1只是指针移动一个基类型,也就是移到二维数组的第二个一维数组一整个中,可是别忘记他的元素是一维数组,没有*之前我们还只是在二维数组中,我们 *{p+1}才是进入一维数组里面,然后接下来就和一级指针一样的操作,再多个*就可以把数值取出:*(*(p+1))

如果要取a[1][1]的地址和值呢

为什么在第一个 * 号后+1呢

因为当我们*(p+1)进入二维数组中第二个一维数组里面后,我们如果想取它一维数组第二个元素的int值,是不是和上面一维数组和一级指针一样,+1就可移动到第二个int,这里(*p+1)+1后面+1移动的是int的基类型,前面的+1移动的是一维数组的基类型,则取出a[1][1] 则需要(*(*p+1)+1) 。

看到这里希望大家明白为什么前面说的数组指针不能指向一维数组以及二维数组和数组指针关系

总结:一维数组和一级指针:

  int a[5];

  int *p = a;

二维数组和数组指针的关系:

 int a[2][2];

 int (*p)[2];    注意数组指针和二维数组后面的[2]必须相同。

C语言学习笔记之数组与指针的关系的更多相关文章

  1. C语言学习笔记 (007) - 数组指针和通过指针引用数组元素的方法总结

    1.数组指针:即指向数组的指针 那么, 如何声明一个数组指针呢? ]; /*括号是必须写的,不然就是指针数组:10是数组的大小*/ 拓展:有指针类型元素的数组称为指针数组. 2.通过指针引用数组元素的 ...

  2. C语言学习笔记 (004) - 数组名和数组首地址(转)

    一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址.指针变量既然可以指向变量,当然也可以指向数组和数组元素(把数据起始地址或某一元素的地址放到一个指针变量中) ...

  3. c语言学习笔记(9)——指针

    指针是c语言的灵魂 ----------------------------------------------------------------------------- # include &l ...

  4. C++ Primer 学习笔记_Chapter4 数组和指针–指针

    一.什么是指针? 指针与迭代器一样,指针提供对其所指对象的间接访问,指针保存的是另一个对象的地址: string s("hello"); string *ps = &s; ...

  5. c语言学习笔记 函数数组传递笔记

    今天学习c语言的一个小例子,果然还是陷入了php的编程习惯里,这里记录一下. #include <stdio.h> //例子很简单,就是编写一个函数把传递进来的数组里的值都赋值为1而已 / ...

  6. Go语言学习笔记(4)——数组和切片

    1 数组的特点: 长度固定.元素数据类型相同.下标从0开始 1.1 声明和初始化: var array_name [size] type         var arr1 [10] float32   ...

  7. 大一C语言学习笔记(9)---指针篇--从”内存的使用“和“流程控制”的角度来理解“指针变量的使用‘

    #深入理解指针变量 举个错误栗子: //以下代码的目的是输出100和1000,但输出结果只有一个100 #include<stdio.h> #include<malloc.h> ...

  8. 大一C语言学习笔记(7)---指针篇--什么是指针?什么是指针变量?取地址符“&”的作用是什么?地址运算符“*”的作用是什么,怎么理解两者?

    "指针是C语言的灵魂"这句话一开始我没怎么明白,现在接触了指针,终于知道为什么这么说了,因为....难,真难:下面说一下我对这句话的见解: C语言拥有着其他语言所没有的特性---直 ...

  9. 大一C语言学习笔记(8)---指针篇--动态内存是什么?与静态内存有什么区别?怎么使用动态内存,有什么需要注意的地方?

    静态内存指的是在编译时系统自动给其分配的内存,运行结束后会自动释放:静态内存是在栈中分配的: 动态内存是我们程序员手动分配的内存,正常情况下,程序运行结束后,也不会自动释放,所以为了避免发生未知的错误 ...

随机推荐

  1. scrapy 基础组件专题(五):自定义扩展

    通过scrapy提供的扩展功能, 我们可以编写一些自定义的功能, 插入到scrapy的机制中 一.编写一个简单的扩展 我们现在编写一个扩展, 统计一共获取到的item的条数我们可以新建一个extens ...

  2. 数据可视化之powerBI入门(七)数据清洗中最常使用的十三招

    https://mp.weixin.qq.com/s?__biz=MzA4MzQwMjY4MA==&mid=2484067158&idx=1&sn=4ad955112df2f4 ...

  3. 关于PowerShell调用Linq的一组实验

    Windows PowerShell 版权所有 (C) Microsoft Corporation.保留所有权利. 尝试新的跨平台 PowerShell https://aka.ms/pscore6 ...

  4. Unity3D Demo项目开发记录

    前言 经过一段时间的学习与实际开发,unity3D也勉强算是强行入门了,正所谓好记性不如烂笔头,更何况本人并非专业从事unity3D开发,会一点C#但也并不熟悉,为了避免后期遗忘,因此特意整理了一个D ...

  5. Trie——解决字符串搜索、异或最值问题

    Trie--解决字符串搜索.异或最值问题 在说到Trie之前,我们设想如下问题: 给我们1e5个由小写字母构成的不重复的字符串,每个字符串长度不超过6,之后是1e5次查询操作,每次给我们一个字符串,要 ...

  6. python常见报错信息!错误和异常!附带处理方法

    作为 Python 初学者,在刚学习 Python 编程时,经常会看到一些报错信息. Python 有两种错误很容易辨认:语法错误和异常. Python assert(断言)用于判断一个表达式,在表达 ...

  7. vscode 无法自动补全第三方库

    点击Settings 找到“Extentions”下的“Python”,点击“Auto Completes: Extra Paths”的“Edit in settings.json”,如下图: 在se ...

  8. 干货分享丨玩转物联网IoTDA服务系列五-智能家居煤气检测联动

    摘要:该场景主要描述的是设备可以通过LWM2M协议与物联网平台进行交互,用户可以在控制台或通过应用侧接口创建设备联动规则,把设备上报的属性转发,通过物联网平台规则引擎转变成命令下发给其他指定设备. 场 ...

  9. spring oauth2+JWT后端自动刷新access_token

    这段时间在学习搭建基于spring boot的spring oauth2 和jwt整合. 说实话挺折腾的.使用jwt做用户鉴权,难点在于token的刷新和注销. 当然注销的难度更大,网上的一些方案也没 ...

  10. 我自己总结的sqlite的命令行命令集

    我自己总结的sqlite 的命令行命令 导入文本数据文件时,设置分隔符为","sql>.separator "," sql>import devic ...