一、指针变量
1.1代码分析
先把代码贴上来进行分析。
笔者在写代码时候会加上头文件stdlib和代码system("pause");这是为了防止闪屏,在学校时候老师有教过其他写法,但是还是觉得笔者这样写比较容易记得住。
1#include<stdio.h> 2#include<stdlib.h> 3 4int main() { 5 int var = 20; 6 int *p; //定义指针变量 7 p = &var; //把存储var变量的地址赋值给指针*p 8 printf("Address of var is :%p\n", &var); 9 printf("Address stores in p:%p\n", p); 10 printf("Value of var is :%d\n", *p); 11 12 int x = 30; 13 int *pInt = &x; 14 printf("%d\n", pInt); 15 printf("%d\n", (pInt + 1)); 16 system("pause"); 17 return 0; 18}
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代码分析
1#include<stdio.h> 2#include<stdlib.h> 3 4int main() { 5 //One-Dimensional ArrayList Method-One 6 int arr[] = { 1,2,3,4,5,6,7 }; 7 int *pInt = arr; 8 for (int i = 0; i < 7; i++) { 9 printf("%d=%d\t", arr[i], *(pInt + i)); 10 } 11 printf("\n"); 12 //Method-Two 13 for (int i = 0; i < 7; i++) { 14 printf("%d\t", pInt[i]); 15 } 16 printf("\n\n"); 17 18 //Two-Dimensional ArrayList Method-One 19 int SecArr[3][3] = { 1,2,3,4,5,6,7,8,9 }; 20 int(*pSec)[3] = SecArr; 21 for (int i = 0; i < 3; i++) { 22 for (int j = 0; j < 3; j++) { 23 printf("%d\t", *(*(pSec + i)+j)); 24 } 25 printf("\n"); 26 } 27 printf("\n"); 28 29 //Method-Two 30 int SecArrayList[3][3] = { 1,2,3,4,5,6,7,8,9 }; 31 int(*pSecArr)[3] = SecArrayList; 32 for (int i = 0; i < 3; i++) { 33 for (int j = 0; j < 3; j++) { 34 printf("%d\t", *(pSecArr[i] + j)); 35 } 36 printf("\n"); 37 } 38 39 system("pause"); 40 return 0; 41}
首先我们定义一个长度为7的一维数组,分别存放整数从1到7,数组的首地址,即为数组名arr。定义一个一级指针为pInt且将数组首地址赋值给指针变量pInt。如下图所示。
数组其实是一段内存。如图,指针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]看做整体。
