网站的建设进入哪个科目,企业网站seo推广方案,建设一个房产网站赚钱吗,深汕特别合作区属于哪个市Visual Studio 2019 解决方案的多项目应用在讲述变量#xff0c;数据类型#xff0c;运算符和表达式以及程序流程控制#xff0c;数组#xff0c;函数的相关内容#xff0c;所有的代码都放在解决方案c-core的c-core-foundational项目下。如果你有其他编程语言经验#xf…Visual Studio 2019 解决方案的多项目应用在讲述变量数据类型运算符和表达式以及程序流程控制数组函数的相关内容所有的代码都放在解决方案c-core的c-core-foundational项目下。如果你有其他编程语言经验类似于C,Java,Python,Go语言它们都会有这些最最基本的内容而且语法结构都很类似(但不完全相同)。而Visual Studio 2019的单个解决方案支持多个项目因此指针以后的内容都会放在c-core-advanced项目下。但是Visual Studio 2019在编译单个解决方案下的多项目时只能启动一个项目来参与编译和运行。因此我们需要指定一个项目为启动项设置为启动项后编译运行时只有该项目会参与编译。设置启动项指针基础指针与指针变量32位编译器上的程序运行时系统会给程序随机分配一段内存空间这段空间的最小单位是字节每个字节都有自己的唯一编号而32位编译器能寻址的范围按照十六进制表示是0x00000000到0xffffffff这个编号就是指针。整型变量用于存储整数的变量而指针变量就是存储指针(地址或者编号例如0x00000001)的变量因为32位编译器的地址编号的范围是0x00000000到0xffffffff因此指针变量的大小是4个字节。 64位编译器能寻址的范围是0x0000000000000000到0xffffffffffffffff因此64位编译器的指针变量占据8个字节。指针变量的定义、声明和初始化首先回顾下变量的声明和赋值这里以大家熟悉的整型变量定义为例int number; 表示在内存中开辟四个字节,假设number变量的内存地址是0x00000002number 10; 表示将内存地址0x00000002代表的那块空间的内容修改为10C语言中通过地址符加上变量名就可以获取变量的地址即number表示number的地址。而C语言中*加上变量名表示一个指针类型的变量例如*p其中指针的变量名是p当然也可以是任何合法的标识符例如p_int那么声明定义一个指针变量呢声明指针变量有三个步骤1.*加上变量名表示为指针变量例如*p,p表示指针变量名2.要保存变量的地址将变量的声明放在此处例如int number;表示声明一个整数变量3.将*p 替换声明的变量名,例如 int number 使用*p 替换后就是 int *p因为指针的本质就是变量内存地址那么给指针变量赋值也就是变量的地址即p number;而指针变量的定义就是将指针变量的声明和赋值写在一行int *pnumber;其中 p是指针变量的名字而p的类型是就是将变量p本身去掉后剩下的类型就是指针变量的类型这里就是int *指针变量p保存什么数据类型的地址就是去掉变量p与其离的最近的一个*后剩下的类型就是保存地址的数据类型这里就是int例如多级指针变量int **p 的指针变量类型是int **,p保存地址的类型就是int *我们还可以根据声明指针变量三个步骤来定义其他类型的指针变量例如字符指针数组指针,代码片段如下//使用指针变量保存char类型变量的地址char ch x;char *p_charch;//输出指针变量p_char的内存地址printf(p_char %p, p_char);//使用指针变量保存整数数组类型变量的地址int numbers[10] {1,2,3,4,5,6,7,8,9,10};int (*p_array)[10]numbers;//输出指针变量p_array的内存地址printf(p_array %p, p_array[10]);指针变量的定义声明和初始化#define _CRT_SECURE_NO_WARNINGS#include #include /*指针变量的定义声明和初始化author liuguanglei 18601767221163.comwechat 18601767221website ittimeline.netversion 2020/11/25*/int main (int argc, char* argv[]){int number 10;//指针变量用于存放变量的地址//那么如何声明指针变量呢 指针变量是什么类型/*声明指针变量的三步骤1. *加变量名表示指针变量例如*p,p表示指针变量名2. 要声明指针变量将变量的声明形式放在此处例如 int number;3. 使用*p替换声明的变量名例如 int number 使用*p 替换后就是 int *p*///声明指针变量int *p;/**与p结合代表是一个指针变量,p是变量名p是变量该变量的类型是将变量p去掉剩下的类型就是指针变量类型即int *指针变量p保存什么数据类型的地址 去掉指针变量p与指针变量p离得最近的一个*后剩下的数据类型就是指针变量p保存的数据类型的地址即int而多级指针 int **p ,p是变量p的类型是int ** ,而p保存的类型是int **///指针变量赋值p number;printf(p %p,p);//使用指针变量保存char类型变量的地址char ch x;char *p_charch;//输出指针变量p_char的内存地址printf(p_char %p, p_char);//使用指针变量保存整数数组类型变量的地址int numbers[10] {1,2,3,4,5,6,7,8,9,10};int (*p_array)[10]numbers;//输出指针变量p_array的内存地址printf(p_array %p, p_array[10]);system(pause);return 0;}程序运行结果指针变量的使用指针变量保存了变量的内存地址就可以操作变量代表的那块内存空间,在使用时*p表示p指向那块内存地址的空间内容即可以通过*p间接修改变量的内容。指针变量和普通变量一样可以多次被赋值即指向别的内存空间的地址。可以获取一个变量的内存地址但是不能取寄存器变量因此寄存器变量不在内存中而在CPU中CPU没有地址。#define _CRT_SECURE_NO_WARNINGS#include #include /*指针变量的使用author liuguanglei 18601767221163.comwechat 18601767221website ittimeline.netversion 2020/11/25*/int main(int argc, char* argv[]){int number 100;//指针变量p指向了number的内存地址int *p number;printf(number的内存地址是%p,number);printf(number的内存地址是%p,p);// 就可以通过p来操作number代表那块空间的内容//使用时*p表示取p指向number所代表那块内存空间的内容printf(*p %d ,*p);//通过指针修改number的值*p 80;printf(*p %d , *p);printf(number %d , number);int x 20;//第二次指向x变量的内存空间p x;printf(*p %d , *p);printf(x %d , x);system(pause);return 0;}程序运行结果赋值运算符()两边的类型必须一致指针变量也是如此对于指针变量和地址符()而言在使用时(例如赋值)对一个表达式取*就会对表达式减一级*,如果对表达式取就会加一级*。例如p x;p的类型是int *,而x的类型是int,取表示加一级*,此时左右两边类型一致都是int *例如*p80,80的类型是int,而在对于一个表达式取*就会减一级*,此时左右两边类型一致都是int例如int *p; int **q; q*p,q的类型是int **,p的类型是int *,而对表达式取加一级*因此左右两边类型一致都是int **,*qp指针变量的大小因为指针变量就是存储的变量的内存地址而不管什么类型的指针(单级指针还是多级指针)32位编译器下指针变量的大小是4个字节64位编译器下指针变量的大小是8个字节。#define _CRT_SECURE_NO_WARNINGS#include #include /*指针变量的大小author liuguanglei 18601767221163.comwechat 18601767221website ittimeline.netversion 2020/11/25*/int main(int argc, char* argv[]){char *p_char;short *p_short;int *p_int;int **p_second_int;//不管是几级地址32位系统下 指针变量都是4个字节64位系统下 指针变量都是8个字节printf(指针变量 p_char的大小是%d个字节,sizeof(p_char));printf(指针变量 p_short的大小是%d个字节,sizeof(p_short));printf(指针变量 p_int的大小是%d个字节,sizeof(p_int));printf(指针变量 p_second_int的大小是%d个字节,sizeof(p_second_int));system(pause);return 0;}x86表示32位编译器32位编译器32位编译器运行效果x64表示64位编译器64位编译器运行效果指针的宽度和步长32位系统的指针变量大小为4个字节但是不同类型的指针变量(char * short * ,int * )指向内存的实际宽度是不一样的宽度也叫做步长求指针变量的宽度或者步长可以通过去掉指针变量p和离它最近的*然后用sizeof()求即可。#define _CRT_SECURE_NO_WARNINGS#include #include /*指针变量的宽度和步长author liuguanglei 18601767221163.comwechat 18601767221website ittimeline.netversion 2020/11/25*/int main(int argc, char* argv[]){int number 0x10203040;//由于右边number的类型是int *//左边是char *//因此类型不一致需要强制类型转换才能成功赋值//如果不强制类型转换编译器会提示 warning C4133: “初始化”: 从“int *”到“char *”的类型不兼容//赋值时尽量保存左右两边类型一致char* p_char (char *)number;short* p_short (short*)number;int* p_int number;//此时三个指针变量 p_char,p_short,p_int都指向同一块内存地址即number的内存地址//打印输出地址的内容printf(*p_char %x , *p_char);printf(*p_short %x ,*p_short);printf(*p_int %x , *p_int);//不同类型的指针获取的指针指向的内容是由指针变量的类型决定的//通过*取指针变量所指向那块空间内容时取得内存宽度是和指针变量本身的类型有关系// p_char获取的一个字节的宽度,p_short获取的是2个字节的宽度p_int获取的是4个字节的宽度//即将指针变量和指针变量最近的*去掉后的类型就是指针变量指向的内存表示的宽度printf(打印三个指针变量指向内容的宽度);printf(p_char指针指向内容的宽度是%u字节 ,sizeof(char));printf(p_short指针向内容的宽度是%u字节 ,sizeof(short));printf(p_int指针向内容的宽度是%u字节 ,sizeof(int));printf(int* 指针向内容的宽度是%u字节 ,sizeof(int*));//宽度也是步长//指针加1跨过多少个字节//打印三个指针变量的地址printf(打印三个指针变量的地址);printf(p_char %p,p_char);printf(p_short %p, p_short);printf(p_int %p,p_int);//打印三个指针变量地址的宽度1//步长为1printf(p_char1 %p, p_char 1);//步长为2printf(p_short1 %p, p_short 1);//步长为4printf(p_int1 %p, p_int 1);system(pause);return 0;}程序运行结果野指针在定义整数变量时如果变量尚未初始化是不能使用变量的。指针变量也是如此当声明一个指针变量但是尚未初始化后就使用时此指针变量称为野指针野指针就是没有初始化过的指针此时指针的指向是随机的内存地址在日常开发中不能使用野指针。在Visual Studio 2019中使用野指针编译器会提示C4700错误:使用了尚未初始化的局部变量#define _CRT_SECURE_NO_WARNINGS#include #include /*野指针author liuguanglei 18601767221163.comwechat 18601767221website ittimeline.netversion 2020/11/25*/int main(int argc, char* argv[]){//野指针:没有初始化的指针指针的指向是随机的不能使用野指针。// 指针p保存的地址一定是初始化过的(向系统申请过的)int *p;//指针变量p没有指向任何内容即尚未初始化//因此不能赋值*p 200;printf(*p %d ,*p);system(pause);return 0;}C4700错误空指针在定义指针变量时如果初始化为0或者初始化为NULL,此时的指针变量就是空指针即指针的编号为0x00000000而0x0000000的地址是不会给应用程序使用。NULL是C语言的关键字这里用于描述空指针。在使用指针之前可以使用if语句判断指针是否为NULL就可以判断该指针是否为空指针。如果指针不再使用可以赋值为NULL。#define _CRT_SECURE_NO_WARNINGS#include #include /*空指针:指针变量的值为0author liuguanglei 18601767221163.comwechat 18601767221website ittimeline.netversion 2020/11/25*/int main(int argc, char* argv[]){//空指针即将指针的值赋值为00的32位十六进制表示0x00000000 // 0x00000000 被操作系统占用了int *p 0;int number 10;//C语言使用NULL关键字表示空指针int *p_null NULL; //等价于 int *p_null0// NULL作为标记if (NULL p_null) {p number;}//因为p_null保存了0x00000000的地址该地址不能给应用程序使用*p_null 200; printf(*p_null %d ,*p_null);system(pause);return 0;}在使用指针时必须首先初始化指针后再使用禁止使用野指针和空指针。const修饰的指针变量在定义变量时使用const修饰的变量不能直接通过变量名修改而const修饰指针变量时有三种情况,这里假设已经初始化了三个指针变量,p_int,p_dbl和p_char指针变量const int *p_int 此时const修饰的是*,表示p_int指向的空间内容不能改变指针变量int const *p_dbl 此时const修饰的是指针变量p_dbl表示p_dbl不能再指向别的内存空间指针变量const int const *p_char,此时const同时修饰*和p_char,表示 p_char不能再指向别的内存空间的同时空间内容也不能改变。#define _CRT_SECURE_NO_WARNINGS#include #include /*const修饰的指针变量author liuguanglei 18601767221163.comwechat 18601767221website ittimeline.netversion 2020/11/25*/int main(int argc, char* argv[]){// const修饰变量后不能通过赋值来修改变量的值const int number 10;printf(const整数变量number的初始化值为%d,number);//此处编译不通过//number 20;//但是可以通过指针来修改number变量的值int *p number;*p 20;printf(通过指针修改number的值为%d,number);*p 20;//const修饰的是*const int *p_int number;//const修饰指针变量后 不同通过*p_int 来修改number的值//*p_int 20;//const修饰的是变量p_dbldouble dbl 3.14;//初始化指针p_dbldouble * const p_dbl dbl;// p_dbl不能的值不能再指向别的内存空间即不能再修改//p_dbl number;//p_char本身的指向不能改变并且不能通过*p_char修改指向空间的内容const char* const p_char number; system(pause);return 0;}#define _CRT_SECURE_NO_WARNINGS#include #include /*const修饰的指针变量author liuguanglei 18601767221163.comwechat 18601767221website ittimeline.netversion 2020/11/25*/int main(int argc, char* argv[]){// const修饰变量后不能通过赋值来修改变量的值const int number 10;printf(const整数变量number的初始化值为%d,number);//此处编译不通过//number 20;//但是可以通过指针来修改number变量的值int *p number;*p 20;printf(通过指针修改number的值为%d,number);*p 20;//const修饰的是*const int *p_int number;//const修饰指针变量后 不同通过*p_int 来修改number的值//*p_int 20;//const修饰的是变量p_dbldouble dbl 3.14;//初始化指针p_dbldouble * const p_dbl dbl;// p_dbl不能的值不能再指向别的内存空间即不能再修改//p_dbl number;//p_char本身的指向不能改变并且不能通过*p_char修改指向空间的内容const char* const p_char number; system(pause);return 0;}多级指针#define _CRT_SECURE_NO_WARNINGS#include #include /*多级指针的定义与初始化定义多级指针保存数据的地址时定义的指针类型只需要比要保存的数据类型多一级*即可。author liuguanglei 18601767221163.comwechat 18601767221website ittimeline.netversion 2020/11/25*/int main(int argc, char* argv[]){int number 10; // *p一级指针初始化int *p number;//定义二级指针q保存p的地址// *q 表示指针变量 **q表示二级指针变量int **q p;//通过**q取number的值 **q// *q表示number的地址 即number//printf(**q %d ,**q);//如果*和相邻就相互抵消了printf(*number %d ,*number);//定义变量保存q的地址//三级指针的定义int ***u q;printf(***u %d ,***u);system(pause);return 0;}程序运行结果指针操作数组指针除了操作变量以外还可以用来操作数组。当定义一个整数数组int numbers[10]{1,2,3,4,5,6,7,8,9,10};,numbers代表了数组的首元素地址。而在没有学习指针时通过数组名[下标]的方式来访问数组for(int i0;i在学习了指针变量后我们可以定义指针变量来保存数组元素的首地址:int *p numbers,由于数组的每个元素都是连续的内存空间,而通过指针变量的加减运算(例如p1表示获取下一个指针地址)就可以很容易获取数组的下一个元素的地址。for (int i 0; i sizeof(numbers)/sizeof(numbers[0]);i) {//通过指针遍历数组的元素printf(numbers[%d] %d ,i,*(pi));}再来初始化一个整数数组: int data[5]{1,2,3,4,5};,计算*(data1)的值。因为data表示数组首元素(即第一个元素)的地址而data1表示获取第二个元素的地址。*(data1) 表示取第二个元素地址的内容结果就是2int* ptr (int*)(data 1);printf(*(ptr-1) %d , *(ptr - 1));(int*)(data 1);表示整个data数组的地址加1然后为了类型匹配转换成int *类型而*(ptr-1)表示ptr原有的地址值减1后获取指向的内容为5指针操作数组的元素#define _CRT_SECURE_NO_WARNINGS#include #include /*指针操作数组的元素author liuguanglei 18601767221163.comwechat 18601767221website ittimeline.netversion 2020/11/25*/int main(int argc, char* argv[]){//初始化整数数组//数组名numbers代表数组首元素的地址int numbers[10] {1,2,3,4,5,6,7,8,9,10};//定义指针变量指向numbers数组的首元素地址//指针p保存的是数组元素的首地址int *p numbers;int size sizeof(numbers) / sizeof(numbers[0]);printf(通过指针遍历数组的元素);for (int i 0; i size;i) {//通过指针遍历数组的元素printf(numbers[%d] %d ,i,*(pi));}int data[5] {1,2,3,4,5};//*(data1)2 2 因为data表示data数组的首元素地址然后data1表示第二个元素的地址*(data1)表示取第二个元素地址对应的内容 因此是2printf(*(data)1 %d ,*(data1));//*(ptr-1)5//表示整个data数组的地址加1然后为了类型匹配转换成int *类型而*(ptr-1)表示ptr原有的地址值减1后获取指向的内容为5int* ptr (int*)(data 1);printf(*(ptr-1) %d , *(ptr - 1));system(pause);return 0;}程序运行结果[]除了在声明数组时使用以外还可以在定义指针变量和指针数组时使用在指针变量和指针数组中使用[]时,[]等价于*()的缩写例如p[0]*(p0)#define _CRT_SECURE_NO_WARNINGS#include #include /*方括号[]在指针变量指针数组的应用author liuguanglei 18601767221163.comwechat 18601767221website ittimeline.netversion 2020/11/25*/int main(int argc, char* argv[]){int number 10;int* p number;//[]等价于*()的缩写//p[0]*(p0)p[0] 100;printf(number %d , number);int numbers[] { 1,2,3,4,5,6,7,8,9,10 };int* p_array numbers;for (int i 0;i程序运行结果指针的运算指针可以进行加减运算#define _CRT_SECURE_NO_WARNINGS#include #include /*指针的算术运算 author liuguanglei 18601767221163.comwechat 18601767221website ittimeline.netversion 2020/11/25*/int main(int argc, char* argv[]){int numbers[10] {1,2,3,4,5,6,7,8,9,10};//数组第一个元素的地址//数组名表示数组首元素的地址int *p numbers;//数组最后一个元素的地址//int* q numbers[9];//另外一种方式表示数组最后一个元素的地址//(int*)(numbers 1)-1 表示整个数组的长度加1后转换为int*后就是元素的地址减1即为数组的最后一个元素地址int *q (int*)(numbers 1) - 1;//p和q中间的元素个数printf(q - p %d ,(q-p));// *(p3) 4//因为p指向第一个数组的第一个元素printf(*(p3) %d ,*(p3));//在C语言中两指针相加没有意义//printf(*(p3) %d ,(pq));system(pause);return 0;}程序运行结果两指针(相同类型的指针)相减得到的结果是中间跨过多少元素。两指针相加没有任何意义。指针数组一级指针操作指针数组整型数组:数组中存放多个整型元素顾名思义指针数组就是数组中存放多个指针。指针数组的类型由指针指向元素的类型决定的例如指针指向int类型数据的内存地址,那么指针数组的中的元素类型就是int *指针数组的定义和初始化和整型数组类似如果指针数组的元素类型是int *,那么每个int *的大小为4个字节//初始化三个整数变量int left 10, middle 20, right 30;//将三个整数变量赋值给numbers数组int numbers[3] {left,middle,right};//定义三个int*类型的指针int* p_left left;int* p_middle middle;int* p_right right;//定义指针数组存放三个整数变量的地址 每个元素都是int *类型int* p_numbers[3] {left,middle,right};// int *占据4个字节printf(p_numbers占%d个字节,sizeof(p_numbers));指针数组的元素可以通过指*针数组名[下标]的方式获取例如*p_numbers[0]printf(left %d ,*p_numbers[0]);指针数组的遍历// 遍历指针数组获取数组中的指针指向空间的内容int size sizeof(p_numbers) / sizeof(p_numbers[0]);for (int i 0; i size;i) {printf(*p_numbers[%d] %d ,i,*(p_numbers[i]));}printf();指针数组的定义、初始化和遍历#define _CRT_SECURE_NO_WARNINGS#include #include /*一级指针数组的定义、初始化和遍历指针数组:数组中存放多个指针author liuguanglei 18601767221163.comwechat 18601767221website ittimeline.netversion 2020/11/25*/int main(int argc, char* argv[]){//初始化三个整数变量int left 10, middle 20, right 30;//将三个整数变量赋值给numbers数组int numbers[3] {left,middle,right};//定义三个int*类型的指针int* p_left left;int* p_middle middle;int* p_right right;//定义指针数组存放三个整数变量的地址 每个元素都是int *类型int* p_numbers[3] {left,middle,right};// int *占据4个字节printf(p_numbers占%d个字节,sizeof(p_numbers));printf(left %d ,*p_numbers[0]);// 遍历指针数组获取数组中的指针指向空间的内容int size sizeof(p_numbers) / sizeof(p_numbers[0]);for (int i 0; i size;i) {printf(*p_numbers[%d] %d ,i,*(p_numbers[i]));}printf();system(pause);return 0;}程序运行结果二级指针操作指针数组当想要把一级指针数组以指针变量的方式保存在另外一个指针中此时就需要使用到二级指针.例如int ** p_first_elementp_numbers,由于p_numbers是int *类型根据要保存int *类型的地址就需要比它多一级*,因此使用int **p_first_element保存。其中p_numbers是指针数组的首元素地址。通过p_first_element变量获取left(即一级指针p_numbers指向的left内存地址的内容)的值p_first_element 通过*p_first_element可以获取left变量的地址值而**p_first_element可以获取left变量地址指向的空间内容也就是left的值printf(通过p_first_element获取left的值 left %d , (**p_first_element));通过p_first_element变量获取middle(即一级指针p_numbers指向的middle内存地址的内容)的值p_first_element 通过*p_first_element可以获取left变量的地址值,而*(p_first_element1)可以获取middle变量的地址值通过**(p_first_element1)就可以获取middle变量的值通过p_first_element变量获取right(即一级指针p_numbers指向的right内存地址的内容)的值p_first_element 通过*p_first_element可以获取left变量的地址值,而*(p_first_element2)可以获取right变量的地址值通过**(p_first_element2)就可以获取right变量的值也可以采用遍历二级指针的方式来获取left,middle,right的值for (int i 0; i sizeof(p_numbers) / sizeof(p_numbers[0]); i) {printf(%d , **(p_first_element i));}二级指针操作指针数组#define _CRT_SECURE_NO_WARNINGS#include #include /*多级指针操作指针数组author liuguanglei 18601767221163.comwechat 18601767221website ittimeline.netversion 2020/11/25*/int main(int argc, char* argv[]){/***********************************************************二级指针操作指针数组*********************************************************///初始化三个整数变量int left 10, middle 20, right 30;//将三个整数变量赋值给numbers数组int numbers[3] { left,middle,right };//定义三个int*类型的指针int* p_left left;int* p_middle middle;int* p_right right;//定义指针数组存放三个整数变量的地址 每个元素都是int *类型int* p_numbers[3] { left,middle,right };//定义指针保存p_numbers首元素的地址//p_numbers就是首元素的地址其类型是int *//要保存int *的地址需要比它多一级*int** p_first_element p_numbers;// 通过p_first_element获取left的值//*p_first_element表示left的地址//**p_first_element表示left地址的内容printf(通过p_first_element获取left的值 left %d , (**p_first_element));//通过p_first_element获取middle的值//*(p_first_element1)表示middle的地址//*(*(p_first_element1))表示middle地址的内容printf(通过p_first_element获取middle的值 middle %d , (*(*(p_first_element 1))));//通过p_first_element获取right的值//*(p_first_element2)表示right的地址//*(*(p_first_element2))表示right地址的内容printf(通过p_first_element获取right的值 middle %d , (*(*(p_first_element 2))));//通过for循环获取p_first_element 的 left,middle,right值printf(通过for循环获取p_first_element 的 left,middle,right值);for (int i 0; i sizeof(p_numbers) / sizeof(p_numbers[0]); i) {printf(%d , **(p_first_element i));}system(pause);return 0;}程序运行效果指针和函数指针作为函数的形参指针作为函数的形参可以改变实参的值在调用函数时如果没有使用指针形参不会改变实参的内容。#define _CRT_SECURE_NO_WARNINGS#include #include /*交换两个整数形式参数的值单向值传递*/void swap_variable(int x,int y) {int tmp x;x y;y tmp;}/*指针和函数指针作为函数的形参可以改变实参的值author liuguanglei 18601767221163.comwechat 18601767221website ittimeline.netversion 2020/11/25*/int main(int argc, char* argv[]){int left 10;int right 20;printf(普通变量交换之前 left %d right %d ,left,right);swap_variable(10,20);printf(普通变量交换之后 left %d right %d , left, right);system(pause);return 0;}运行上面的程序会看到当执行完swap_variable()方法后形参x和y的值已经交换(即x20,y10),而实际参数left和right的值在交换前后并没有发生改变。此时可以将指针变量作为函数的形式参数当在函数内部改变形式参数的值实际参数也会跟着改变#define _CRT_SECURE_NO_WARNINGS#include #include /*交换两个int*指针变量 形式参数的值*/void swap_pointer(int* p_left,int *p_right) {//交换指针变量指向空间内容的值int p_tmp *p_left;*p_left *p_right;*p_right p_tmp;}/*指针和函数指针作为函数的形参可以改变实参的值author liuguanglei 18601767221163.comwechat 18601767221website ittimeline.netversion 2020/11/25*/int main(int argc, char* argv[]){int left 10;int right 20;int* p_left_val left;int* p_right_val right;printf(指针变量交换之前 left %d right %d , left, right);swap_pointer(p_left_val, p_right_val);printf(指针变量交换之后 left %d right %d , left, right);system(pause);return 0;}程序运行结果数组作为函数的参数数组作为函数的形参会退化为指针,即int data[] 退化为 int *data有个遍历数组元素的需求首先定义一个函数函数的参数为整型数组/*遍历data[]数组元素的内容*/void print(int data[]) {int size sizeof(data) / sizeof(data[0]);for (int i 0; i size; i) {printf(data[%d] %d, i, data[i]);}}然后在main函数中调用函数#define _CRT_SECURE_NO_WARNINGS#include #include /*数组作为函数的参数author liuguanglei 18601767221163.comwechat 18601767221website ittimeline.netversion 2020/11/25*/int main(int argc, char* argv[]){int numbers[10] {1,2,3,4,5,6,7,8,9,10};//数组名numbers代表首元素地址print(numbers);system(pause);return 0;}当运行该程序时结果只输出了numbers数组的第一个元素。因为当调用print()方法时传递的numbers表示数组首元素的地址而int data[]会退化成 int *data,data的类型是int *它占据四个字节即sizeof(data)的结果就是4个字节。而sizeof(data[0])等价于sizeof(*(data0)),data表示首元素的地址data0依然表示首元素的地址*(data0)表示首元素地址的内容也就是1sizeof(1)的结果也是4个字节。4/4的结果是1因此for循环遍历时只输出了数组的第一个元素。程序运行结果正确遍历数组的姿势首先定义方法print_array,方法中的参数分别是int* data和数组的大小/*遍历数组元素的内容*/void print_array(int *data,int array_size) { // printf(data数组占据%d个字节,sizeof(data));for (int i 0; i array_size;i) {printf(data[%d] %d,i,*(datai));}}然后在调用时传递数组首元素的地址和大小就可以正常遍历数组#define _CRT_SECURE_NO_WARNINGS#include #include /*数组作为函数的参数author liuguanglei 18601767221163.comwechat 18601767221website ittimeline.netversion 2020/11/25*/int main(int argc, char* argv[]){int numbers[10] {1,2,3,4,5,6,7,8,9,10};//数组名numbers代表首元素地址//print(numbers);print_array(numbers,sizeof(numbers)/sizeof(numbers[0]));system(pause);return 0;}程序运行结果指针作为函数的返回值在定义函数时函数的返回值也可以是指针。例如定义一个返回随机数的指针/*获取随机数*/int* get_rand_num () {//以当前时间的毫秒数设置随机数的种子数srand(time(NULL));int number rand();//返回随机数的地址return number;}然后在main函数中调用随机数函数#define _CRT_SECURE_NO_WARNINGS#include #include int main(int argc, char* argv[]){int* p get_rand_num();printf(当前生成的随机数是%d,*p);system(pause);return 0;}程序运行结果但是这里有个问题因为在get_rand_num()函数中定义了int类型的number来接收生成的随机数而函数内部定义的变量叫局部变量局部变量会随着get_rand_num()函数执行完成被系统释放内存空间。一旦空间被释放则不能再使用因为在get_rand_num()。因此这里改进下程序将number的定义放到函数外当程序启动时系统会为number开辟空间而当程序结束时系统才会释放。#define _CRT_SECURE_NO_WARNINGS#include #include /*指针作为函数的返回值author liuguanglei 18601767221163.comwechat 18601767221website ittimeline.netversion 2020/11/25*///在函数外面定义的变量叫全局变量 整个项目都可以使用,变量在程序启动时开辟空间程序运行结束时释放空间int number 0;/*获取随机数*/int* get_rand_num() {//以当前时间的毫秒数设置随机数的种子数srand(time(NULL));//获取随机数//一旦get_rand_num()函数执行完成局部变量num会被释放。//int num rand();number rand();//返回随机数的地址return number;}int main(int argc, char* argv[]){int* p get_rand_num();printf(当前生成的随机数是%d,*p);system(pause);return 0;}