【C语言6】指针 文章目录6. 指针6.1 指针基础6.1.1 指针变量的定义6.1.2 指针变量的初始化和赋值6.1.3 指针运算符6.2 指针的算数运算6.3 指针作为函数参数6.4 指针和数组6.4.1 指针和一维整型数组6.4.2 指针和一维字符型数组6.4.3 数组指针6.4.4 指针和二维数组6.4.5 指针数组6.5 二级指针6.6 指针函数6.7 函数指针6.8 const修饰的指针6.9 void*指针此处为C语言汇总版: 【C语言md编辑器版】从0基础开始到熟练掌握完整篇,共9部分6. 指针内存程序运行时可以访问到的内存存储空间计算机为了方便对内存的管理以字节为单位对内存进行了编号。地址计算机管理内存时给内存的编号。指针指针即为地址地址即为指针指针指向了一个具体的空间。指针变量变量保存地址的变脸需要占用内存空间。6.1 指针基础6.1.1 指针变量的定义指针变量保存的地址为指针指向数据的首地址。基类型*变量名基类型该指针指向空间存储数据的数据类型。(例如int、char、float、构造数据类型…)*类型说明符说明后面的变量是指针。变量名遵循标识符的命名规则。一般以p开头没有强制要求sizeof(指针)在64位计算机系统下占8字节。在32位计算机系统下占4字节。6.1.2 指针变量的初始化和赋值野指针未初始化或赋值的一个指针或指向一个已经释放内存空间的指针。避免野指针对指针定义初始化为空指针NULL在指针定义时直接赋值。#defineNULL(void*)0;//万能指针NULL6.1.3 指针运算符*指针运算符用来访问指针变量指向的内存空间的数据。*指针变量——指针降级为变量类型——基类型的变量。int*p;p ——int**p ——int注意*指针运算符不可以用于普通变量只能放在指针变量的前边。*指针变量访问指针变量指向的数据该表达式降级为变量类型——基类型的变量。*指针变量访问的字节数取决于定义该指针时的基类型。类型访问大小char *p1字节int *p4字节double *p8字节取地址运算符变量只能给一个变量取地址不能给常量或表达式取地址。给某个变量取地址时获取的是这个变量首字节的地址。6.2 指针的算数运算 - * / % -- * / %对指针运算毫无意义-指针1-指针2表示两个指针之间间隔的元素个数地址值之间的字节差/sizeof基类型指针1表示从当前地址向后偏移sizeof基类型字节。--指针-1表示从当前地址向前偏移sizeof基类型字节。char*p;p1;//向后偏移一个字节。int*p;p1;// 向后偏移一个字节。6.3 指针作为函数参数被调函数中想要修改主调函数中定义的变量必须传递该变量的地址;被调函数中想要使用主调函数中定义的变量可以传递值也可以传递地址。被调函数想要返回多个结果时可以传递主调函数定义的变量的地址地址指向的空间可以保存被调函数得到的结果。6.4 指针和数组6.4.1 指针和一维整型数组数组的数组名为数组的首元素地址。注意数组名为地址常量不可赋值不可移动。一维整型数组作为参数传递voidprint_array(inta[],intlen){}voidprint_array(int*pa,intlen){}6.4.2 指针和一维字符型数组charstr[32]{hello};strstr[0]char*--------*strstr[0]str1str[1]char*--------*(str1)str[1]...strnstr[n]char*--------*(strn)str[n]str1;指针向内存高地址偏移sizeof(char)字节数 str-1;指针向内存低地址偏移sizeof(char)字节数char*mystrcpy(char*dst,constchar*src){char*rdstdst;while(*src!\0){*dst*src;dst;src;}*dst\0;returnrdst;}注意const在这起到提高安全性的作用保证源不会发生改变。6.4.3 数组指针本质是一个指针指向数组整体的指针。基类型(*指针名)[常量];//数组的指针。int(*指针名)[5];//定义了一个指向5个整型元素的数组的指针。inta[5]{1,2,3,4,5};a:首元素地址——a[0]——int*a:数组的指针——int(*)[5];a1:数组指针1——偏移整个数组大小为sizeof(a)字节。注意指针变量自己占8字节的空间大小。总结int a[5] {1, 2, 3, 4, 5};a首元素地址——int *除了两种情况1.sizeof(a/数组名)a不能当作int *类型当作数组整体代表整个数组。2.a数组指针该指针类型为int (*)[5]指向一个数组。6.4.4 指针和二维数组二维数组的数组名是首元素地址首元素是一维数组所以二维数组名本质上是一个数组指针。inta[5]{1,2,3,4,5};a 首元素地址a[0]int*a[n]——*an)inta[2][3]{1,2,3,4,5,6};a 首元素地址a[0]int(*)[3]——数组指针 a[m][n]——*(a[m]n)——*(am)[n]——*(*(am)n)二维数组的数组名作为参数传递voidprint_2d_array(inta[][列数],inthang){}voidprint_2d_array(int(*pa)[列数],inthang){}voidprint_2d_array(chara[][列数],inthang){}voidprint_2d_array(char(*pstr)[列数],inthang){}6.4.5 指针数组定义用数组来保存若干个指针。语法指针类型 *数组名[常量];int*a[5];int*——数组中保存的数据类型该数组保存的元素是int*指针。[5]——该数组中可以保存5个int*指针。 定义了一个可以保存5整型指针的数组整体占40个字节。指针数组的初始化char*pNULL;char*p[5]{NULL};将5个字符型指针都初始化成NULL;char*phello;char*p[5]{hello,world,how,are,you};p[0]——是一个指针保存字符串常量hello的首地址。char*p1hello;char*p2world;char*p[2]{p1,p2};指针数组和二维字符数组的区别charstr[3][100]{hello,world,how};//300字节char*pstr[3]{hello,world,how};//24字节二维字符型数组中保存的是多个字符串本身指针数组中保存的是多个字符串的地址。要保存多个字符串用二维字符型数组要操作多个字符串用指针数组。6.5 二级指针定义本质上还是指针是一个指针变量的指针。int**指针名称;——保存整型指针的指针char**指针名称;——保存字符型指针的指针C语言中主要有两个二级指针的使用场景想要在被调函数中修改主调函数中的指针变量实参需要传递该指针变量的地址形参用二级指针接收。指针数组的数组名是一个二级指针实参传递指针数组的数组名时形参用二级指针接收。char*str[3]{hello,world,!};str[0];——char*——保存了字符串常量hello的首地址。 str ——str[0]——char**二级指针值传递:无法在被调中修改主调中的变量只能使用该变量指针传参:可以在被调中修改主调中定义的变量也可以使用该变量。值传递:恰好传递的值是一个指针变量无法在被调用修改主调中定义的指针变量可以使用该指针变量。指针传参:可以在被调函数中可以修改主调函数中定义的指针变量也可以使用该变量。6.6 指针函数定义本质上还是一个函数具有指针类型返回值的函数我们便称其为指针函数。指针函数返回的指针类型局部变量的地址不能被返回变量、数组charstr[32]{hello world};具有静态生命周期的变量的地址可以被返回。static修饰的静态变量地址。全局变量的地址。可以返回字符串常量的地址。char*strhello world!;可以返回通过参数传递给该函数的地址。strcpy(dst,src);可以返回堆区申请且没有被释放的空间地址。6.7 函数指针定义本质上还是一个指针指向函数我们便称其为函数指针。函数函数的函数名为函数的入口地址。函数的指针语法定义函数指针返回值类型 (*指针名称)(形参表)函数声明intfun(intnum1,intnum2);函数指针int(*pfun)(int,int);定义了一个函数指针变量该指针变量在内存占8字节 该函数指针可以指向具有int类型返回值两个int类型形参的函数。char*(*pfun)(char*);注意int *fun(int, int )为指针函数。int (*pfun)(int, int)为函数指针。函数指针初始化int(*pfun)(int,int)NULL;函数指针赋值intadd(intnum1,intnum2){}int(*pfun)(int,int)NULL;pfunadd;函数指针调用函数函数名(实参表);函数指针名(实参表);函数指针的应用回调函数将函数作为某个函数的参数传递传递的函数称为回调函数。降低代码耦合度减少重复代码。6.8 const修饰的指针constread only ——只读必须初始化。constintnum10;该变量只允许被使用不允许被改变。constint*p;——与intconst*p 等价。intconst*p;——修饰*p对指针p指向的内容修饰。即p指向的内容不可改变。 pnum//ok*p1000;//noint*constp;——修饰p指针p只读不能修改。因此定义该指针时必须为其初始化。 pnum//no*p1000;//okconstint*constp;与下面等价。intconst*constp;p的指向不能修改*p中的内容也不允许修改记得初始化。6.9 void*指针void*缺省类型指针。只是一个保存地址编号的变量。是一个万能指针。void*——char*int*short*double*float*void*p;*(int*)p;*(char*)p;char *int *short *double *float *这些指针不仅保存地址还有具体指向可以明确指向sizeof基类型个字节空间。注意void *可以看作一个高精度的指针其余看作低精度即可以将其看作一个隐式转换。