C语言 二维数组与指针笔记

今天分析了C语言二维数组和指针的基本理解,感觉有点懵。。。代码记录一下,如果有大神临幸发现哪里有误,欢迎指正~~~

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//void func(int p[][])  //这样写等同于void func(int **p)   p++移动了四个字节,(*p)++移动了四个字节,不符合二维数组规律
//{
//}

//列优先输出的函数(即竖着输出)
void func(int p[][4], int a, int b)  //这样写是正确的,这样写等同于void func(int (*p)[4])   p++移动16个字节,(*p)++移动了4个字节,a和b是为了保持维度,a表示列,b表示行
{
    for (int i = 0; i < a; i++)
    {
        for (int j = 0; j < b; j++)
        {
            printf("%d\n", *(*(p + j) + i));
        }
    }
}

int main()
{
    int array[3][4] = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 } };

    //printf("%d\n", sizeof(array[0]));  // 结果为16,妈的,array[0]竟然不是指针,而是一个数组的名称,
    //printf("%d\n", sizeof(array));    //结果48
 func(array, 

sizeof(array[0]) / sizeof(int), sizeof(array) / sizeof(array[0]));//

第二个参数是列数,第三个参数为行数
//array[0]并不是一个变量,是二维数组中第0行的首地址
//和下面的:      *(p + 0) + 1;    代表int *向后位移了一个位置   道理上应该是相同的。

        //在二维数组中*array代表的也是数组的首地址,而一维数组中*array代表的是第一个元素的值
    //printf("%d  %d  %d  %d\n", array, *array, &array, &array[0][0], array[0]);

   //

printf("%d\n", array + 1); //

printf("%d\n", array[0] + 1);
        //结果为array + 1  移动了16个字节
        //        array[0] + 1 移动了4个字节
        //可以这样理解,array + 1看成连长,array[0] + 1看成排长,连长每次走一行(即走4个数,14个字节),排长每次走一列(即走一个数,4个字节)

    //int *p = array;  //指向一维数组的指针

//int (*p)[4];

是一个变相的二级指针
    //p = array;
    //*(p + 0) + 1;    代表int *向后位移了一个位置

    //for (int i = 0; i < 4; i++)
    //{
    //    for (int j = 0; j < 3; j++)
    //    {
    //        printf("%d\n", *(*(p + j) + i));
    //    }
    //}
    //*(p + 0)   代表的是指向第一行的指针。所以*(p + 0) + 1  是指向第一行第二个元素的位置
    //printf("---------------\n");

    //-----------
    //p + 1;   //代表的是排长,每次走一行
    //p[0][0] = *(*(p + 0) + 0);  //代表的是连长,每次走一个数

    //printf("%d\n", *(*(p+1)));  //第一行第0个元素

    system("pause");
    return 0;
}

分析如下:

黄色代码部分:输出的地址完全相同,所以二维数组和一维数组的一点区别是:   在二维数组中*array代表的也是数组的首地址,而一维数组中*array代表的是第一个元素的值

红色代码部分:      相对于黄色代码部分,红色代码结果为:     array + 1 移动了16个字节  , array[0] + 1 移动了4个字节;

因为array是数组的首地址,而且是一个二维数组,所以array+1  应该是移动一行,即4个数字,array[0]是二维数组的“第一行数组”的首地址,所以+1应该是在第一行数组里面移动指针;

( 如果 int  *p = &i;  那么p+1的结果就会移动4个字节,如果 char  *p = &i;  那么p+1的结果就会移动1个字节,  这里其实也是相同的道理,只是不好理解。。。)

也可以使用排长和连长的例子来理解,把array看成连长,把array[0]看成排长,连长每次审阅,会一行一行的走,排长审阅,则会一排一排的走,所以array(连长)每次走16个字节,array[0]每次走4个字节。

橘黄色代码部分:       定义二级指针的时候,一般会这样定义,int (*p)[4];

这里有一个“指针数组”和“数组指针”的概念,图示和代码如下:

指针数组:                                                                                    数组指针

int *p[5];                                                                           int (*P)[10];

#include <stdio.h>
#include <stdlib.h>

int main()
{
           //指针数组
           char *s[10];   //是一个数组,该数组中有10个char *指针,每个指针指向一个字符
          printf( "%d\n" ,sizeof (s[0]));  //4

           //数组指针
           char (*s1)[10];    //是一个指针变量,该指针变量指向一个char[10];不能指向其他任何char[n]数组
          printf( "%d\n" , sizeof (s1));   //4

          system( "pause" );
           return 0;
}

所以:int (*p)[4]; 是一个数组指针,指向一个4个元素的数组,

p = array;    也就是把二维数组的首地址赋给p,array也是一个地址(相当于一个指针,但如果我们用sizeof(array)会发现其实不是一个指针),所以p其实是一个变相的二级指针(你不信的话可以利用**p测试看是否能够取到数组的第一个元素)

所以    *(p + 0) + 1; 代表int *向后位移了一个位置   也就不难理解了, p是一个二级指针, p+0代表的其实就是第一行数组的首地址。*(p+0) 还是一个指针,  也就是一个int * 类型的变量(指针也是一个变量),*(p + 0) + 1;代表的就是int *向后位置了一个位置

