C的实用笔记27——数组指针(指针引用二维数组的桥梁)

文章详细介绍了如何通过普通指针间接访问二维数组的元素,强调了正确赋值二维数组首地址的方法。同时,讨论了一维指针自加取星花作为访问二维数组元素的可行方式。此外,文章阐述了数组指针的概念,指出不同类型数组指针在访问内存和自加操作时的差异,并提供了通用的类型判别方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.如何通过普通指针间接访问二维数组的每个元素?合理吗?

1、第一步,如何用普通指针保存二维数组的首地址
  1. 正确的做法:将二维数组第0行第0列的元素的地址赋值给指针。背后的逻辑:&a[0][0] 、 a[0] 、 *a 三者在逻辑上是等价的,这些“指针”的类型都是int *型的
    #include <stdio.h>
    int main(int argc, char const *argv[])
    {
        int arr[3][4] = {{1,3,5,7},{9,11,13,15},{17,19,21,23}};
        int i, j;
        int *parr = &arr[0][0];			//第0行第0列的元素的地址
        return 0;
    }
    或者: int *parr = a[0];   或者   int *parr = *a

  2. 被警告的做法(也可以运行):将二维数组的名字arr赋值给指针。背后的逻辑:arr 这个“指针”的类型是 int (*)[4]类型的,与普通指针的int *类型不匹配,语句上虽然合法,但是我们要避免使用
    #include <stdio.h>
    int main(int argc, char const *argv[])
    {
        int arr[3][4] = {{1,3,5,7},{9,11,13,15},{17,19,21,23}};
        int i, j;
        int *parr = arr;
        return 0;
    }

2、一种可行的做法:回顾在一维数组中,我们可以通过指针进行间接访问数组元素,它有以下三种可行方式,但是只有一种能用在二维数组身上:

  1. 指针下标法:行不通,因为二维数组在内存中是连续存储的,用指针保存二维数组的第0行第0列的地址后,就相当于把二维数组看成一维数组,那么下标只能有一个,也就是parr[ 1 ] 是可行的,但是parr[ 1 ][ 0 ]是错的。
  2. 指针偏移后取星花:行不通,原因同上。
  3. 指针自加取星花:行得通,因为二维数组在内存中是连续存储的。
    #include <stdio.h>
    int main(int argc, char const *argv[])
    {
        int arr[3][4] = {{1,3,5,7},{9,11,13,15},{17,19,21,23}};
        int i, j;
        int *parr = &arr[0][0];
        for(i=0; i<3; i++){
            for(j=0; j<4; j++){
                printf("%d ", *parr++);		//通过一维指针自加后取星花能访问二维数组元素
            }
            putchar('\n');
        }
        return 0;
    }

3、用普通指针访问二维数组不合理:虽然说二维数组名arr是可以赋值给int *类型的指针parr,但是 parr++ 和 arr++ 的跨度不一样,没法用之前的结论:通过二维数组的父子数组名偏移的方式来间接访问二维数组的元素

2.数组指针的引入

1、数组指针的概念:数组指针本身是一个指针变量,它指向一个数组,它不是数组。如图:

 

2、数组指针的类型:指针变量有四要素,其中指针的类型十分重要。数组指针关心这个指针指向的数组中有几个元素,于是,当你定义数组指针时,中括号里面的数字不一样,代表你定义的数组指针就是不同类型的。如下:

int (*p1)[4];
int (*p2)[5];
p1 和 p2,这两个指针的类型不一样,体现在:
	1.它们能访问的内存空间不同;p1一次性能够访问4*4=16字节的内存空间;p2一次性能够访问5*4=20字节的空间
    2.它们自加后的跨度不同:   p1++后,指针p1往后移动16字节;p2++后,指针p2往后移动20字节。

3、数组指针为啥这样写?(通用的类型判别方法):

  1. 数组指针首先它得是一个指针,所以用小括号把*p括起来是为了先让修饰符*和p结合,确保p是一个指针;其次,关心的是这个指针指向的数组中有几个元素,也就是中括号里面的数字;最后,关注的是数组指针这个指针指向的数组,数组里面的元素是什么数据类型的。
    int (*p)[4];		//数组指针,指针指向的数组中有4个元素,每个元素是int类型的。
    int *p[4];			//指针数组,数组中有4个元素,每个元素是int *类型的。

  2. 适用于变量、指针、函数的类型判别方法
    1. 找到变量名,若没有变量名,找到最里面的结构
    2. 向右看,读出看到的东西,不要跳过括号
    3. 向左看,读出看到的东西,不要跳过括号
    4. 若有括号,跳出第一层括号
    5. 重复上述过程,直到读出最终的类型
### 解决PyCharm无法加载Conda虚拟环境的方法 #### 配置设置 为了使 PyCharm 能够成功识别并使用 Conda 创建的虚拟环境,需确保 Anaconda 的路径已正确添加至系统的环境变量中[^1]。这一步骤至关重要,因为只有当 Python 解释器及其关联工具被加入 PATH 后,IDE 才能顺利找到它们。 对于 Windows 用户而言,在安装 Anaconda 时,默认情况下会询问是否将它添加到系统路径里;如果当时选择了否,则现在应该手动完成此操作。具体做法是在“高级系统设置”的“环境变量”选项内编辑 `Path` 变量,追加 Anaconda 安装目录下的 Scripts 文件夹位置。 另外,建议每次新建项目前都通过命令行先激活目标 conda env: ```bash conda activate myenvname ``` 接着再启动 IDE 进入工作区,这样有助于减少兼容性方面的问题发生概率。 #### 常见错误及修复方法 ##### 错误一:未发现任何解释器 症状表现为打开 PyCharm 新建工程向导页面找不到由 Conda 构建出来的 interpreter 列表项。此时应前往 Preferences/Settings -> Project:...->Python Interpreter 下方点击齿轮图标选择 Add...按钮来指定自定义的位置。按照提示浏览定位到对应版本 python.exe 的绝对地址即可解决问题。 ##### 错误二:权限不足导致 DLL 加载失败 有时即使指定了正确的解释器路径,仍可能遇到由于缺乏适当的操作系统级许可而引发的功能缺失现象。特别是涉及到调用某些特定类型的动态链接库 (Dynamic Link Library, .dll) 时尤为明显。因此拥有管理员身份执行相关动作显得尤为重要——无论是从终端还是图形界面触发创建新 venv 流程均如此处理能够有效规避此类隐患。 ##### 错误三:网络连接异常引起依赖下载超时 部分开发者反馈过因网速慢或者其他因素造成 pip install 操作中途断开进而影响整个项目的初始化进度条卡住的情况。对此可尝试调整镜像源加速获取速度或是离线模式预先准备好所需资源包后再继续后续步骤。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值