基础

示例一:

1
2
3
4
5
6
int arr [5] = {1,2,3,4,5} ;
int * p1 = &arr ;
int * p2 = arr ;

printf("*p1:%d\n" , *(p1+1)) ;
printf("*p2:%d\n" , *(p2+1)) ;

C-array-pointer1

示例二:

1
2
3
4
5
6
int arr [5] = {1,2,3,4,5} ;
int * p2 = &arr[2] ;

printf("*p2‐1:%d\n" , *(p2‐1)) ;
printf("*p2:%d\n" , *p2) ;
printf("*p2+1:%d\n" , *(p2+1)) ;

以上代码是通过指针 p2 来访问数组中的元素。一开始定义p2并初始化让指针p2 指向数组中第3个元素的地址。当我们使用p2 进行指针加减运算的时候 ,由于指针是整型的,可以访问到数组中的下一个元素以及上一个元素。

数组指针

概念:专门用来指向一个数组的指针。

1
2
3
4
5
6
7
8
9
10
int * p ;
int (* p) [5] ; //定义一个 名为p 的指针,

//并且确定他指向的类型为int [5] ,一个拥有5个元素的整型数组4
int arr [5] = {1,2,3,4,5} ;
int (*p) [5] = arr ;

printf("arr:%p\n" , &arr );
printf("%p‐‐‐%d\n" ,p , (*p)[2] ); // 3 * p ==> arr
printf("%p‐‐‐%d\n" , p+1 , (*(p+1))[2] ); // 已经越界访问

注意:
以上代码中 p指向的是 一个整型数组并有5个元素。 因此在对p 进行加减运算时, 是加减一个数组。

指针数组

概念:专门用来存放指针的数组,称为指针数组。

1
2
3
4
5
6
7
8
9
10
11
12
13
int a = 100 ;
int b = 250 ;
int c = 550 ;
int d = 256 ;
int e = 998 ;

int * p [5] = {&a, &b , &c , &d , &e} ; // 定义一个名字为 p的数组, 并且确定该数组中用来存放int * 整型地址


for (size_t i = 0; i < 5; i++)
{
printf("*p[%d]:%d \n" , i , *(p[i]) ); // p[0] ‐‐> &a
}

