个人建网站大概多少钱,网站正在建设中色,网站不同时期的优化工作该怎么做,wordpress定義小工具目录 1、内存和地址
2、指针简介
与指针相关的运算符#xff1a;
取地址操作符#xff08;#xff09;
解引用操作符#xff08;间接操作符#xff09;#xff08;*#xff09;
编辑 指针变量的声明
指针变量类型的意义
指针的基本操作
1、指针与整数相加…目录 1、内存和地址
2、指针简介
与指针相关的运算符
取地址操作符
解引用操作符间接操作符*
编辑 指针变量的声明
指针变量类型的意义
指针的基本操作
1、指针与整数相加当然也可以相减
2、指针与指针相加或者相减
3、比较
野指针
1、解引用未初始化的指针
2、指针越界访问
3、指针指向的空间释放
4、如何规避野指针
1、指针初始化
2、小心指针越界 1、内存和地址
什么是内存呢我们知道计算机上CPU中央处理器在处理数据的时候需要的是数据是在内存中读取的处理后的数据也会放回内存中比如电脑上的内存是8GB/16GB/32GB等那这些内存空间是如何高效的管理的呢
其实也是把内存划分为一个个的内存单元每个内存单元的大小取一个字节。
补充计算机中常见的单位——一个比特位可以存储一个二进制的位1或者0 1byte 8bitbit-比特位byte-字节 1KB 1024byte 1MB 1024KB 1GB 1024MB 1TB 1024GB 1PB 1024TB 其实每个内存单元相当于一个学生宿舍一个字节空间里面能放8个比特位就好比一个宿舍里面住了八个人每个人就是一个比特位。 每个内存单元也都有一个编号这个编号就相当于宿舍房间的门牌号有了这个内存单元的编号CPU就可以快速找到一个内存空间。生活中我们把门牌号也叫地址在计算机中我们把内存单元的编号也称为地址。C语言中给地址起了新的名字指针。
所以我们可以理解为:
内存单元的编号地址指针
2、指针简介
指针什么是指针从根本上指针pointer是一个值为内存地址的变量或者数据对象。比如char类型变量的值是字符int类型变量的值是整数指针变量的值是地址。
与指针相关的运算符
那我们如何获得地址呢
取地址操作符
一般注解后跟一个变量名给出该变量的地址
#includestdio.h
int main()
{int a 10;a;//这里是取出a的地址的意思printf(%p, a);//p是打印地址的占位符return 0;
} 如图所示0133F70C就是a的地址特别注意的是上述代码在创建变量a的时候会向内存申请4个字节的空间用于存放整数10其中每个字节都有地址且a取出的是a所占4个字节中地址较小的字节的地址。虽然整型变量占4个字节但我们只要知道了第一个字节地址就能顺藤摸瓜访问到4个字节的数据。
我们把取到的数据地址放到指针变量存储指针变量也是一种变量这种变量就是用来存放地址的存放在指针变量中的值都会理解为地址。
解引用操作符间接操作符*
一般注解后跟一个指针名或者地址时*给出储存在指针指向地址上的值。 示例 int a10; int *paa;//这里pa左边写的是int**是在说明pa是指针变量而前面的int是在说明pa指向的是整型int类型的对象。 *pa20;//*pa等价于a,最终a的值等于20 指针变量的声明
声明指针变量时必须指定指针所指向变量的类型因为不同的变量类型占用不同的存储空间一些指针操作要求知道操作对象的大小。另外程序必须知道存储在指定地址上的数据类型。long和float可能占用相同的存储空间但是它们存储数字却大相径庭。下面是一些示例 int *pa //pa是指向int类型变量的指针 char *pb //pb是指向char类型变量的指针 float *pc //pc是指向float类型变量的指针 类型说明符表示了指针所指向对象的类型星号*表明声明的变量是一个指针。
int*pa声明的意思是pa是一个指针*pa是int类型。
指针变量类型的意义
指针变量的大小和类型无关只要是指针变量在同一个平台上大小都是一样的为什么还要各种各样的指针类型呢
其实指针类型是有特殊意义的例如以下代码
#include stdio.h
int main()
{int n 0x11223344;int* pi n;*pi 0;printf(%p, *pi);return 0;
} #include stdio.h
int main()
{int n 0x11223344;char* pc (char*)n;*pc 0;printf(%p, n);return 0;
} 从上面两个代码可以看出第一个代码会将n的四个字节全部改为0但是第二个代码只是将n的第一个字节改为0。
结论指针的类型决定了对指针解引用的时候有多大权限一次能操作几个字节指针的类型决定了指针向前或者向后走一步有多大
比如char*的指针解引用就只能访问一个字节而int*类型的解引用就能访问四个字节。
指针的基本操作
1、指针与整数相加当然也可以相减
可以使用运算符把指针和整数相加或整数与指针相加。无论哪种情况整数都会和指针所指向类型的大小以字节为单位相乘然后把结果与初始地址相加。
#include stdio.h
int main()
{
int n 10;
char *pc (char*)n;
int *pi n;
printf(%p\n, n);
printf(%p\n, pc);
printf(%p\n, pc1);
printf(%p\n, pi);
printf(%p\n, pi1);
return 0;
} 上面就是指针与整数相加的结果另外也可以看出char*类型的指针变量1跳过一个字节int*类型的指针变量1跳过了4个字节。这就是指针变量的类型差异带来的变化。
另外再举一个数组的例子
我们知道数组在内存中都是连续存放的所以只要我们知道第一个元素的地址就能顺藤摸瓜找到后面的所以元素。
#includestdio.h
int main()
{int arr[10] { 1,2,3,4,5,6,7,8,9,10 };int sz sizeof(arr) / sizeof(arr[0]);int* pst arr[0];for (int i 0;i sz;i){printf(%d , *(pst i));//这里的pi就是指针加整数}return 0;
}
2、指针与指针相加或者相减
int my_strlen(char* s)//定义一个求字符串长度的函数
{char* p s;while (*p ! \0)p;return p-s;//这里就是指针减指针
}#includestdio.h
int main()
{printf(%d, my_strlen(abc));//传参后打印结果return 0;
}
3、比较
可以使用关系运算符比较两个指针的值前提是两个指针都指向相同类型的对象。
#include stdio.h
int main()
{int arr[10] { 1,2,3,4,5,6,7,8,9,10 };int* p arr[0];int i 0;int sz sizeof(arr) / sizeof(arr[0]);while (p arr sz) //这里是指针大小的比较{printf(%d , *p);p;}return 0;
}
野指针
成因
1、解引用未初始化的指针 int* pst; //未初始化的指针 *pst5; //严重的错误 为何不行呢第二行的意思是把5存储在pst指向的位置。但是pst未被初始化未被初始化其值是一个随机值所以不知道将5存储在何处这可能不会出什么错也可能会擦写数据或代码或者导致程序崩溃。
切记创建一个指针时系统只分配了存储指针本身的内存并未分配存储数据的内存。因此在使用指针之前必须先用已分配的地址初始化它。
#include stdio.h
int main()
{
int *p;//局部变量指针未初始化默认为随机值
*p 20;
return 0;
}
2、指针越界访问
#include stdio.h
int main()
{
int arr[10] {0};
int *p arr[0];
int i 0;
for(i0; i11; i)
{
//当指针指向的范围超出数组arr的范围时p就是野指针
*(p) i;
}
return 0;
}
3、指针指向的空间释放
#include stdio.h
int* test()
{
int n 100;
return n;
}
int main()
{
int*p test();
printf(%d\n, *p);
return 0;
}
4、如何规避野指针
1、指针初始化
如果明确知道指针指向哪里就直接赋值地址如果不知道指针应该指向哪里可以给指针赋值NULLNULL是C语言中定义的一个标识符常量值是0,0也是地址这个地址是无法使用的读写该地址会报错。
#include stdio.h
int main()
{
int num 10;
int*p1 num;
int*p2 NULL;
return 0;
}
2、小心指针越界
一个程序向内存申请了哪些空间通过指针也就只能访问哪些空间不能超过访问范围超过了就是越界访问。 今天的笔记到此结束了