C/C++中的二维指针问题

C/C++ 字符指针数组循环赋值问题 前言:想用字符指针数组char* strArr[10];存储多个字符串,通过while循环赋值产生的bug。 先看一段代码: main(){ char *strArr[5];//存储字符串的数组 char str[10]; int i = 0; char *p = NULL; while (i<5){//循环赋值 gets(str); p = str; strArr[i] = p; i++; 阅读详情
 

指针是可变数组的首地址。正因为是可变数组,所以一般使用指针时都是采用动态内存分配和释放的方式。一维指针形式简单,容易理解。平时应用较多。二维数组和二维指针比较复杂,并且在动态内存分配与释放方面比较复杂且难以理解。但是二维数组和二维指针是非常有用的。

     考虑以下应用:对一幅图像进行模板运算。这必然会牵涉到对图像的各象素点的操作。此时使用一维指针进行图像传递时,不可避免的会使用形如*(p+i*width+j)的方式完成对图像象素点的访问。这种方式很不直观并且编写程序时容易出错。如果使用二维指针进行图像数据的传递,则会收到很好的效果。可以采用p[i][j]的方式直接操作象素点,直观又便于维护。因此掌握二维数组和二维指针是必要的。

使用http://www.wangchao.net.cn/bbsdetail_59038.html中的示例。

定义如下3个二维数组和二维指针进行说明:

1.         int** ptr;

2.         int *ptr[M];

3.         int (*ptr)[M];

以上都是存放整数的二维数组,并且都可以通过ptr[i][j]的形式访问内容。但是它们之间有很大的差别。以下依照文中提到的方面进行分析。

l         内容
三个ptr本身都是指针,并且是二维指针,但是它们的最终内容总是整数。但中间内容,形如ptr[i]并不是整数,而是指针int *.

l         意义
1. int** ptr 表示指向(一组指向整数数据指针)的指针;
2. int *ptr[M] 是指针数组,表示指向(M个指向整数指针)的指针;
3. int (*ptr)[M]表示指向一组(指向包含M个整型数据的指针)的指针。

l         所占空间
1和3占用一个内存空间,在32位平台上为4个字节,也就是一个指针。
2是M个指针,在其定义过程中编译器即对其进行了分配,占用4*M共4M个字节。

l         用法
1. int** ptr 表示指向(一组指向整数数据指针)的指针,是一个二维指针。在其定义过程中,编译器并不对其进行内存的分配,因此必须自己管理其内存的分配与释放。典型使用如下:

int** ptr;

int i,j;

ptr = (int**)malloc((sizeof(int*))*M); 

printf("The Address of ptr:%10x\n",ptr); 

for (i=0;i<M;i++)

{

       ptr[i] = (int*)malloc(sizeof(int)*N); 

         printf("The Address of ptr[%d]:%10x\n",i,ptr[i]); 

}

//采用如上内存分配方法,意味着将ptr初始化为M*N的二维数组首地址

//可以访问ptr[0:M-1][0:N-1]的数据

//操作

for (i=0;i<M;i++)

{

         free(ptr[i]); 

}

free(ptr);

使用上述方法分配内存,最终ptr耗费的内存空间为M*sizeof(int*)+M*N*sizeof(int)

2. int *ptr[M] 
是指针数组,表示指向(M个指向整数指针)的指针。是一个二维指针。但是在定义的时候,编译器已经为ptr指向的M个指向整数的指针ptr[0:M-1]分配了内存。也就是说,定义之后即可得到ptr的地址以及用于存放ptr[0:M-1]的内存空间4MB。要使用ptr必须对ptr[i]分配内存。分配内存后,ptr地址相应内存空间填入ptr[i]指向内存地址。使用如下操作:

int* ptr[M]; 

int i,j; 

printf("The Address of ptr:%10x\n",ptr); 

for (i=0;i<M;i++)

{

         ptr[i] = (int*)malloc(sizeof(int)*M); 

         printf("The Address of ptr[%d]:%10x\n",i,ptr[i]); 

}

//采用如上内存分配方法,意味着将ptr初始化为M*N的二维数组首地址

//可以访问ptr[0:M-1][0:N-1]的数据

//操作

for (i=0;i<M;i++)

{

         free(ptr[i]); 

}

//free(ptr); //此处不释放ptr内存,是因为ptr的内存是由编译器分配的。

使用上述方法分配内存,最终ptr耗费的内存空间为M*sizeof(int*)+M*N*sizeof(int),其中M*sizeof(int*)为编译器分配,M*N*sizeof(int)为程序员自己分配。

3. int (*ptr)[M]表示指向一组(指向包含M个整型数据的指针)的指针。该定义限定了ptr[i][0:M-1],所有指针ptr[i]必须指向长度为M的数组。使用方式如下:

int (*ptr)[M]; 

int i,j; 

 

printf("The Address of ptr:%10x\n",ptr); 

ptr = (int (*)[M])malloc(sizeof(int)*M*N); //一次分配连续内存

printf("The Address of ptr:%10x\n",ptr); 

for (i=0;i<N;i++)

{

//      ptr[i] = (int [M])malloc(sizeof(int)*M); 

         printf("The Address of ptr[%d]:%10x\n",i,ptr[i]); 

}

//采用如上内存分配方法,意味着将ptr初始化为N*M的二维数组首地址

//可以访问ptr[0:N-1][0:M-1]的数据

//操作

free(ptr);

使用上述方法分配内存后,ptr所占内存空间为M*N*sizeof(int)(不考虑不同操作系统用于管理的内存)。ptr内存空间中保存的为最终内容而非ptr[i]地址。


指针 指针数组(一维/二维)遍历 指针学习,一维、二维数组、字符串数组遍历总结 阅读详情

相关推荐

新手学习Vivado XDMA (1) - 配置详细分析

PCIe 在 Vivado XDMA 中的配置分析。

qq_18553915的博客 9708

C/C++二维数组指针(指向二维数组的指针)详解

在概念上是二维的,有行和列,但在内存中所有的数组元素都是连续排列的,它们之间没有 “缝隙”。以下面的二维数组 a 为例: int a[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} }; 从概念上理解,a 的分布像一个矩阵: 0 1 2 3 4 5 6 7 8 9 10 11 但在内存中,a 的分布是一维线性的,整个数组占用一块连续的内存: C 语言中的二维数组是按行排列的,也就是先存放 a .

