1.指针和地址的区别
记忆方法: 我们靠指针来区分那些没有分类的地址
指针是有类型的
地址没有类型,需要强制类型转化才能够赋值给指针变量
int* p = (int*)0x123456
2空指针
指针在使用之前必须要有初始值(初始化),否则报空指针
如果一时没有用到可以给一个null为初始值,
null和"空"不一样的概念
#include<stdio.h> #include<stdlib.h> void main(){ int* p = NULL; p = 200; printf("p的值是%d", *p); getchar(); }
把200(16机制)当做一个内存地址赋值给了指针变量,打印指针变量对应的值-->是不能访问的
总结:由于 数字比较小 系统本身已经占用了这块内存区域 然而系统本身的内存数据是不允许访问的,所以一般情况下我是不会给指针变量赋值为正数
3.多级指针---二级指针
#include<stdio.h> #include<stdlib.h> void main(){ int a = 100; int b = 200; //a变量地址 int* p = &a; //打印指针的地址 printf("p指针的地址是%#x",p); printf("a变量的地址%#x", &a); getchar(); }
p指针的地址是0xeffae4
a变量的地址0xeffae4
一般正常的情况下:3级指针
多级指针的作用: 删除链表 动态分配内存给二维数组
4.指针的运算
赋值运算
算数运算 ( + - * /)
#include<stdio.h> #include<stdlib.h> void main(){ int ids[] = { 23, 15, 67, 38, 99, 70 }; //打印数据 注意数组就是指针地址; printf("数组的地址是 : %#x\n",ids); //打印数组的第一个数据, printf("数组的第一个数是 : %#x\n ", &ids[0]); getchar(); }
总结:
ids 是一个常量的指针 存储的是数组元素第一个元素的地址
1. 数组地址 的数值和数组的第一个值的的 地址 是同一个
2.数组在内存中排列的连续不断的线性排列
#include<stdio.h> #include<stdlib.h> void main(){ int ids[] = {1,2,22,34}; printf("数组地址%#x\n", ids); printf("数组第一个数值%#x\n",&ids[0]); int* p = ids; p++; printf("p的地址是:%#x||p的数值是%d",p,*p); getchar(); }
数组地址0x23fbcc
数组第一个数值0x23fbcc
p的地址是:0x23fbd0||p的数值是23.p++ 每次向前移动sizeof(数组类型) 个 长度
5遍历数组
使用传统的方式遍历
int i = 0;
for (; i < 4; i++){
printf("数组第%d个值是%d\n",i,ids[i]);
}
使用指针的方式遍历
int* p = ids;
for (; p < ids + 4; p++){
printf("数组的值是>>%d\n", *p);
}
6.假设指针越界了会怎么半
指针递增和递减只有在数组遍历的时候才有意义
基于数组指针是线性排列的方式,有可能导致访问到其它内存区域
7数组循环赋值
1高级写法(指针写法)
//高级写法
//指针方式赋值
int* p = pds ;
//赋值
for (; p < pds + 6;p++){
*p = i;
++i;
}
//输出
int j = 0;
for (; j < 6; j++){
printf("数组第%d个值是%d\n", j, pds[j]);
}
getchar();
2普通赋值方法
int pds[6];
int i = 0;
for (; i < 6; i++){
pds[i] = i;
}
//输出
int j = 0;
for (; j < 6; j++){
printf("数组第%d个值是%d\n", j,pds[j]);
}