指针与二维数组

二维数组的本质:

int matrix[3][4];

int matrix[3][4];  ==> int [4] matrix[3];     令type为int[4];  type int[3]; 说明matrix是一个数组,有3个元素;每一个元素是int [4]类型的;

实质上int[4]就是一个拥有4个int元素的一维数组。

事实上,二维数组名称的本质是:二维数组的首地址常量(指针常量);

指针加1移动的是该指针的指类长度。

例:double *p;

p+1  就是移动8字节的长度。

matrix +1 移动了32B,&matrix[3][4]  + 1移动了8B,(matrix的指类是 double[4],&matrix[3][4]的指类是double);

c编译器不会对指针指类进行严格检查

scanf("%lf" , matrix);

scanf("%lf" ,*matrix); //两个同样是给二维数组第一个元素从键盘赋值。gcc运行&matrix[3][4]时出现警告,而*matrix不会,他们两的类型是完全相同的。。

&matrix[i][0] => &*(matrix[i] + 0) =>matrix[i];

matrix[i]就是二维数组第i行首地址。

二维数组名称,引用二维数组元素的过程:

matrix[i][j] <=> (*(matrix + i))[j]

*(mareix + i) 中:

matrix + i将移动i * sizeof(double[4])字节空间,即,跳跃i行元素!!!!

然后,*降其阶,是*(matrix)的指类成为double,即,matrix[i]是指针,是下标为i的那一行的首地址,只是,其指类已经变成double!

