精华内容
下载资源
问答
  • C语言指针数组数组每个元素都是指针)详解 C语言二数组指针(指向二数组的指针)详解 如果个数组中的所有元素保存的都是指针,那么我们就称它为指针数组指针数组的定义形式一般为: dataType *arrayName...

    声明!本文转载仅为方便学习使用!
    如有需要,请访问
    C语言指针数组(数组每个元素都是指针)详解
    C语言二维数组指针(指向二维数组的指针)详解

    如果一个数组中的所有元素保存的都是指针,那么我们就称它为指针数组。指针数组的定义形式一般为:

    dataType *arrayName[length];
    

    [ ]的优先级高于*,该定义形式应该理解为:

    dataType *(arrayName[length]);
    

    括号里面说明arrayName是一个数组,包含了length个元素,括号外面说明每个元素的类型为dataType *

    除了每个元素的数据类型不同,指针数组和普通数组在其他方面都是一样的,下面是一个简单的例子:

    #include <stdio.h>
    int main(){
        int a = 16, b = 932, c = 100;
        //定义一个指针数组
        int *arr[3] = {&a, &b, &c};//也可以不指定长度,直接写作 int *arr[]
        //定义一个指向指针数组的指针
        int **parr = arr;
        printf("%d, %d, %d\n", *arr[0], *arr[1], *arr[2]);
        printf("%d, %d, %d\n", **(parr+0), **(parr+1), **(parr+2));
        return 0;
    }
    

    运行结果:

    16, 932, 100
    16, 932, 100
    

    arr 是一个指针数组,它包含了 3 个元素,每个元素都是一个指针,在定义 arr 的同时,我们使用变量 a、b、c 的地址对它进行了初始化,这和普通数组是多么地类似。

    parr 是指向数组 arr 的指针,确切地说是指向 arr 第 0 个元素的指针,它的定义形式应该理解为int *(*parr),括号中的*表示 parr 是一个指针,括号外面的int *表示 parr 指向的数据的类型。arr 第 0 个元素的类型为 int *,所以在定义 parr 时要加两个 *

    第一个 printf() 语句中,arr[i] 表示获取第 i 个元素的值,该元素是一个指针,还需要在前面增加一个 * 才能取得它指向的数据,也即 *arr[i] 的形式。

    第二个 printf() 语句中,parr+i 表示第 i 个元素的地址,*(parr+i) 表示获取第 i 个元素的值(该元素是一个指针),**(parr+i) 表示获取第 i 个元素指向的数据。

    指针数组还可以和字符串数组结合使用,请看下面的例子:

    #include <stdio.h>
    int main(){
        char *str[3] = {
            "Gakki",
            "is",
            "my girlfriend."
        };
        printf("%s\n%s\n%s\n", str[0], str[1], str[2]);
        return 0;
    }
    

    运行结果:

    Gakki
    is
    my girlfriend.
    

    需要注意的是,字符数组 str 中存放的是字符串的首地址,不是字符串本身,字符串本身位于其他的内存区域,和字符数组是分开的。

    也只有当指针数组中每个元素的类型都是char *时,才能像上面那样给指针数组赋值,其他类型不行。

    为了便于理解,可以将上面的字符串数组改成下面的形式,它们都是等价的。

    #include <stdio.h>
    int main(){
        char *str0 = "c.biancheng.net";
        char *str1 = "C语言中文网";
        char *str2 = "C Language";
        char *str[3] = {str0, str1, str2};
        printf("%s\n%s\n%s\n", str[0], str[1], str[2]);
        return 0;
    }
    

    测试

    #include <string.h>
    #include <conio.h>
    #include <stdio.h>
    
    void main()
    {
    	int a = 2014, b = 7, c = 29;
    	char *arr[3] = {&a,&b,&c};
    	int **parr = arr;
    	printf("\ta, b, c:\n\t%d,%d,%d\n", a, b, c);
    	printf("\t&a, &b, &c:\n\t%d,%d,%d\n", &a, &b, &c);
    	printf("\tarr[0], arr[1], arr[2]:\n\t%d,%d,%d\n", arr[0], arr[1], arr[2]);
    	printf("\t*(arr+0),*(arr + 1),*(arr + 2):\n\t%d,%d,%d\n", *(arr+0),*(arr + 1),*(arr + 2));
    	printf("\tparr+0,parr+1,parr+2:\n\t%d,%d,%d\n", parr+0,parr+1,parr+2);
    	printf(" \t*(parr + 0), *(parr + 1), *(parr + 2):\n\t%d,%d,%d\n", *(parr + 0), *(parr + 1), *(parr + 2));
    	printf("\t**(parr + 0), **(parr + 1), **(parr + 2):\n\t%d,%d,%d\n", **(parr + 0), **(parr + 1), **(parr + 2));
    }
    

    运行结果:
    在这里插入图片描述

    展开全文
  • C语言指针重点难点整理(详解)(包括一维数组,二维数组的元素指针,二维数组的行指针做函数参数,指针数组,行指针数组) 笔者学指针之前: 呵呵,听闻指针是C语言的难点,我倒要见识一下,到底有多难 笔者学完...

    C语言指针重点难点整理(详解)(包括一维数组的元素指针,二维数组的元素指针,二维数组的行指针做函数参数,指针数组,行指针数组)

    笔者学指针之前: 呵呵,听闻指针是C语言的难点,我倒要见识一下,到底有多难

    在这里插入图片描述

    笔者学完指针之后: 我还是收拾行囊,离开吧!

    在这里插入图片描述

    但是,在我的内心经过反复的挣扎,终于我决定,我要战胜它,现在,笔者已经大概弄清楚了指针的知识点,今天周末,刚好整理一下指针的一些难以理解的地方,和一些重点的地方(常言道:难以理解的地方往往是重点的地方),下年我分几个部分梳理一下,供各位大佬茶余饭后打发时间,如有不妥之处,还望指出。

    一.一维数组的指针做函数参数

    来,给皇上把代码呈上来:

    void Test_1(int *x,int lenx)
    {
     for (int i = 0; i < lenx; i++)
     {
      printf("%-3d ", x[i]);
     }
    }
    
    
    int main()
    {
     int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
     printf("用一维数组的指针作为函数参数来引用数组元素:\n");
     Test_1(a, 10);
     printf("\n");
     return 0;
    }
    /*
    用一维数组的指针作为函数参数来引用数组元素:
    1   2   3   4   5   6   7   8   9   10
    */

    (1)实参

    首先要把一维数组名作为函数的实参,像这样Test_1(a, 10);

    (2)形参

    函数的形参依据一维数组的类型,一维数组维type型,形参为type *型,像这里的int *x

    ***这里函数的形参有多种形式,还可以是void Test_1(int x[],int lenx),void Test_1(int x[10],int lenx)

    这里虽然写成一维数组的形式,但是其本质上还是一个type *型的指针

    (3)数组元素的引用

    ***注意,可以在函数中直接用x[i]来引用数组元素,但是要想遍历,就必须知道数组长度,这里可以将数组长度一并传递

    还可以用*(a+i)来引用一维数组的第i个元素

    (4)函数的声明

    函数的声明为void Test_1(int *x,int lenx);或者是void Test_1(int x[],int lenx);

    二.二维数组的行指针做函数参数(逐行传递行指针)

    老规矩,先上DJ,先上DJ:

    void Test_2_1(int (*x)[N])
    {
     for (int i = 0; i < N; i++)
      printf("%-3d ", (*x)[i]);
     printf("\n");
     }
     
     int main()
    {
     int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
     int b[5][5] = { { 1, 2, 3, 4, 5 }, { 6, 7, 8, 9, 10 }, 
     { 11, 12, 13, 14, 15 }, { 16, 17, 18, 19, 20 },
      { 21, 22, 23, 24, 25 } };
     printf("二维数组的行指针作为函数参数(逐行传递行指针):\n");
     for (int i = 0; i < 5; i++)
      Test_2_1(b + i);
      return 0;
    }
    /*
    二维数组的行指针作为函数参数(逐行传递行指针):
    1   2   3   4   5
    6   7   8   9   10
    11  12  13  14  15
    16  17  18  19  20
    21  22  23  24  25
    */

    解释一下趴!

    在这里插入图片描述

    (1)形参

    函数的形参,数组为type型,则形参为type (x)[N],这表示该函数的形参为一个type型的行指针,

    该行指针指向有N个type型元素的二维数组的一行,N是行指针指向的哪一行的type型元素的个数,

    –这里是二维数组的每一行的长度。***形参变量还可以写成与type (*x)[N]等价的形式,type x[][N],type x[5][N]

    这两种形式本质上还是行指针

    (2)实参

    这里实参是这样写的,别的也大同小异b+i,这表示第i行的行指针(下标从0开始算)

    (3)数组元素的引用

    ①用(*x)[i]来访问这一行第i个元素,(*x)[N]是行指针,指向一行,(*x)相当于一个一维数组名,

    (*x)[i]访问这一行第i个元素

    ②*(*x+i)来访问这一行第i个元素,这个表示应该这么理解,(*x)[N]是行指针,可以看作是一个一维数组,

    (*x)相当于一维数组名,是这个数组第一个元素的指针,也就是这一行第一个元素的指针,*x+i自然就是这一行第i个元素的指针

    *(*x+i)自然就访问了这一行的第i个元素

    (4)函数的声明

    void Test_2_1(int (*x)[N]);或者是void Test_2_1(int x[][N]);或者是void Test_2_1(int x[5][N]);

    三.二维数组的行指针做函数参数(只传递第0行的指针)

    还是来看代码:

    void Test_2_2(int(*x)[N])
    {
      for (int i = 0; i < 5; i++)
     {
      for (int j = 0; j < N; j++)
      {
       printf("%-3d ", x[i][j]);
      }
      printf("\n");
     }
    
    
    int main()
    {
     int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
     int b[5][5] = { { 1, 2, 3, 4, 5 }, { 6, 7, 8, 9, 10 }, 
     { 11, 12, 13, 14, 15 }, { 16, 17, 18, 19, 20 },
      { 21, 22, 23, 24, 25 } };
      printf("二维数组的行指针作为函数参数(传递第0行的行指针,也就是传递二维数组名):\n");
     Test_2_2(b);
     return 0;
    }
    /*
    二维数组的行
    /*
    二维数组的行指针作为函数参数(传递第0行的行指针,也就是传递二维数组名):
    1   2   3   4   5
    6   7   8   9   10
    11  12  13  14  15
    16  17  18  19  20
    21  22  23  24  25
    */

    (1)形参

    只传递第0行的指针,这里的形参的规则跟依次传递每一行的指针规则相同

    (2)实参

    这里的实参,很显然,是第0行的行指针,这里是b,也就是二维数组名

    (3)数组元素的引用

    ***这里的数组元素引用十分便捷,直接用b[i][j]引用,因为这里系统知道了每行有N个元素

    (4)函数的声明

    void Test_2_2(int (*x)[N]);或者是void Test_2_2(int x[][N]);或者是void Test_2_2(int x[5][N]);

    四.二维数组的元素指针做函数参数

    老规矩:

    void Test_3(int *p)
    {
     for (int i = 0; i < 25; i++)
     {
      printf("%-3d ", p[i]);
      if ((i + 1) % 5 == 0 && i != 0)
       printf("\n");
     }
    }
    
    int main()
    {
     int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
     int b[5][5] = { { 1, 2, 3, 4, 5 }, { 6, 7, 8, 9, 10 }, 
     { 11, 12, 13, 14, 15 }, { 16, 17, 18, 19, 20 }, 
     { 21, 22, 23, 24, 25 } };
     printf("二维数组的元素指针作为函数参数:\n");
     Test_3(&b[0][0]);
     return 0;
    }
    /*
    二维数组的元素指针作为函数参数:
    1   2   3   4   5
    6   7   8   9   10
    11  12  13  14  15
    16  17  18  19  20
    21  22  23  24  25
    */

    (1)形参

    形参就是一个type *型的指针就可,和一维数组相同

    (2)实参

    实参在这里其实有三种形式,Test_3(&b[0][0]);这种形式是用二维数组的元素指针作为函数参数

    但是在这里用Test_3(b);,Test_3(b[0]);均可,需要指出的是,这里的两种情况,并不是二维数组的元素指针

    作为函数参数,严格的来说,b这是第一行的行指针,b[0]是b[0][0]的指针,本质来说还是指针,是可以传递给p的

    但是这里的b是行指针,传递给一个Int型的指针,虽然结果没错,但是充满着不专业

    但是因为数组元素是连续储存的,所以说这两种方法都能够访问到数组元素

    (3)数组元素的引用

    *(p + i),p[i]两种方法均能够对数组元素进行引用

    (4)函数的声明

    直接就是跟一维数组类似void Test_3(int *p);

    五.指针数组

    我叫你一声代码,你敢答应吗?
    在这里插入图片描述

    int main()
    {
     int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
     int b[5][5] = { { 1, 2, 3, 4, 5 }, { 6, 7, 8, 9, 10 }, 
     { 11, 12, 13, 14, 15 }, { 16, 17, 18, 19, 20 }, 
     { 21, 22, 23, 24, 25 } };
     printf("指针数组:\n");
     int *p[5] = { b[0], b[1], b[2], b[3], b[4] };
     for (int i = 0; i < 5; i++)
      printf("%d  %-3d\n", p[i], *p[i]);
      return 0;
    }
    /*
    指针数组:
    12187356  1
    12187376  6
    12187396  11
    12187416  16
    12187436  21
    */

    (1)声明

    type *p[N];例如int *p[5];表示声明一个有五个指针的指针数组

    注意,这里指针数组的声明和行指针要区分开来,行指针声明是int (p)[5];[]的优先级比

    一个指向五个int型元素的行指针

    (2)赋值

    给指针数组赋值。每一个元素都要是指针

    六.行指针数组

    在这里插入图片描述

    int main()
    {
     int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
     int b[5][5] = { { 1, 2, 3, 4, 5 }, { 6, 7, 8, 9, 10 }, 
     { 11, 12, 13, 14, 15 }, { 16, 17, 18, 19, 20 },
      { 21, 22, 23, 24, 25 } };
      printf("行指针数组:\n");
     int(*p1[5])[5] = { b, b + 1, b + 2, b + 3, b + 4 };
     for (int i = 0; i < 5; i++)
     {
      printf("%d   ", p[i]);
      for (int j = 0; j < 5;j++)
       printf("%-3d ", p[i][j]);
      printf("\n");
     }
     return 0;
    }
    /*
    行指针数组:
    12187356   1   2   3   4   5
    12187376   6   7   8   9   10
    12187396   11  12  13  14  15
    12187416   16  17  18  19  20
    12187436   21  22  23  24  25
    */

    (1)声明

    type (*p[M])[N];这里声明了一个数组名为p,共有M个元素,

    每个元素都是指向一行有N个int型元素的一维数组,注意M,N的含义不要弄反了

    即p[0],p[1],p[2],p[3],p[4]均是行指针,均指向一行,p[i]指向第i行,*p[i]指向第i行的第一个元素
    *p[i]+j指向b[i][j]

    (2)赋值

    给行指针数组赋值。每一个元素都要是行指针

    (3)引用

    行指针可以带下标使用,p[i][j]代表b[i][j],和*(*p[i]+j)等价

    好啦,六个我觉得是重难点的分享完了,下面把这六个部分合在一起来的代码放在下面:
    #define _CRT_SECURE_NO_WARNINGS 1
    #define N 5
    #include<stdio.h>
    
    void Test_1(int *x,int lenx)
    {
     for (int i = 0; i < lenx; i++)
     {
      printf("%-3d ", x[i]);
     }
    }
    
    void Test_2_1(int (*x)[N])
    {
     for (int i = 0; i < N; i++)
      printf("%-3d ", (*x)[i]);
     printf("\n");
    }
    
    void Test_2_2(int(*x)[N])
    {
     for (int i = 0; i < 5; i++)
     {
      for (int j = 0; j < N; j++)
      {
       printf("%-3d ", x[i][j]);
      }
      printf("\n");
     }
    }
    
    void Test_3(int *p)
    {
     for (int i = 0; i < 25; i++)
     {
      printf("%-3d ", p[i]);
      if ((i + 1) % 5 == 0 && i != 0)
       printf("\n");
     }
    }
    
    int main()
    {
     int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
     int b[5][5] = { { 1, 2, 3, 4, 5 }, { 6, 7, 8, 9, 10 }, 
     { 11, 12, 13, 14, 15 }, { 16, 17, 18, 19, 20 }, 
     { 21, 22, 23, 24, 25 } };
    
    printf("用一维数组的指针作为函数参数来引用数组元素:\n");
     Test_1(a, 10);
     printf("\n");
    
     printf("二维数组的行指针作为函数参数(逐行传递行指针):\n");
     for (int i = 0; i < 5; i++)
      Test_2_1(b + i);
    
     printf("二维数组的行指针作为函数参数(传递第0行的行指针,也就是传递二维数组名):\n");
     Test_2_2(b);
    
     printf("二维数组的元素指针作为函数参数:\n");
     Test_3(&b[0][0]);
    
     printf("指针数组:\n");
     int *p[5] = { b[0], b[1], b[2], b[3], b[4] };
     for (int i = 0; i < 5; i++)
      printf("%d  %-3d\n", p[i], *p[i]);
    
     printf("行指针数组:\n");
     int(*p1[5])[5] = { b, b + 1, b + 2, b + 3, b + 4 };
     for (int i = 0; i < 5; i++)
     {
      printf("%d   ", p[i]);
      for (int j = 0; j < 5;j++)
       printf("%-3d ", p[i][j]);
      printf("\n");
     }
    
    return 0;
    }
    /*
    1   2   3   4   5
    6   7   8   9   10
    11  12  13  14  15
    16  17  18  19  20
    21  22  23  24  25
    指针数组:
    12187356  1
    12187376  6
    12187396  11
    12187416  16
    12187436  21
    行指针数组:
    12187356   1   2   3   4   5
    12187376   6   7   8   9   10
    12187396   11  12  13  14  15
    12187416   16  17  18  19  20
    12187436   21  22  23  24  25
    请按任意键继续. . .
    */

    最后,特殊时期
    在这里插入图片描述
    原创不易,嘿嘿
    在这里插入图片描述

    展开全文
  • 指针数组其实就是个数组,数组中每个元素都是指针。 2. 二数组 二数组也是个数组,不过数组中的每个元素都是数组。乍看起来好像很像对不对,区别只是数组元素不同,但其实这两种东西在内存中的布局完全...

    一个C语言指针数组和二维数组的小实验

    最近在用C语言写toy compiler,写的过程中突然发现自己对指针数组和二维数组的语法有了新的认识。
    1. 指针数组
    指针数组其实就是一个数组,数组中每个元素都是指针。
    2. 二维数组
    二维数组也是一个数组,不过数组中的每一个元素都是数组。

    乍看起来好像很像对不对,区别只是数组元素不同,但其实这两种东西在内存中的布局完全不一样。再看下面的代码就会发现它们俩更像了:

    char *a[5];         // 指针数组
    char b[5][5];       // 二维数组
    
    char c = a[3][3];
    char d = b[3][3];

    这段程序编译是可以通过的,这会给我们一种假象——二维数组和指针数组是一回事。
    这当然是不对的,原因其实很简单,a[3][3]b[3][3]完全不是一回事,虽然长得很像。
    其实如果你学过汇编或者计算机组成原理之类的课就会知道,a[3][3]其实可以分成两步:

    char *tmp = a[3];
    char c = tmp[3];
    或者
    char c = *(tmp+3);

    但是再一想,b[3][3]也可以分成这两步啊,大写懵逼对不对:

    char *tmp = b[3];
    char d = tmp[3];
    或者
    char d = *(tmp+3);

    区别就在于char *tmp = a[3]这一句,指针数组中a[3]的值就是a向后移动3个sizeof(char *)那个存储单元中的值。而b[3]的值是是b向后移动3*5+3sizeof(char)那个位置的地址。

    很清楚了,第一个tmp的值是内存里的数据(a是一个指针数组,所以tmp的值就是指针),第二个tmp的值是地址(这个地址其实是编译器在代码生成时就静态生成了的)。

    以一个例子结尾,这个例子只能在i386平台或者其他32位小端模式的CPU上运行。

    #include <stdio.h>
    
    void m(char *ar[]) {
        char a = ar[0][3];
        printf("%c", a);
    }
    
    int main() {
        char a[5][5];
        char b = 'a';
        char *pb = &b;
        pb = pb-3;
        a[0][0] = (char)((int)pb);
        a[0][1] = (char)((int)pb>>8);
        a[0][2] = (char)((int)pb>>16);
        a[0][3] = (char)((int)pb>>24);
        m((char **)a);
    
    }

    其中a是一个二维数组,而m()中的ar是一个元素是char *的数组。我的目的就是想让把a传入m()中,在m()中使用ar访问。
    ar[0][3]的访问就像刚刚说的,访问的是ar[0]指向的那个数组中第三个元素。

    这里写图片描述

    现在我们让a的前四个元素a[0][0-3]分别赋值为&b-3的地址各八位。然后将a赋值给ar。所以ar[0][3]访问的就是由a[0][0-3]所构成的地址指向的数组的第三个成员b。这里ar[0]其实并没有指向一个数组指针,只是我们把ar[0]变成了&b-3罢了。

    需要注意的是,在Intel的32位机器上地址才是4byte,4个连续的char才能存的下;如果是64位机器则有可能需要8个char才能放下,但不排除64位机器仍然使用32位地址的可能。

    为此我们需要在编译时加上-m32参数
    gcc test.c -m32

    另外,在Intel机器上,默认采用的是小端模式存储超过一个字节的数据类型。所以我们将a[0][0]赋值为&b-3最低8位,a[0][3]赋值为最高8位。

    总结

    C语言的指针数组和二维数组完全不一样,虽然都是通过[][]的形式访问,但一个是运行时生成,一个是编译时生成。C语言的指针和强制类型转换可以写出强大的代码,能够修改程序内存中的任意位置,但可读性以及可移植性都大大降低,这恐怕也是Java这类语言的出现原因吧。

    展开全文
  • 数组与指针、指针数组、数组指针的用法

    万次阅读 多人点赞 2018-03-12 18:16:20
    二维数组指针⑴ 用指针表示二维数组元素。要用指针处理二维数组,首先要...而每个大数组元素对应二维数组的一行,我们就称之为行数组元素,显然每个行数组元素都是一个一维数组下面我们讨论指针和二维数组元素的...

    二维数组和指针⑴ 用指针表示二维数组元素。
    要用指针处理二维数组,首先要解决从存储的角度对二维数组的认识问题。我们知道,一个二维数组在计算机中存储时,是按照先行后列的顺序依次存储的,当把每一行看作一个整体,即视为一个大的数组元素时,这个存储的二维数组也就变成了一个一维数组了。而每个大数组元素对应二维数组的一行,我们就称之为行数组元素,显然每个行数组元素都是一个一维数组

    下面我们讨论指针和二维数组元素的对应关系,清楚了二者之间的关系,就能用指针处理二维数组了。
    设p是指向二维数组a[m][n]的指针变量,则有:

    int* p=a[0];//此时P是指向一维数组的指针。P++后,p指向 a[0][1]。

    如果定义int (*p1)[n];p1=a;p1++后,p1指向a[1][0];  

    则p+j将指向a[0]数组中的元素a[0][j]。
    由于a[0]、a[1]┅a[M-1]等各个行数组依次连续存储,则对于a数组中的任一元素a[i][j],指针的一般形式如下:
    p+i*N+j             相应的如果用p1来表示,则为*(p1+i)+j
    元素a[i][j]相应的指针表示为:
    *( p+i*N+j)        相应的如果用p1来表示,则为*(*(p1+i)+j)
    同样,a[i][j]也可使用指针下标法表示,如下:
    p[i*N+j]
    例如,有如下定义:
    int a[3][4]={{10,20,30,40,},{50,60,70,80},{90,91,92,93}};
    则数组a有3个元素,分别为a[0]、a[1]、a[2]。而每个元素都是一个一维数组,各包含4个元素,如a[1]的4个元素是a[1][0]、a[1][1]、a[1]2]、a[1][3]。
    若有:
    int *p=a[0];
    则数组a的元素a[1][2]对应的指针为:p+1*4+2
    元素a[1][2]也就可以表示为:*( p+1*4+2)
    用下标表示法,a[1][2]表示为:p[1*4+2]
    特别说明:
    对上述二维数组a,虽然a[0]、a都是数组首地址,但二者指向的对象不同,a[0]是一维数组的名字,它指向的是a[0]数组的首元素,对其进行“*”运算,得到的是一个数组元素值,即a[0]数组首元素值,因此,*a[0]与a[0][0]是同一个值;而a是一个二维数组的名字,它指向的是它所属元素的首元素,它的每一个元素都是一个行数组,因此,它的指针移动单位是“行”,所以a+i指向的是第i个行数组,即指向a[i]。对a进行“*”运算,得到的是一维数组a[0]的首地址,即*a与a[0]是同一个值。当用int *p;定义指针p时,p的指向是一个int型数据,而不是一个地址,因此,用a[0]对p赋值是正确的,而用a对p赋值是错误的。这一点请读者务必注意。
    ⑵ 用二维数组名作地址表示数组元素。
    另外,由上述说明,我们还可以得到二维数组元素的一种表示方法:
    对于二维数组a,其a[0]数组由a指向,a[1]数组则由a+1指向,a[2]数组由a+2指向,以此类推。因此,*a与a[0]等价、*(a+1)与a[1]等价、*(a+2)与a[2]等价,┅,即对于a[i]数组,由*(a+i)指向。由此,对于数组元素a[i][j],用数组名a的表示形式为:
    *(*(a+i)+j)
    指向该元素的指针为:
    *(a+i)+j

    数组名虽然是数组的地址,但它和指向数组的指针变量不完全相同。

    第一,指针变量的值可以改变,即它可以随时指向不同的数组或同类型变量,而数组名自它定义时起就确定下来,不能通过赋值的方式使该数组名指向另外一个数组。

    第二,数组名是指针,类型是指向元素类型的指针,但值是指针常量,声明数组时编译器会为声明所指定的元素数量保留内存空间。数组指针是指向数组的指针,声明指针变量时编译器只为指针本身保留内存空间。

    例4 求二维数组元素的最大值。


    该问题只需对数组元素遍历,即可求解。因此,可以通过顺序移动数组指针的方法实现。
    main()
    {
    int a[3][4]={{3,17,8,11},{66,7,8,19},{12,88,7,16}};
    int *p,max;
    for(p=a[0],max=*p;p<a[0]+12;p++)
       if(*p>max)
          max=*p;
    printf("MAX=%d/n",max);
    }
    执行结果:
    MAX=88
    这个程序的主要算法都是在for语句中实现的:p是一个int型指针变量;p=a[0]是置数组的首元素地址为指针初值;max=*p将数组的首元素值a[0][0]作为最大值初值;p<a[0]+12是将指针的变化范围限制在12个元素的位置内;p++使得每比较一个元素后,指针后移一个元素位置。
    例5 求二维数组元素的最大值,并确定最大值元素所在的行和列。
    本例较之上例有更进一步的要求,需要在比较的过程中,把较大值元素的位置记录下来,显然仅用上述指针移动方法是不行的,需要使用能提供行列数据的指针表示方法。
    main()
    {
    int a[3][4]={{3,17,8,11},{66,7,8,19},{12,88,7,16}};
    int *p=a[0],max,i,j,row,col;
    max=a[0][0];
    row=col=0;
    for(i=0;i<3;i++)
       for(j=0;j<4;j++)
         if(*(p+i*4+j)>max)
          {
            max=*(p+i*4+j);
            row=i;
            col=j;
          }
    printf("a[%d][%d]=%d/n",row,col,max);
    }
    程序运行结果:
    a[2][1]=88
    ⑶ 行数组指针
    在上面的说明中我们已经知道,二维数组名是指向行的,它不能对如下说明的指针变量p直接赋值:
    int a[3][4]={{10,11,12,13},{20,21,22,23},{30,31,32,33}},*p;
    其原因就是p与a的对象性质不同,或者说二者不是同一级指针。C语言可以通过定义行数组指针的方法,使得一个指针变量与二维数组名具有相同的性质。行数组指针的定义方法如下:
    数据类型 (*指针变量名)[二维数组列数];
    例如,对上述a数组,行数组指针定义如下:
    int (*p)[4];
    它表示,数组*p有4个int型元素,分别为(*p)[0]、(*p)[1]、(*p)[2]、(*p)[3] ,亦即p指向的是有4个int型元素的一维数组,即p为行指针

    此时,可用如下方式对指针p赋值:

    p=a;

    (4)指针数组的定义

    指针数组是指每个元素中存放的是指针。定义为 int *p[4];sizeof(p)=16,返回的是数组的总空间

    展开全文
  • 如果指针指向了数组,我们就称它为数组指针(Array Pointer) ...如果指针变量 p 指向了数组的开头,那么 p+i 就指向数组的第 i 个元素;如果 p 指向了数组的第 n 个元素,那么 p+i 就是指向第 n+i 个元素;...
  • 指针数组 首先从名字就可以知道这是一个数组,是存放指针的数组。 先看几种指针数组: int * 数组指针 函数指针 函数指针数组 指向函数指针数组的指针
  • 一维数组 指针形式 赋值指针 含义 ...指向一int类型的指针 ...二维数组 ...指针形式 ...指向含有四int类型的一维数组 数组指针 指针形式 含义 多与二维数组使用 int (...
  • 数组指针和指针数组

    万次阅读 多人点赞 2019-09-17 16:39:06
    首先,理解一下数组指针和指针数组这两名词: “数组指针”和“指针数组”,只要在名词中间加上“的”字,就知道中心了...(*p)[n]:根据优先级,先看括号内,则p是一指针,这指针指向一个一维数组,数组长...
  • 指针一维数组 指针移动方式访问数组元素: int a[5], *p; // a存放了数组的首地址 p=a; // 数组首地址赋给p p++; // 向下移动4字节 指针数组名都是地址,因此可以混合使用访问数组元素。...
  • 维数组下面的代码先定义了一个整数二维数组,board[3][3] int board[3][3]={ {'1','2','3'}, {'4','5','6'}, {'7','8','9'} }; printf("*board:%9d\n",*
  • 数组组数据的集合称为数组,它所包含的每一个数据叫做数组元素,例如 int a[4]; 它定义了一个长度为4的整型数组,名字是a . 一般的定义数组可以用 :数据类型 数组名 [数组长度];来声明。当然数组中除了存储...
  • C语音 指针 指向一维数组元素

    千次阅读 2016-01-11 13:06:31
    前面我们已经学习了指针,如果指针存储了某个变量的地址,我们就...一、用指针指向一维数组元素 1 // 定义一int类型的数组 2 int a[2]; 3 4 // 定义一int类型的指针 5 int *p; 6 7 // 让指针指向
  • 概念详解:指针指针与“int a”,...一维数组:定义一维数组之后,即在内存中分配一段连续的地址空间,如C语言中,int num[5],在32位系统中,int占据4字节,现假设num[0]的地址空间为0x00000004,那么num[...
  • #include #include float stu_ave(int *p,int n) //接收列地址,和元素个数 { int i;...//p[i] p是一个列地址 把二维看成一个一维数组所以就是P[i] 来进行遍历每个元素  return sum/n; } int
  • 指针数组与数组指针详解

    万次阅读 多人点赞 2016-09-28 21:21:20
    指针数组指针数组可以说成是”指针的数组”,首先这变量是一个数组,其次,”指针”修饰这数组,意思是说这数组的所有元素都是指针类型,在32位系统中,指针占四字节。 数组指针:数组指针可以说成是”...
  • 本来我是这么想的,令p = a后,p将指向二维数组中首元素的地址,而这个首元素是由4个整型元素组成的一维数组。想用cout *p;输出一行中的第一个元素,即a[0][0], a[1][0], a[2][0], 可是,为什么不管是cout *p; ...
  • * cppTest-3.0:指针相关-2(二维数组&一级指针&二级指针&一维指针数组) * 总结: 1、设有数组Type[列数]、Type[行数][列数]: 数组变量类型:类型+数组长度表示,如一维数组:Type[列数]。二维数组:Type[行数]...
  • 关于指针数组和数组指针要弄明白这...指针数组本质是一数组,它的目的把相同类型的指针统一放在一数组里,与数组指针不同的是:指针数组既可以用在一维数组中也可以用在二维数组中。2:数组指针的声明方式为 int
  • 在这里一共有四概念:二数组、数组指针、指针数组和指针的指针。 下面我们一个个来进行分析。 二数组: int a[3][3] = {1,2,3,4,5,6,7,8,9}; 这概念应该都很清楚,用起来也都很顺手,a表示二数组名,同时...
  • 一维指针数组的定义形式为:“类型名 *数组标识符[数组长度]”。即有诸形如“ptr_array[i]”的指针。指针数组中的元素亦可以表示为“*(*(ptr_array+i))”。又因为“()”的优先级较“*”高,且“*”是右结合的,...
  • 指针数组、数组指针——用指针访问数组方法总结

    万次阅读 多人点赞 2019-01-14 09:51:11
    2.2.2 指向每一行的指针(指针数组方式) 2.2.3 指向整个数组的指针(数组指针方式) 3 总结 1.数组元素的访问 数组中的各元素在内存中是连续分布的,要想访问数组中某一元素,那么就必须知道其地址。 在....
  • 定义一个一维数组int a[10],其内存结构如图:   图1 在中括号[]之前的a表示数组的首地址,a+i则表示第iint型数据的地址,通过*解引用,来索引具体的数据。 2. 二维数组与指针数组、二级指针   图2 先有...
  • 1、指针数组:本质是个数组,数组中的每一个元素个指针。 2、数组指针:本质是个指针,而指针指向个数组。 二、我们该怎么区分指针数组和数组指针? 1、总共有三种表示形式:int * P[4]和int (*P)[4]和int...
  • 1、二维指针维指针也就是指针的指针,动态分配和释放如下: void fun() { int i; X **a; //分配 a = (X **)malloc(sizeof(X *) * m); //也可以写成 a = new X*[m]; for(i = 0; i a[i] = (X *)malloc(sizeof...
  • 1 #include  2  3 int main(void)  4 { ... 5 int ar[3][4]= { {7,10,-2,3}... 小结 二维指针数组定义 int(* ptr)[4] 与一维指针定义int *p 不一样 。 取出每个二维数组里面内容 *(*(ptr + i) + j)
  • 维数组数组元素存储地址的计算

    万次阅读 多人点赞 2019-01-31 08:55:59
    关于二维数组数组元素的存储地址,有同学问出了好问题。  在我的课件中,出现了下面的讲解:  a[i][j]的地址是p+(i*col+j)*d(d是数组元素所占的字节数)。  同学编程序进行验证,出问题了:  地球停止...
  • C++ 对象指针数组

    千次阅读 2019-04-21 12:27:40
    typedef Student * PStudent; PStudent *stud;//Student **stud; stud=new PStudent[5];//stud=new Student *[5];一维都是一指针 for(int k=0;...//为每一维指针new一类 代替: typedef Stu...
  • 关于用指针方式访问二维数组的问题 首先说明几种类型: ... //该语句是定义一指向数组指针,指向含4int元素一维数组。跨度为4*sizeof(int); int * q2[4]; //定义了一个数组 里面存有int *...
  • 二维数组元素指针引用 指针与一维数组和二维数组 1.定义 2.关系 3.数组指针和指针数组的区别 数组指针(也称行指针) ... //该语句是定义一个数组指针,指向含4个元素一维数组。 p=a; //将该二维数组的首地址赋给
  • *p[3]这个是一个指针数组,它所代表的意思是数组中的个元素都是一个指针变量,而(*p)[3],p是一个指针变量,表示指向一个含有3个整型元素的一维数组。 复制代码代码如下: int i,j;  int a[2][3]={3,4,5,6,7...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 83,768
精华内容 33,507
关键字:

一维对象指针数组的每个元素