coder_Alger 的博客 5万+

远心F-theta镜ZEMAX设计

根据给出的F-theta镜的设计指标,对F-theta镜进行了具体的光学设计。从对F-theta镜设计思想的介绍出发,对选取的初始结构进行了优化设计,优化完成后,对所设计的F-theta镜进行了像质评价,通过点列图、场曲与畸变图、相对照度、能量集中度对所设计的F-theta镜进行了分析,最终,对F-theta镜的设计效果进行了验证。

hitliuyi17的博客 9426

[C++]C/C++:二级指针、二维数组、指针数组解析

由于数组储存物理的连续性,所以可以将二维数组拉伸看做一维数组,可以由一级指针表示,再由指针偏移逐一访问各元素:int arr3[3][5] = {01,02,03,04,05,11,12,13,14,15,21,22,23,24,25};上述二维数组可以看成是由{01,02,03,04,05},{11,12,13,14,15},{21,22,23,24,25}三个数组组成。每行(横向为行)首元素为该行数组的首地址:arr[0],arr[1],arr[2];

FL1768317420的博客 1747

sylar学习系列一

开发环境 Centos7最小系统 gcc 9.1 cmake 环境可能存在的一些问题 可能存在的问题,linux最小系统没有一些常用命令,如果我们处于外网我们可以yum安装,但却遇到以下问题 can not find a valid baseurl for repo: base/7/x86-64 可修改网络配置 vi /etc/sysconfig/network-scripts/ifcfg-ens123 # 不是每个主机都是ens123 把ONBOOT=no,改为ONBOOT=yes 重启网络

wuguinianjing的博客 1018

iTerm2+oh-my-zsh最全配置

