1.指针和地址的区别
指针:指针有类型。
地址:没有类型,需要强制类型转换才能赋值给指针变量。
int *p = (int *)0x33fc32;
2.空指针
注意 :指针使用之前必须要有初始化值(初始化)。
void main(){
int *p = NULL;
//NULL地址
printf("地址:%#x",p);
//取值:0x00000000 因为这个是操作系统所使用,
//一般应用程序不能够访问
printf("值:%d",*p);
//判断NULL
if(p == NULL){
printf("为NULL。。。。。");
}
//把10当做一个内存地址赋值给了指针变量(16进制)
p = 200;
//打印指针变量对应的值
printf("%d\n",*p);
//总结:由于数字比较小,系统本身已经占用了这块内区
//域,系统本身内存数据不允许访问所以一般情况下,我
//们不会直接给指针变量赋值为整数。
getchar();
}
3.多级指针
指针变量也是变量,也占用内存空间,同样有地址,因此可以用一个指针指向它,这就称之为二级指针。正常情况下最多就是三级指针。
多级指针的作用:删除链表、动态分配内存给二维数组等等。。。
void main(){
int a = 100;
int b = 200;
//a变量的地址
int *p1 = &a;
//打印指针的地址
printf("p1的地址:%#x\n",p1);
//二级指针
int **p2 = &p1;
//p2保存的数据是p1的地址,*p2上的数据是p1地址值,
//p1保存的数据是a的地址,**p2实际上就是a的值。
**p2 = 999;
printf("二级指针地址:%#x\n",&p2);
printf("a的值:%d",a);
getchar();
}
4.指针的运算(赋值运算、算数运算)
void main(){
//赋值运算
int a = 44;
int *p = &a;
//算术运算(+ - * /)
//数组:(1)ids常量指针,存储的是数组的首地址
//(2)数组在内存中排列是连续不断的(线性排列)
int ids[] = {23,53,24,63,62,73}
//打印数组
printf("数组:%#x\n",ids);
//数组第一个元素地址
printf("数组第一个元素的地址:%#x\n",&dis[0]);
//p++每次向前移sizeof(数据类型)个字节
int *P = ids;
p++;
printf("p的地址:%#x p的值:%d\n", p,*p);
//遍历数组
//传统方法
int i = 0;
for(;i<6;i++){
printf("值:%d\n",ids[i]);
}
//通过指针遍历 注意:让指针递增或者递减,一般情况下只
//有在数据遍历的时候才有意义,基于数组在内存中是线性排
//列的,有可能会导致访问到其他的内存区域(如:系统程序,
//第三方程序)
for(;p<ids+6;i++){
printf("地址:%#x 值:%d\n",p,*p);
}
getchar();
}
5.指针运算(通过使用指针循环给数组赋值)
void main(){
int ids[6] ;
int *p = ids;
//传统赋值
int i = 0;
int j = 0;
/**
* for(;i<6;i++){
* ids[i] = i;
* }
*/
//指针方式赋值
for(;p<ids+6;p++){
*p = i;
i++;
}
//输出
for(;j<6;j++){
printf("值:%d\n",ids[j]);
}
getchar();
}
6.数组内部指针的加减
void main(){
int ids[6] = {24,34,25,16,34,84};
int *p = ids;
p = p+4;
printf("值:%d 地址:%#x\n",*p,p);
p = p - 1;
printf("值:%d 地址:%#x\n",*p,p);
getchar();
}
7.指针大小比较
1.指针大小比较:都是在遍历数组的时候运用,其他情况下没什么用。
2.指针相等比较:指针地址相等,并不代表值相等,因为指针有类型。
void main(){
int *p1 = (int *) 0x006732;
double p2 = (double*)0x006732;
}
8.指针和数组的几种写法
void main(){
int ids[6] = {24,34,25,16,34,84};
int i = 0;
for(;i<6;i++){
printf("%d %#x\n",ids[i],&ids[i]);
//分析取地址:ids是首地址
//ids+0等价于&ids[0]
//ids+1等价于&ids[1]
//以此类推.....
//总结:ids+i等价于&ids[i]
//分析取值
//*(ids+0)等价于ids[0]
//*(ids+1)等价于ids[1]
//以此类推.....
//总结:*(ids+i)等价于ids[i]
printf("%d %#x\n",*(ids+i),ids+i);
}
printf("\n\n");
int *p = ids;
int i = 0;
for(;i<6;i++){
printf("%d %#x\n ",ids[i],&ids[i]);
printf("%d %#x\n ",*(p+i),p+i);
}
}
9.指针和二维数组
void main(){
//两行三列二维数组
int ids[2][3] = {32,43,24,53,64,63};
//遍历二维数组:外层循环控制行,内层循环控制列。
int i = 0;
for(;i<2;i++){
int j = 0;
for(;j<3;j++){
printf(“值:%d 地址:%#x”,
ids[i][j],&ids[i][j]);
}
printf("\n");
}
printf("\n");
printf("\n");
//地址相同,不代表值相同。
//ids代表的是一个行指针,指向一个有三个元素数组,大小
//12
//&ids代表的是一个二维数组指针,当前二维数组6个元素,
//长度24。
//*ids代表的是一个指向该二维数组的数据类型的指针(相当
//于首地址:ids[0][0]
printf("ids:%#x &ids:%#x *ids:%#x\n",ids,&ids,*ids);
printf("长度:%d 长度:%d 长度:%d\n",sizeof(*ids),sizeof(*&ids),sizeof(**ids));
printf("值:%d\n",**ids);
//打印第二行第三列
printf(“%d\n”,ids[1][2]);
//推导过程分析
//ids+0代表第一行 第一行的第一个值
//ids+1代表第二行 第二行的第一个值
//以此类推 ids+i
//取每一行第一个元素的指针:*(ids+i)
//取第一行第一个指针:*ids+0
//取第一行第二个指针:*ids+1
//取第一行第三个指针:*ids+2
//以此类推 *ids+j
//取第一行第二个指针:*(ids+0)+1;
//取第二行第二个指针:*(ids+1)+1;
//以此类推:*(ids+i)+j (这个公式获取的是地址,
//是一个指针变量)
//值:*(*(ids+i)+j)
printf("%d",*(*(ids+1)+2));
getchar();
}