移动端网站开发流程,网站设计实验,无锡公司做网站,查商标是否被注册在哪里查文章目录 目录1. 指针是什么2. 指针变量的类型2.1 指针变量-整数2.2 指针变量的解引用 3. 野指针3.1 野指针成因3.2 如何规避野指针 4. 指针运算4.1 指针-整数4.2 指针-指针4.3 指针的关系运算 附#xff1a; 目录
指针是什么指针变量的类型野指针指针运算指针和数组二级指针… 文章目录 目录1. 指针是什么2. 指针变量的类型2.1 指针变量-整数2.2 指针变量的解引用 3. 野指针3.1 野指针成因3.2 如何规避野指针 4. 指针运算4.1 指针-整数4.2 指针-指针4.3 指针的关系运算 附 目录
指针是什么指针变量的类型野指针指针运算指针和数组二级指针指针数组 1. 指针是什么 指针是内存中一个最小单元1个字节的编号也就是地址平时口语中说的指针通常指的是指针变量是用来存放内存地址的变量存放在指针变量中的值都被当成地址处理 总结 指针就是地址口语中说的指针通常指的是指针变量
#include stdio.hint main()
{int a 100;int * pa a;//pa是专门用来存放地址指针的这里的pa就被称为指针变量//指针变量在32位平台下是4个字节//指针变量在64位平台下是8个字节//int arr[10];//printf(%p, a);return 0;
}注
经过仔细的计算和权衡我们发现一个字节给一个对应的地址是比较合适的。对于32位的机器假设有32根地址线那么假设每根地址线在寻址的时候产生高电频高电压和低电频低电压就是1或者0那么32根地址线会产生2的32次方个地址每个地址标识一个字节那我们就可以给 2^32Byte 2^32/1024KB 2^32/1024/1024MB2^32/1024/1024/1024GB 4GB 4G的空间进行编址64位机器同理。在32位的机器上地址是32个0或者1组成二进制序列那地址就得用4个字节的空间来存储所以一个指针变量的大小就应该是4个字节。那如果在64位机器上如果有64个地址线那一个指针变量的大小是8个字节才能存放一个地址。
#include stdio.hint main()
{printf(%d\n, sizeof(char*));printf(%d\n, sizeof(short*));printf(%d\n, sizeof(int*));printf(%d\n, sizeof(long*));printf(%d\n, sizeof(float*));printf(%d\n, sizeof(double*));return 0;
}2. 指针变量的类型 char * pc NULL; short * ps NULL; int * pi NULL; long * pl NULL; float * pf NULL; double * pd NULL; 这里可以看到指针变量的定义方式是 type *
其实 char* 类型的指针变量是为了存放 char 类型变量的地址。 short* 类型的指针变量是为了存放 short 类型变量的地址。 int* 类型的指针变量是为了存放 int 类型变量的地址。
但是指针变量的大小又和指针变量的类型无关那么指针变量的类型的意义是什么呢
2.1 指针变量±整数
#include stdio.hint main()
{int a 0x11223344;//0x开头的是16进制数字int * pa a;char * pc a;printf(%p\n, pa);//010FFE7Cprintf(%p\n, pc);//010FFE7Cprintf(%p\n, pa1);//010FFE80printf(%p\n, pc1);//010FFE7Dreturn 0;
}总结 指针变量的类型决定了指针向前或者向后走一步有多大距离。
2.2 指针变量的解引用
#include stdio.hint main()
{int a 0x11223344;//0x开头的是16进制数字char * pa a;*pa 0;return 0;
}#include stdio.hint main()
{int a 0x11223344;int* pa a;*pa 0;return 0;
}总结 指针变量的类型决定了对指针变量解引用的时候有多大的权限能操作几个字节比如 char* 的指针变量解引用就只能访问一个字节而 int* 的指针变量解引用就能访问四个字节。
3. 野指针 概念 野指针就是指针指向的位置是不可知的随机的、不正确的、没有明确限制的 3.1 野指针成因
指针未初始化
#include stdio.hint main()
{int* p;//局部变量不初始化的时候内容是随机值*p 20;printf(%d\n, *p);return 0;
}指针越界访问
#include stdio.hint main()
{int arr[10] { 0 };int * p arr;int i 0;for (i 0; i 11; i){//当指针指向的范围超出数组arr的范围时p就是野指针*(p) i;}return 0;
}指针指向的空间释放
放在动态内存开辟的时候讲解这里可以简单提示一下。
#include stdio.hint * test()
{int a 110;return a;
}int main()
{int* p test();printf(%d\n, *p);return 0;
}3.2 如何规避野指针
指针初始化小心指针越界指针指向空间释放及时置NULL避免返回局部变量的地址指针使用之前检查有效性
#include stdio.hint main()
{int a 10;int* p a;int* ptr NULL;//ptr是一个空指针没有指向任何有效的空间这个指针不能直接使用//int* ptr2;//野指针if (ptr ! NULL){//使用}return 0;
}4. 指针运算
4.1 指针±整数
#include stdio.hint main()
{int arr[10] { 0 };//不使用下标访问数组int* p arr[0];int i 0;int sz sizeof(arr) / sizeof(arr[0]);for (i 0; i sz; i){*p i;p;//p p 1}p arr;for (i 0; i sz; i){printf(%d , *(p i));//p i}/*for (i 0; i sz; i){printf(%d , arr[i]);}*/return 0;
}#define N_VALUES 5int main()
{float values[N_VALUES];float *vp;//指针-整数指针的关系运算for (vp values[0]; vp values[N_VALUES]; ){*vp 0;}return 0;
}注
//int arr[10]
//int* p arr;
//*(pi) arr[i]
//*(arri) arr[i]//arr[i] *(arri) *(iarr) i[arr]int main()
{int arr[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };int i 0;for (i 0; i 10; i){printf(%d , i[arr]);//[] 操作符}//23 -- 32//arr[i] -- i[arr]return 0;
}4.2 指针-指针
//地址-地址
//指针-指针#include stdio.hint main()
{int arr[10] { 0 };printf(%d\n, arr[9] - arr[0]);//9printf(%d\n, arr[0] - arr[9]);//-9return 0;
}//指针-指针得到的数值的绝对值是指针和指针之间的元素个数之前我们学习过如何通过自己的函数来实现计算字符串长度
#include stdio.hint my_strlen(char* s)
{int count 0;while (*s ! \0){count;s;}return count;
}int main()
{char arr[] abcdef;int len my_strlen(arr);printf(%d\n, len);return 0;
}#include stdio.hint my_strlen(char* s)
{if (\0 *s){return 0;}else{return 1 my_strlen(s 1);}}int main()
{char arr[] abcdef;int len my_strlen(arr);printf(%d\n, len);return 0;
}其实这也能通过指针-指针来实现
#include stdio.hint my_strlen(char* s)
{char* start s;while (*s ! \0){s;}return s - start;
}int main()
{char arr[] abcdef;int len my_strlen(arr);printf(%d\n, len);return 0;
}#include stdio.hint my_strlen(char* s)
{char* start s;while (*s)//a b c d e f \0 - 0{s;}return s - start;
}int main()
{char arr[] abcdef;int len my_strlen(arr);printf(%d\n, len);return 0;
}#include stdio.hint my_strlen(char* s)
{char* start s;while (*s){;}return s - start - 1;
}int main()
{char arr[] abcdef;int len my_strlen(arr);printf(%d\n, len);return 0;
}注
#include stdio.hint main()
{int arr[10] { 0 };char ch[5] { 0 };//指针和指针相减的前提是两个指针指向了同一块空间printf(%d\n, ch[4] - arr[0]);//errreturn 0;
}4.3 指针的关系运算
#define N_VALUES 5int main()
{float values[N_VALUES];float *vp;for(vp values[N_VALUES]; vp values[0];){*--vp 0;}return 0;
}这段代码也可以这样写
#define N_VALUES 5int main()
{float values[N_VALUES];float *vp;for(vp values[N_VALUES-1]; vp values[0];vp--){*vp 0;}return 0;
}实际在绝大部分的编译器上是可以顺利完成任务的然而我们还是应该避免这样写因为标准并不保证它可行。
标准规定 允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。 附