理解题

  1. 题 1

    C-array-pointer2

  2. 题 2

    C-array-pointer3

    &b—>b—>*b—>**b

    整个数组的地址—>第一个元素({1,2,3,4})的地址—>“1“的地址—>“1”的值

    补充:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    printf("**(b+1):%d\n", **(b + 1));  // 打印5
    printf("*(*(b+2)+2):%d\n", *(*(b + 2) + 2)); // 打印11

    // 使用指针来访问二维数组的每一个元素,打印所有
    for (size_t i = 0; i < 12; i++)
    {
    printf("%d\t", *((*b) + i));
    }

    // 使用数组来访问二维数组
    for (size_t i = 0; i < 3; i++)
    {
    for (size_t j = 0; j < 4; j++)
    {
    printf("b[%d][%d]:%d\t", i, j, b[i][j]);
    }
    }
  3. 题 3

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #include <stdio.h>
    int main(void)
    {
    int arr[] = { 1, 3, 5, 7, 9};
    int i, *p = arr, len = sizeof(arr) / sizeof(int);
    for(i=0; i<len; i++)
    {
    //   * 和 ++ 得优先级是同级的 , 又因为当前这一级的结合性是从右往左 , 因此先 p++  , 但是是后缀,所以先预算再++

    printf("%d\n", *p++ );   // 先运算(*p)得到 1  , 然后再(p++)地址+1
    printf("%d\n", (*p)++ );  // 先得到p得内容  3 , 然后再对3进行自加
    for (size_t j = 0; j < len ; j++)
    {
    printf("arr[%d]:%d\t" , j , arr[j]);
    }
    printf("\n");
    }

    printf("\n");
    return 0;
    }

    注意:

    • 题①中: p=&arr; p 是一个地址,为整个数组的首地址,相当于&arr。解一次引用,即* p 则为数组首元素的地址。

    • 题③中: * p=arr; arr 为数组首元素的地址,p 指向的是首元素的首地址 (p 只是一个普普通通的整型指针),*p 意思为解一次引用,即第一个元素的值。—> 当我们使用 *p 解引用指针 p 时,我们获取的是指针 p 所指向内存位置的值,p 是指向整型数组的指针,所以 *p 将获取数组中的一个整数值。

  4. 题 4

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <stdio.h>
    int main(void)
    {
    int a = 1, b = 2, c = 3;
    int *arr[3] = {&a, &b, &c};//整型指针数组
    int **parr = arr; // 第一部分 *p , 第二部分 int * 说明类型   为指针类型   +1 则+1个指针类型 8字节(64)

    //    arr[0]  --> &a   *&a --> a
    printf("%d, %d, %d\n", *arr[0], *arr[1], *arr[2]);
    printf("%d, %d, %d\n", **(parr+0), **(parr+1), **(parr+2));
    return 0;
    }
  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
    #include <stdio.h>
    int main(void)
    {
    char *lines[5] =     //字符指针数组(里面的字符串是以 `char*` 类型的指针形式存在的)
    {
    "COSC1283/1984",
    "Programming",
    "Techniques",
    "is",
    "great fun"
    };

    char *str1 = lines[1];        
    char *str2 = *(lines + 3);
    char c1    = *(*(lines + 4) + 6);  
    char c2    = (*lines + 5)[5];  
    char c3    = *lines[0] + 2;

    printf("str1 = %s\n", str1);  
    printf("str2 = %s\n", str2);  
    printf("c1   = %c\n", c1);    
    printf("c2   = %c\n", c2);    
    printf("c3   = %c\n", c3);    
    return 0;
    }

    C-array-pointer4

  6. 题 6

    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    #include <stdio.h>
    int main(void)
    {
    int i;
    int num;
    int (*p)[5] = NULL;  //数组指针  
    int arr[5] =  {5,2,4,5,7};
    p = &arr;

    printf("=====================================\n");
    num = sizeof(arr)/sizeof(arr[0]);
    for(i=0;i<num;i++)
    {
    printf("*p[%d] = %d\n",i,*p[i]);
    }

    printf("=====================================\n");
    for(i=0;i<num;i++)
    {
    printf("*(p+%d) = %p\n",i,*(p+i));  
    }

    printf("=====================================\n");
    for(i=0;i<num;i++)
    {
    printf("p[%d] = %p\n",i,p[i]);    
    }

    printf("=====================================\n");
    for(i=0;i<num;i++)
    {
    printf("(*p)[%d] = %d\n",i,(*p)[i]);
    }
    return 0;
    }

    C-array-pointer5

更多

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//程序段一
int arr[] = { 1, 3, 5, 7, 9};
int *p = &arr[2];  // p只是一个普普通通的整型指针, 并指向的 数据5 的地址,是一个地址
// arr[2] 是数据 5 , & 则把数据5 的地址进行取出
printf("%d, %d, %d, %d, %d\n", *(p-2), *(p-1), *p, *(p+1), *(p+2) );
//*p解一次引用,则打印出1,3,5,7,9


//程序段二
int (*p)[5] = NULL; //数组指针
int arr[5] = {1,2,4,5,7};
p = &arr; // p指向整个数组的地址
printf("p    = %p\n",p);        //&arr,地址
printf("*p   = %p\n",*p );      //解一次引用,数组首元素的地址


//程序段三
int arr[] = { 1, 3, 5, 7, 9};
int *p = arr; //p只是一个普普通通的整型指针, 并指向的数组首元素的地址(arr)
printf("%d\n", *p); //*p,解一次引用,得到数组首元素的值,即 1