婚纱网站制作,东莞seo外包公司费用,wordpress手机认证登录页面模板,郑州做网站多少钱1.什么是指针#xff1a; 指针是存放地址的地方#xff0c;是内存中最小单元的地址#xff08;编号#xff09;#xff0c;内存被分为一个个小的单元格#xff0c;每一格有一个字节。比如说int a0#xff1b;a会占据四个字节的大小#xff0c;每个字节对应单元格都有自…1.什么是指针 指针是存放地址的地方是内存中最小单元的地址编号内存被分为一个个小的单元格每一格有一个字节。比如说int a0a会占据四个字节的大小每个字节对应单元格都有自己的编号a代表着第一个单元格的地址用十六进制表示0x0000006b2d1dfa34
2.指针变量的大小 从上面我们得知指针是用来存放地址的地方所以地址的长度决定了指针变量的大小。对于64位系统每个地址长度是16位十六进制数一个十六进制位恰好可以表示4位二进制位所以需要4*16个比特位二进制位也就是4*16地址所占比特位/81字节所占比特位8字节所以在64位系统中指针变量的大小是8字节而在32位系统中也可以得知是4个字节。
3.指针类型的问题引出
在上面我们说明了指针变量是存放地址的地方在64位系统之中都是由16为二进制数构成而我们又知道指针变量有不同的类型如int*double*char*等等现在就有一个疑问指针大小是由地址长度确定的需要这么多类型的指针类型干什么呢接下来我们将对指针类型的意义进行探索。
4.不同指针类型的意义 4.1指针类型决定了指针在算数运算时移动的单位。 比如如下代码对于int*p1p11移动的单位为4个字节而char*p2p21只移动了一个字节。这样的方便之处在于可以对指针进行相应的算数运算来实现一些操作。比如数组的遍历如果指针类型与对应的数据类型不匹配的话就会导致指针所指向的地址出错对应解引用也会出错。
4.2指针类型决定指针解引用时访问的长度。比如如下代码解应用的访问主要表现在两个方面1.对于数据的修改 2.对于数据的打印。 从上面的结果可以看出char*解引用只能访问1个字节2个十六进制数而int*可以访问4个字节8个十六进制数。
注是否可以利用指针类型访问字节数相同但是指针类型不相同的指针来解引用修改数据呢比如float和int都是答案是否定的因为浮点数在内存中储存与整数不一样
5.野指针
野指针是一个非正式的术语用于描述一个指向无效内存地址的指针。这种指针可能会引发未定义的行为如程序崩溃、数据损坏等。以下几种情况可能会导致野指针的产生
1.未初始化的指针指针变量在声明后未被赋值其值是不确定的比如如下代码int* p;*p 0p指向的地址是不确定的对p解引用虽然不报错但是对于p我们无法掌控。
2.指针指向的内存被释放当使用动态内存分配如malloc创建的内存被释放如使用free后或者函数内局部变量地址作为返回值使用指向该内存的指针就变成了野指针。比如下列代码a在执行完fun函数之后就会被销毁此时再对于a进行解引用就会产生野指针。 int* fun(void)
{int a 0;return a;
}
int main()
{int* p fun();*p 20;return 0;
}
3.指针越界当指针访问数组或缓冲区之外的内存时它也可能变成一个野指针。比如如下代码 在实际使用中应该避免野指针的出现对于指向地址位置的指针常常初始化为NULL
6.指针运算 6.1.指针的关系运算指针与地址比较常用于数组中因为数组是一组连续的地址且地址由低到高这是地址比较的依据。 6.2.指针的算术运算如下面的代码通过比较地址和对指针加减整数的操作实现了数组的初始化和打印。 int arr[] {1,2,4,5,6,10,25,78,99,100};
int* p arr;
int sz sizeof(arr)/sizeof(arr[0]);
//将数组中的元素全部初始化为0
for (int i 0; p arr[sz]; p)
{*p i;
}
//此时p指向的是数组中的最后一个元素的后一个地址
//所以p--指向最后一个元素
p--;
for (; p arr[0]; p--)
{printf(%d , *p);
}6.3.指针地址之间的运算对于指向同一数组不同元素的指针地址两个指针地址差的绝对值是两者之间的元素个数。如下 列代码
int arr[10] {1,2,4,5,6,10,25,78,99,100};
printf(%d, arr[9] - arr[0]);
//打印结果为9
该特性是对于内存的直接应用。比如下列代码
int my_strlen(char* str)
{char* start str;while (*str ! \0){str;}return str - start;
}
int main()
{printf(%d, my_strlen(abcdef));return 0;
}
7.二级指针
存放一级指针变量地址的指针变量。需要注意的就是二级指针可以进行两次解引用分别对应有不同的意义。比如下列代码
int a 0,b0;
int* p a;
int** pp p;
**pp 20;//两次解引用可以访问到a的地址
*pp b; //一次解引用可以访问到b的地址
**pp 10;
printf(%d\n, a);//结果20
printf(%d, b); //结果10
8.指针数组
存放地址的数组。这里只介绍其简单的应用如下列代码将三个数组地址存放在一个指针数组中从而联系起来。
int arr[5];
int brr[5];
int crr[5];
//指针数组存放地址
int* prr[3] { arr,brr,crr };
for (int i 0; i 3; i)
{for (int j 0; j 5; j){//prr[i]代表访问prr数组中下标为i的元素地址//比如prr[0]arr,相当于直接替换//prr[0][j]arr[j]//通过指针数组将三个不相关的数组联系起来prr[i][j] 0;}
}
for (int i 0; i 3; i)
{for (int j 0; j 5; j){printf(%d , prr[i][j]);}printf(\n);
}