*(p + 0) 代表的是指向第一行的指针。所以*(p + 0) + 1 是指向第一行第二个元素的位置的指针,*(*(p + 0) + 1 ) 就是第一行第二个元素的值;

灰色颜色代码的部分:     这样写的原因就是直接把二维数组的维度发过去,因为在接收端函数方是不知道二维数组的维度的,而且这样写以后更改数组的维度的时候,不用更改其他代码。

时间: 2024-10-11 11:56:44

C语言 二维数组与指针笔记的相关文章

C语言 二维数组(指针)动态分配和释放(转)

C 二维数组(指针)动态分配和释放 先明确下概念: 所谓32位处理器就是一次只能处理32位,也就是4个字节的数据,而64位处理器一次就能处理64位,即8个字节的数据.如果我们将总长128位的指令分别按照16位.32位.64位为单位进行编辑的话:旧的16位处理器,比如Intel 80286 CPU需要8个指令,32位的处理器需要4个指令,而64位处理器则只要两个指令,显然,在工作频率相同的情况下,64位处理器的处理速度会比16位.32位的更快.而且除了运算能力之外,与32位处理器相比,64位处理器

程序猿之--C语言细节13(二维数组和指针,&amp;*a[i][0]的理解,数组1[e]和e[1]很可能你没见过)

主要内容:二维数组和指针,&*a[i][0]的理解.数组1[e]和e[1] #include <stdio.h> #define NUM_ROWS 10 #define NUM_COLS 10 int main(int argc, char **argv) {     int a[NUM_ROWS][NUM_COLS], *p, i = 0; // a理解为指向整数指针的指针 即int **     int c, d=2,*test, e[2] = {4,5},f[2][2] = {{

程序员之--C语言细节13(二维数组和指针,&amp;amp;*a[i][0]的理解,数组1[e]和e[1]非常可能你没见过)

主要内容:二维数组和指针.&*a[i][0]的理解.数组1[e]和e[1] #include <stdio.h> #define NUM_ROWS 10 #define NUM_COLS 10 int main(int argc, char **argv) {     int a[NUM_ROWS][NUM_COLS], *p, i = 0; // a理解为指向整数指针的指针 即int **     int c, d=2,*test, e[2] = {4,5},f[2][2] = {{

直观理解C语言中指向一位数组与二维数组的指针

一维数组和指针: 对于一位数组和指针是很好理解的: 一维数组名: 对于这样的一维数组:int a[5];  a作为数组名就是我们数组的首地址, a是一个地址常量 . 首先说说常量和变量的关系, 对于变量来说, 用箱子去比喻再好不过了, 声明一个变量就声明一个箱子,比如我们开辟出一个苹果类型的箱子, 给这个变量赋值就是把盛放苹果的箱子中放入一个实实在在的苹果, 这就是变量的赋值.  而对于数组来说, 就是一组类型相同的箱子中,一组苹果箱子, 可以放入不同的苹果. 一维数组空间: 变量被声明后, 我

对二维数组使用指针进行操作的探索(C语言)

1 /* 2 Name: 对二维数组使用指针进行操作的探索 3 Copyright: 4 Author: lingr7 5 Date: 01/12/18 11:55 6 Description: 7 */ 8 #include<stdio.h> 9 int main() { 10 11 int a[2][3] = {{1,2,3},{4,5,6}}; 12 int **p = a;/*这一步,将a存放的地址赋值给了p,这一步是的p与a完全等价*/ 13 int *p2 = p;/*这一步就将a

C语言二维数组作为函数的参数

前言:今天在实现装配线调度程序时候,用到了二维数组,并将其作为函数的参数.在写程序的时候,遇到一些问题,即二维数组做函数的参数应该如何正确表示.我写程序的错误如下程序所示: #include <cstdio> void print(int *a[3]) { printf("%d\n",a[0][0]); } int main() { int a[2][3] = {1,2,3,4,5,6}; print(a); return 0; } 编译程序时候,在第10行提示错误信息:|

c语言二维数组传递

c语言二维数组传递,目前我总结三种方法,以及纠正一个不能使用的方法 /********************************* * 方法1: 第一维的长度可以不指定 * * 但必须指定第二维的长度 * *********************************/ void fun(int a[][3], int n, int m) { int i, j; for (i = 0; i < n; i++) { for (j = 0; j < m; j++) printf(&quo

二维数组和指针

二维数组和指针⑴ 用指针表示二维数组元素.要用指针处理二维数组,首先要解决从存储的角度对二维数组的认识问题.我们知道,一个二维数组在计算机中存储时,是按照先行后列的顺序依次存储的,当把每一行看作一个整体,即视为一个大的数组元素时,这个存储的二维数组也就变成了一个一维数组了.而每个大数组元素对应二维数组的一行,我们就称之为行数组元素,显然每个行数组元素都是一个一维数组 下面我们讨论指针和二维数组元素的对应关系,清楚了二者之间的关系,就能用指针处理二维数组了.设p是指向数组a的指针变量,若有:p=a

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

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