概念:
指针:指针就是地址
数组:存储多个相同类型数据的集合
注意:
- 数组越界问题
- 数组作为参数传递,不仅需要地址,还需要长度
指针:
int a = 10;
int b = 20;
int *p; // 定义整型指针( 地址) 变量
p = &a; //”&” 取地址符,&a 取a 的地址
int *p1 = &a; // 等同p
*p = 100; //*p: 对p 解引用, 即为a=100;
p = &b; //p 赋值为b 的地址
*p = 200; //b = 200;
int **pp = &p; // 二级指针变量pp 赋值为p 的地址
*pp = &a; //p = &a;
**pp = 1000; //a = 1000;
*pp = &b; **pp = 2000;//b = 2000;
一、定义指针变量:类型 * 变量名;
如:int *p1, *p2;
注意: 指针变量在32 位平台(X86) 为4 个字节
在64 位平台(X64) 为8
二、两个 和指针相关的 运算符:
(1) & & 取地址运算符。
&a 是变量a 的地址
(2) * 指针运算符(“间接访问”运算符)
如果: p 指向变量a , 则*p 就代表a 。
k=*p; ( 把a 的值 赋给k)
*p=1; ( 把1 赋给a)
三、可以用一个指针变量指向一个数组元素
int a[10]={1,3,5,7,9,11,13,15,17,19};
int *p;
p=&a[0];
注意:这里数组名a不代表整个数组,只代表数组首元素的地址。
“p=a; ”的作用是“把a数组的首元素的地址赋给指针变量 元素的地址赋给指针变量p”而不是“把数组 不是“把数组a 各元素的值赋给p”。
四、引用一个数组元素,可用下面两种方法:
(1) 下标法,如a[i] 形式
(2) 指针法,如*(a+i) 或*(p+i)
其中a 是数组名,p 是指向数组元素的指针变量,其初值p=a
两个重要的表达式:
- p[i] == *(p+i);
- *(arr+i) == arr[i]
五、 用数组名作函数参数时,
因为 实参数组名代表该数组首元素的地址 ,
形参应该是一个指针变量
注:C 编译都是将形参数组名作为指针变量来处理的
六、指针和数组的不同:
1、大小不同
指针: 指针变量在32 位平台(X86) 为4 个字节
在64 位平台(X64) 为8个字节
数组所占存储空间的内存:sizeof(数组名)
数组的大小:sizeof(数组名)/sizeof(数据类型)
2、存储方式不同
指针:它可以指向任何类型的数据。
指针的类型说明了它所指向地址空间的内存。
由于指针本身就是一个变量,它所存放的也是变量,
所以指针的存储空间不确定。
数组:在内存中是连续存放的,开辟一块连续的内存空间。
数组是根据数组的下标进行访问的,
多维数组在内存中是按照一维数组访问的,
只是在逻辑上是多维的。
数组的存储空间在静态存储区或栈上。
3、指针可以++,数组名不可以。
七、指针的类型强转
int main()
{
int arr[5] = {1,2,3,4,5};
int *p1 = (int *)(&arr+1);
printf("%d\n",p1[-2]); //1
int *p2 = (int *)((int *)&arr+1);
printf("%x\n",p2); //2
int *p3 = (int *)((int )&arr+1);
printf("%x\n",p3); //3
retuen 0;
}
- int *p1 = (int *)(&arr+1);
printf("%d\n",p1[-2]);
// p[i] == *(p+i) == *(p-2)
- int *p2 = (int *)((int *)&arr+1);
printf("%x\n",p2); //p2=2
- int *p3 = (int *)((int )&arr+1);
printf("%x\n",p3); //p3=200 0000