iTerm2+oh-my-zsh最全配置安装前先看效果图一.安装[iTem2](https://iterm2.com/)二.安装[oh-my-zsh](https://ohmyz.sh/)三.安装[Powerline](https://powerline.readthedocs.io/en/latest/installation.html)四.安装 [Meslo](https://github.com/powerline/fonts) 字体库五.安装agnoster主题六.安装语法高亮七.安装代码补全插件八

xinximo的博客 2610

【C++】二维数组的行指针和列指针

在C++中,数组与指针有密切的关系。任何通过数组和下标实现的表达式可等价地通过指针和偏移量实现。下面首先介绍一维数组与指针的关系,之后介绍二维数组的行指针和列指针。

zzy979481894的博客 1万+

Microapp 接入vite子应用

MicroApp接入vite版本,干货满满,手把手步骤说明,加上报错说明,赶紧上车!

outsider76557的博客 4659

c++二维数组指针

1.定义指针指向二维数组 为了方便根据用户输入动态定义二维数组的行和列,引入变量rowsNum(行),colsNum(列)。 以定义5行4列的二维数组为例, int rowsNum = 4; int colsNum = 5; float** a = new float*[rowsNum]; for(int i = 0; i < rowsNum; i++) { a[i] = n

北望花村 2万+

机器人系统能用MQTT5.0代替ROS2吗?

更为灵活和友好的方案是通过把ROS(Robot Operating System)与MQTT(Message Queuing Telemetry Transport)协议相结合的解决方案,利用MQTT的轻量级、跨平台和广泛适用性特点,扩展ROS系统的通信能力,或将非ROS系统接入ROS网络。

QzmAIoT 2163

Ubuntu下为RK3568开发板搭建Qt交叉编译环境:手把手教你配置Qt Creator和远程调试

本文详细介绍了在Ubuntu系统下为RK3568开发板搭建Qt交叉编译环境的完整流程,包括工具链配置、Qt源码交叉编译、Qt Creator环境设置以及远程调试技巧。通过手把手教程,开发者可以快速掌握RK3568平台的Qt开发环境搭建方法,实现高效的应用开发和部署。

weixin_30776273的博客 374

C++指针:(包括二维数组、二级指针、动态二维数组内存连续)

C++指针:(包括二维数组、二级指针、动态二维数组内存连续) 在C++数组的创建及使用中,简单介绍了数组中指针的使用,但是还有一些其他问题,这里主要展开一些关于二维数组指针、二级指针以及实现动态二维数组的内存连续。 1、任何指针变量被创建时不会自动成为NULL指针,它的默认值是随机的,它会乱指一气。因此如果在短期不用的话,就先把指针赋值为NULL,例如:int * p = null; 2、以内存需求的角度来看,不同类型的指针没有什么不同,其所占空间与操作系统有关(32位操作系统指针占用4字节,64位系统指针

weixin_43294620的博客 3110

基于STM32、HAL库的RN8209D电能计量芯片驱动程序设计

/ 假设电压互感器变比为220V:0.5V,电流互感器变比为20A:5mA。// 电压ADC原始值。// 电流ADC原始值。// 有功功率(W)// 电能(kWh)

corlin6688的博客 470

C/C++ 二维指针数组与修改指针所指对象的函数传递问题

1、二维指针数组函数传递问题 1、二维数组的函数传递问题 在考虑这个问题前,我们首先要了解数组a[2]的a的含义,其实a可以看作一个指向数组元素类型并指向数组内第1个元素的指针。 当我们要将二维数组作为函数参数时,可以参照一维数组的方法,一维数组sd[2]作为参数时,是将指向第1个元素的地址传递进去并给出元素个数,假设函数原型为 fun1(int *p_num),则调用时为func1(sd,2)。...

风拂寒雪_我的博客 883

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

C/C++函数返回二维数组指针问题

方法1:需要对指针有较好的理解 int(*f())[2] { int (*m)[2]=new int[2][2]; m[0][0]=1;m[0][1]=0; m[1][0]=2;m[1][1]=0; return m; } //总感觉这种函数定义很怪,可以使用typedef重定义下类型,如下: typedef int(*Matrix)[2]; Matrix f() {

blueangle17的专栏 5657

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

C/C++中的二维指针问题--转载

转载:http://blog.youkuaiyun.com/deadknightliu/archive/2009/06/03/4238717.aspx原作者:DeadKnightLiu感谢原作者!指针是可变数组的首地址。正因为是可变数组,所以一般使用指针时都是采用动态内存分配和释放的方式。一维指针形式简单,容易理解。平时应用较多。二维数组和二维指针比较复杂,并且在动态内存分配与释放方面比较复杂且难以理解。但是

cuihao0532的博客 375

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

知识分享:C/C++函数返回二维数组指针

C/C++从函数返回指针是常规操作,本文针对返回二维数组指针做了一些研究,并给出二维数组指针返回double**类型指针的结论。 常规C/C++函数返回二维数组指针 (1)返回值返回二维数组指针 首先看通过返回值返回二维指针的简单情况: 上述代码中,数据内存从堆(heap)分配,因此函数结束后分配的存储空间依然可用。调用方式: (2)传参返回二维数组指针 一些情况下,我们希望传入一个指针,其在函数内完成内存分配。这个要求稍微复杂点,其代码为: 因为要改变二维指针的指向,传参方.

致力于C语言C++知识分享! 2277

指针数组和二维数组指针的区别

int *(p1[5]); //指针数组,可以去掉括号直接写作int *p1[5]; int (*p2)[5]; // 二维数组指针,不能去掉括号。 /**p1:指针数组是一个数组,只是每个元素保存的都是指针。 * p2 是个指针,频指向一个一维的数组,这个一维数组包含5个元素。 */ 一道面试题引发的问题,首先要知道[]的优先级高于*,题目: char **p,...

dianzi1117的博客 255

C/C++中通过指针参数返回多个值

文章目录 C\C++中可以通过传递指针的方式来达到返回多个参数的效果,对于数组也可以用参数指针修改指向,而初学者容易犯的错误就是直接传递参数,最近我也犯了这个错误,下面通过一个例子解释数组指针的修改 #include <iostream> using namespace std; void sendAndChangeArray(int **addrOfArr) { int ar...

qq_46627454的博客 2395

c语言二维指针做参数,[讨论]二维指针和数组做参数的问题

[讨论]二维指针和数组做参数的问题double sum(double **sum){double result=0.0;int k,l;for(k=0;kfor(l=0;l{result+=sum[k][l]>0?sum[k][l]:(-sum[k][l]);}return result;}double subsum(double **sub1,double **sub2){double s...

weixin_28756005的博客 273

C/C++二维数组名和二级指针

转载自http://blog.youkuaiyun.com/wu_nan_nan/article/details/51741030 C/C++二维数组名和二级指针 原创 2016年06月23日 11:53:...

从小跑开始 353

c指针与数组,传参问题,指针数组与数组指针的区别,二维数组动态内存分配...

一 数组的结构:顺序存储,看谭浩强中的图,牢记 1、数组名指代一种数据结构:数组  现在可以解释为什么第1个程序第6行的输出为10的问题,根据结论1,数组名str的内涵为一种数据结构,即一个长度为10的char型数组,所以sizeof(str)的结果为这个数据结构占据的内存大小:10字节。  再看: 1. int intArray[10]; 2. cout << s...

159

c/c++ 一维数组、二维数组作为函数参数、返回值

c/c++ 一维数组、二维数组作为函数参数、返回值 一、一维数组作为参数 传入数组 int [] 为了规范,常常需要将数组的size一同传入,这是因为C++/C遇到参数为数组时,不会去一个个拷贝数组内的元素(太过于耗时),此时数组在函数内退化为数组首地址。 使用sizeof(array)/sizeof(array[0])得到1,可以验证我们前面的说法。 一般情况下,函数内经常需要使用数组的size,此时就需要我们将size传入函数。 int sum(int array[], int size) #inclu

qq_41854911的博客 8981

c语言双指针,深入理解双指针的两种用法

好久没有用过C/C++的二级指针了,总觉的它就是指针的指针,没什么大不了的,但是今天看到一道面试题,感觉自己对二级指针的理解还是不够深刻。于是,从网上找资料,学习了一番……题目是这样的:#include "stdafx.h"#include using namespace std;void GetMemory(char *p, int num){p = (char *)malloc(sizeof(...

weixin_30393279的博客 1243

【面试题003】c数组做为参数退化的问题,二维数组中的查找

【面试题003】c数组做为参数退化的问题,二维数组中的查找 一,c数组做为参数退化的问题 1.c/c++没有记录数组的大小,因此用指针访问数组中的元素的时候,我们要确保没有超过数组的边界, 通过下面的程序了解数组与指针的区别。 array.c: 12345678910111213141516171819202122232425262728 ...

A201241302241的博客 213
上一篇: 详谈 空指针NULL、野指针、通用指针(1)
下一篇: delete指针之后应该赋值NULL
雪岢奇
博客等级 码龄17年 310粉丝 60原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值