一、指针变量
1.1代码分析
先把代码贴上来进行分析。
笔者在写代码时候会加上头文件stdlib和代码system("pause");这是为了防止闪屏,在学校时候老师有教过其他写法,但是还是觉得笔者这样写比较容易记得住。
#include<stdio.h>
#include<stdlib.h>
int main() {
    int var = 20;
    int *p;        //定义指针变量
    p = &var;    //把存储var变量的地址赋值给指针*p
    printf("Address of var is :%p\n", &var);
    printf("Address stores in p:%p\n", p);
    printf("Value of var is :%d\n", *p);
    int x = 30;
    int *pInt = &x;
    printf("%d\n", pInt);
    printf("%d\n", (pInt + 1));
    system("pause");
    return 0;
}1.2使用指针时候,会频繁进行如下操作:
(1)定义指针变量, (2)把存储刚刚定义的变量如var=20的地址,赋值给指针变量, (3)访问指针变量中可用的地址的值。 指针变量定义形式:数据类型 指针变量名称,比如上面的int p。 指针变量的使用:如 *p=&a**,通过取地址符&,获取 a 的地址,赋值给指针变量。 通过指针来获取地址中存储的内容:在打印中直接使用 *p。
1.3指针与整数的加减运算:
指针变量的自增自减运算。指针加 1 或减 1 运算,表示指针向前或向后移动一个单元(不同类型的指针,单元长度不同)。这个在数组中非常常用。 指针变量加上或减去一个整形数。和第一条类似,具体加几就是向前移动几个单元,减几就是向后移动几个单元。
输出的结果如图:
这里要说一点就是,printf打印的时候,%x和%p,%d都可以打印出来内存地址,但是%x会把地址开头的一串0去掉,%p不会,而%d则是为了方便直观的观察指针指向地址的变化。
二、一级指针和一维、二维数组
2.1.1代码分析
#include<stdio.h>
#include<stdlib.h>
int main() {
    //One-Dimensional ArrayList Method-One
    int arr[] = { 1,2,3,4,5,6,7 };
    int  *pInt = arr;
    for (int i = 0; i < 7; i++) {
        printf("%d=%d\t", arr[i], *(pInt + i));
    }
    printf("\n");
    //Method-Two
    for (int i = 0; i < 7; i++) {
        printf("%d\t", pInt[i]);
    }
    printf("\n\n");
    //Two-Dimensional ArrayList Method-One
    int SecArr[3][3] = { 1,2,3,4,5,6,7,8,9 };
    int(*pSec)[3] = SecArr;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            printf("%d\t", *(*(pSec + i)+j));
        }
        printf("\n");
    }
    printf("\n");
    //Method-Two
    int SecArrayList[3][3] = { 1,2,3,4,5,6,7,8,9 };
    int(*pSecArr)[3] = SecArrayList;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            printf("%d\t", *(pSecArr[i] + j));
        }
        printf("\n");
    }
    system("pause");
    return 0;
}首先我们定义一个长度为7的一维数组,分别存放整数从1到7,数组的首地址,即为数组名arr。定义一个一级指针为pInt且将数组首地址赋值给指针变量pInt。如下图所示。
 数组其实是一段内存。如图,指针pInt指向的地址为数组的首地址,然后,我们就进行循环遍历了。这里用了两种方法。
第一种如One-Dimensional Method-One中所写,因为已经对指针变量进行赋值操作,可以从首地址开始,对指针进行移动,从元素1移动元素2,随着每次循环,再移动到3这样,然后再移动。
第二种方法,如One-Dimensional Method-Two所写,因为指针变量可以这里当做数组名使用,直接用pInt[i]作为arr[i]来使用。
数组其实是一段内存。如图,指针pInt指向的地址为数组的首地址,然后,我们就进行循环遍历了。这里用了两种方法。
第一种如One-Dimensional Method-One中所写,因为已经对指针变量进行赋值操作,可以从首地址开始,对指针进行移动,从元素1移动元素2,随着每次循环,再移动到3这样,然后再移动。
第二种方法,如One-Dimensional Method-Two所写,因为指针变量可以这里当做数组名使用,直接用pInt[i]作为arr[i]来使用。
二维数组
 如上面代码中
如上面代码中    //Two-Dimensional ArrayList Method-One部分。道理如上面的一维数组如出一辙,定义二维数组,定义指针变量,因为一维数组有int  *pInt = arr;二维数组时候也成立,因此pSec[3] = SecArr[3][3],那么,int(*pSec)[3] = SecArr;就容易理解了。在循环遍历时候如上图,记住一维数组可以理解成为一行字,二维数组就是一页字,同理三维数组就是一书。这样比喻,会更加容易理解。类似的,*(*(pSec + i)+j)可以把*(pSec + i)看做整体。*(pSecArr[i] + j)可以把pSecArr[i]看做整体。

 
  
  
  
 
 
  
 
 
 