热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

c语言指针向量表位置,C语言中二维数组指针的简要说明

C语言中,指针是一个复杂但又灵活多变的知识点,我们知道,在一维数组中,对于一个数组a[],*a,

C语言中,指针是一个复杂但又灵活多变的知识点,我们知道,在一维数组中,对于一个数组a[],*a,a,&a,都表示a的首地址,但如果与二维数组混合使用,就显得更为复杂了。例如对于一个二维数组

a[2][4]={{1,2.3},{4,5,6}}

a+i,&a[i],*(a+i),a[i],

这四个表达式到底表示什么呢?

先告诉答案吧,其实这几个表达式都是指向同一个地址的,也许你会很诧异,也会很疑惑,怎么会是这样呢!!事实证明就是这样的,

01c68526ad0550c0e9f25a5301f84e45.png

C语言中,指针是一个复杂但又灵活多变的知识点,我们知道,在一维数组中,对于一个数组a[],*a,a,&a,都表示a的首地址,但如果与二维数组混合使用,就显得更为复杂了。例如对于一个二维数组

a[2][4]={{1,2.3},{4,5,6}}

a+i,&a[i],*(a+i),a[i],

这四个表达式到底表示什么呢?

先告诉答案吧,其实这几个表达式都是指向同一个地址的,也许你会很诧异,也会很疑惑,怎么会是这样呢!!事实证明就是这样的。

来看一道题目:

char **p,a[6][8]; 问p=a是否会导致程序在以后出现问题?为什么?

直接用程序说明:

#include

void main()

{

char **p,a[6][8];

p = a;

printf("\n");

}

编译,然后就会发现通不过,报错:错误 1 error C2440: “=”: 无法从“char [6][8]”转换为“char **”

于是乎,我看了下《C专家编程》里10.5节—使用指针向函数传递一个多维数组。

方法一,函数是 void fun(int arr[2][3]); 这种方法只能处理2行3列的int型数组。

方法二,可以省略第一维的长度。函数是 void fun(int arr[][3]);这种方式虽然限制宽松了一些,但是还是只能处理每行是3个整数长度的数组。

或者写成这种形式 void fun(int (*arr)[3]);这是一个数组指针或者叫行指针,arr和*先结合使得arr成为一个指针,这个指针指向具有3个

int类型数据的数组。

方法三,创建一个一维数组,数组中的元素是指向其他东西的指针,也即二级指针。函数是 int fun(int **arr);这种方法可以动态处理各行各列不一样长度的数据。

注意:只有把二维数组改成一个指向向量的指针数组的前提下才可以这么做!比如下面的程序可以正常输出abc:

#include

using namespace std;

void test(char **ptr)

{

cout <<*ptr <

}

int main()

{

char *p[3] &#61; {"abc", "def", "ghi"};

test(p);

return 0;

}

在《C专家编程》10.3节的小启发里讲的很透彻&#xff1a;(以下这段文字及对比一定要认真分析&#xff01;)

数组和指针参数是如何被编译器修改的&#xff1f;

“数组名被改写成一个指针参数”规则并不是递归定义的。数组的数组会被改写成“数组的指针”&#xff0c;而不是“指针的指针”&#xff1a;

be88eb525c6578476cd10f6ca70e7acd.png

下面再看一个网友的一段分析相当给力的代码&#xff1a;

#include "stdafx.h"

#include

using namespace std;

int _tmain(int argc, _TCHAR* argv[])

{

int arr1[3];

int arr2[3];

int arr3[3];

int * ptr;

// ptr1是一个指向 int [3] 的指针&#xff0c;即ptr的类型和&arr1的类型是一样的&#xff0c;注意&#xff1a;arr1指向的内存区域定长

int ptr1[3][3]&#61;{{1,2,3},{1,2,3},{1,2,3}};

// ptr2是一个指向 int * 的指针&#xff0c;即ptr2的类型和&ptr是一样的&#xff0c;注意&#xff1a;ptr指向的内存区域不定长

int * ptr2[3]&#61;{arr1,arr2,arr3};

// ptr3是一个指向 int [3] 的指针&#xff0c;即ptr3的类型和&arr1的类型是一样的&#xff0c;注意&#xff1a;arr1指向的内存区域定长

int(* ptr3)[3]&#61;&arr1;

ptr3&#61;ptr1; // 没错&#xff0c;他们的类型相同

// ptr3&#61;ptr2;//error 无法从“int *[3]”转换为“int (*)[3]

// ptr4是一个指向 int * 的指针&#xff0c;即ptr4的类型和&ptr是一样的&#xff0c;注意&#xff1a;ptr指向的内存区域不定长

int ** ptr4;

//ptr4&#61;&arr1; //error 无法从“int (*)[3]”转换为“int **

ptr4&#61;ptr2; // 没错&#xff0c;他们的类型相同

//ptr4&#61;ptr3; // error 无法从“int (*)[3]”转换为“int **

return 0;

}



推荐阅读
  • C语言判断正整数能否被整除的程序
    本文介绍了使用C语言编写的判断正整数能否被整除的程序,包括输入一个三位正整数,判断是否能被3整除且至少包含数字3的方法。同时还介绍了使用qsort函数进行快速排序的算法。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文介绍了基于c语言的mcs51单片机定时器计数器的应用教程,包括定时器的设置和计数方法,以及中断函数的使用。同时介绍了定时器应用的举例,包括定时器中断函数的编写和频率值的计算方法。主函数中设置了T0模式和T1计数的初值,并开启了T0和T1的中断,最后启动了CPU中断。 ... [详细]
  • c语言\n不换行,c语言printf不换行
    本文目录一览:1、C语言不换行输入2、c语言的 ... [详细]
  • 本文介绍了C函数ispunct()的用法及示例代码。ispunct()函数用于检查传递的字符是否是标点符号,如果是标点符号则返回非零值,否则返回零。示例代码演示了如何使用ispunct()函数来判断字符是否为标点符号。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 本文介绍了在Windows系统上使用C语言命令行参数启动程序并传递参数的方法,包括接收参数程序的代码和bat文件的编写方法,同时给出了程序运行的结果。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
author-avatar
kkq--_771
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有