(matrix[i])[j] <=> *((matrix[i] + j)

matrix[i] + j事实上移动了 j +sizeof (double)个字节,即,在行内移动了J个double元素空间!

*(matrix [i] +j),对其指向的空间引用,实际上引用的就是matrix[i][j]!

关于&matrix

因为matrix的类型是double (*)[4],因此,&matrix的指类就是double (*)[4],那么,&matrix + 1应该移动48字节。

代码检验如下;

#include <stdio.h>

int main() {
    int num;
    double array[10];
    double *p;
    double matrix[3][4];
    // double[4] arr[3], *q = arr;    // 这种写法C编译器可能不接受!
    
    printf("%p\n", &num);
    p = &array[0];    // <=> p = &(*(array + 0));    <=> p = &*array;
    // <=> p = array;
    printf("p=%p array=%p &array[0]=%p\n", p, array, &array[0]);
    // 证明array就是指针,且指类与p是相同的:
    printf("p+1=%p array+1=%p\n", p+1, array+1);
    // 指针+1将移动该指针的“指类”长度;因为p的指类是double,
    // 因此,p+1应该移动8B;
    // 实验结果发现,array+1与p+1移动了相同的字节数,那么,可以说明
    // array的指类就是double。
    
    // matrix完全可以看成是一个一维数组的首地址常量:
    // double matrix[3][4]; => double[4] matrix[3];
    // 令double[4]为type(某种数据类型);那么,对matrix的定义可以看成:
    // type matrix[3];
    // 在这个角度看,matrix就是一个一维数组名称;根据前面对一位数组名称
    // 的讨论可知,matrix是一个指针常量,且其指类为type!
    // 更进一步可知:matrix + 1将移动sizeof(type)的长度!
    // 即,sizeof(double[4])
    printf("sizeof(double[4]):%d\n", sizeof(double[4]));
    printf("matrix:%p\t&matrix[0][0]:%p\n", matrix, &matrix[0][0]);
    printf("matrix+1:%p\t&matrix[0][0]+1:%p\n", matrix + 1, &matrix[0][0]+1);
    // matrix + 1移动了32B;&matrix[0][0] + 1移动了8B;
    // 说明:指针常量matrix的值与指针表达式&matrix[0][0]的值相同;
    // 但是!这不是两个类型相同的指针,即,指类不同!
    // matrix的指类是double[4];&matrix[0][0]的指类是double!
    // C编译器在处理两个指针时,在不涉及指类操作的情况下,将一视同仁!
    
    // scanf("%lf", &matrix[0][0]);    // 这是给二维数组第一个元素从键盘赋值
    // scanf("%lf", matrix); // 这同样可以完成上述任务!
    // 在此时,C编译器不对指针指类进行严格检查!!!
    // scanf("%lf", *matrix); // 这样的写法将使gcc的警告消失!
    // printf("matrix[0][0]:%lf\n", matrix[0][0]);
    // 上述实验证明*matrix与&matrix[0][0]类型是完全相同的!
    printf("*matrix+1:%p\t &matrix[0][0]+1:%p\n", *matrix+1, &matrix[0][0]+1);
    
    printf("\n&matrix:%p\t &matrix+1:%p\n", &matrix, &matrix + 1);
    scanf("%lf", &matrix); // 这样的写法将使gcc的警告消失!

return 0;
}

原文地址:https://www.cnblogs.com/youdiaodaxue16/p/9031972.html

时间: 2024-08-27 12:37:21

指针与二维数组的相关文章

二级指针与二维数组

最近看<Linux C程序设计大全>这本书,虽然书中有一些错误,但整体来说,书写得还算可以. 当看到网络编程[第23.2.4小节 获得主机信息]时,遇到了一段代码,原文如下: “一台主机有许多和网络相关的信息,例如,主机名称.IP地址.主机提供的服务等.这些信息一般都保存在系统中的某个文件里(例如/etc/hosts等),用户程序可以通过系统提供的函数读取这些文件上的内容.Linux环境下使用gethostent函数读取和主机有关的信息,该函数的原型如下: 1 #include <net

指针与二维数组间的关系

1.四种表示a[i][j]的形式是等价的: a[i][j]==*(a[i]+j)==*(*(a+i)+j)==(*(a+i))[j] 2.通过行指针p引用二维数组a的元素a[i][j]的方法可用以下4种等价形式: p[i][j]==*(p[i]+j)==*(*(p+i)+j)==(*(p+i))[j] 3.对指向二维数组的行指针p进行初始化的方法: p=a 或p=&a[0] 4.对指向二维数组的列指针进行初始化的方法(以下三种方法等价): p=a[0] 或 p=*a 或 p=&a[0][0

例看二维数组,指针,二维数组指针

例程: /****************************************************** * * 文件名:例程 * * 文件描述:例看二维数组,指针,二维数组指针 * * 创建人:Jesse * * 版本号: * * 修改记录: * ******************************************************/ #include <stdio.h> #define ROW 3 #define LINE 3 void main(voi

指针和二维数组

指针和二维数组 首先定义一个数组: 1 int a[5][3] = { {1,6,11}, 2 {2,7,12}, 3 { 3,8,13 }, 4 { 4,9,14 }, 5 { 5,10,15 } 6 }; 随便定义的一个二维数组i = 5, j = 3 然后看下面3种方式: 1 int *b = a[0]; 2 int *c = *a; 3 int &d = **a; 其实上面的三种方式的效果是一样的,大牛一看就知道,这不是废话么.我们还是输出下 1 //value 2 std::cout

数组指针与二维数组的寻址

引例:已知如下程序 1 #include <stdio.h> 2 main() 3 { 4 int x[3][4] = {1,3,5,7,9,11,2,4,6,8,10,12} ; 5 int (*p)[4] = x, k = 1, m, n = 0; 6 for(m=0; m < 2; m++) 7 n += *(*(p+m)+k); 8 printf("%d\n",n); 9 } 试写出程序的输出值.(虽然我很讨厌做这种笔头功夫的题,我也坚信编程语言是在实践中练出

c语言指针与二维数组

1 指针数组 例子: int i,j; int x[2][3]={{1,2,3},{4,5,6}}; int *p[2]={x[0],x[1]};//声明一个含有2个元素的一维int指针数组p for(i=0;i<2;i++) { for(j=0;j<3;j++) { cout<<*(p[i]+j)<<endl; } } 输出语句为cout<<p[i][j]<<endl;也是可以的. int i,j; int x[2][3]={{1,2,3},{

指针和二维数组的关系

指针引用多维数组 int a[3][4] = {{1,3,5,7},{9,11,13,15},{17,19,21,23}};                    二维数组 a[0]  == 1 2 5 7 a[1]  == 9 11 13 15 a[2]  == 17 19 21 23 OK,二维数组在我们眼中,相当于三个一维数组组成:a代表着 二维数组的首地址. 而在二维数组中需要我们特别注意的是 a+1 指向其实是a[1]的地址. 我们在例子中设置的是 “INT” 类型的,在32位 vs中

指针与数组--指针与二维数组2

指向一维数组的指针   char (*p)[10] ;指向一维数组的指针类型 typedef  char(*TYPE_P2ARRAY)[10]  ;   该指针可以指向数组 ,且使用起来效果节本相同,但指针与数组并不等价.{sizeof结果不同  , 且该指针还可以指向除此之外其他类型的数据. } #include <stdio.h> typedef int (*TP_PARRY1)[3] ; #define Uart_Printf printf void f1(void) { int a[2

C语言数组篇(五)多级指针和二维数组指针的区别

多级指针 以二级指针为例 二级指针的由来是 指针数组 的指针形式. int *p[10] 读取的顺序是 p[10] --> 10个空间的数组 * p[10] --> 这10个空间的数组里面存放的数据都是 指针型的数据 int *p[10] --> 数组里面每个指针指向的空间存放的是int型的数据 int *p[10] --> int **p; p: 指针数组的数组名,也是数组的首地址. *p 数组里面存放的指针 **p 数组里面存放的指针 指向的空间 的内容 二维数组指针: 二维数