前言 C语言函数里最常用就是指针传参和返回地址,特别是字符串处理中,经常需要封装各种功能函数完成数据处理,并且C语言标准库里也提供了string.h 头文件,里面包含了很多字符串处理函数;这些函数的参数和返回值几乎都是指针类型...c=*a; *a=*b; *b=c; } //return语句只能返回一个值 //如果函数想返回多个值,可以使用指针(形参)实现。...注意: 从大到小或者小到大排序可以通过函数形参区分。...='\0'){} return str-p-1; } /* 函数功能: 实现字符串排序.支持从小到大或者大到小 函数形参: char *p 将要排序的字符串 char flag 选择排序方式...局部变量默认值是随机值(系统没有赋值) 静态变量默认值是0 */
文章目录 导引 指针函数 指针函数定义 指针函数的三种写法 代码示例 函数指针 定义 代码示例 函数指针和指针函数区别 定义不同 写法不同 用法不同 导引 函数指针和指针函数,在学习 C 语言的时候遇到这两个东西简直头疼...指针函数 指针函数定义 指针函数,简单的来说,就是一个返回指针的函数,其本质是一个函数,而该函数的返回值是一个指针。...其返回值是一个 int 类型的指针,是一个地址。 这样描述应该很容易理解了,所谓的指针函数也没什么特别的,和普通函数对比不过就是其返回了一个指针(即地址值)而已。...函数指针 定义 函数指针,其本质是一个指针变量,该指针指向这个函数。总结来说,函数指针就是指向函数的指针。...函数指针和指针函数区别 通过以上的介绍,应该都能清楚的理解其二者的定义。那么简单的总结下二者的区别: 定义不同 指针函数本质是一个函数,其返回值为指针。 函数指针本质是一个指针,其指向一个函数。
不带形参的main函数一般写成: int main() 或 int main(void) 表示mian函数没有参数,调用mian函数时不需要给出实参。...而main函数有形参的形式: int main( int argc, char** argv) int main( int argc, char *argv[]) 我是这样理解这两种方式,其中第一种方式...**argv是指针的指针,指针指向变量,指针是一个地址,所以*argv是一个地址。...第二种 *argv[]是指针数组,由于[]的优先级比*高,所以argv[]是一个数组,而数组名其实代表的是首地址,还是一个地址。所以这两种方法没有什么区别。...,因为第一个参数是操作系统给出的可执行文件名。
我们定义一个指针变量int *p; p是指针变量,专门用来存放地址。...指针变量p既然是变量,也同变量a一样对应一个小盒子,也有一个地址编号,&p就是取指针p的地址。...(&p) = p p是指针,&p为p的地址 (取包有内容p的盒子的编号) 再进行解引用(拆开盒子),所以得到 *&p = p 指针传递 形参出现在函数定义中,在整个函数体内都可以使用, 离开该函数则不能使用...”; } void main() { int b = 10; test(&b); cout << “b的值:” << b << “\n” << “b的地址:” << &b << “\n”; } 形参...当要使用数组作为函数形参时,因为一个数组不能使用另外一个数组初始化,也不能将一个数组赋值给另外一个数组,而在“1.1 非引用形参”中提到要用实参的副本来初始化形参,所以实参为数组时,不能直接传递给形参
数组作为实参,指针作为形参,传递的就只是地址。...由于buffer作为实参是8位数组,因此数组内储存的实际值为{0x01,0x01,0x02,0x02,0,0}。 可以看出数组指针看出仅仅是传递了地址,然后在函数内部按照函数自己的规则进行运算。
出现这样的结果其原因就是在函数中,当数组作为形式参数进行传参时,其意义发生了变化。将其解析为一个指针,而指针的大小为四个字节。此时将数组作为一个指针类型进行计算。
自定义的 业务子函数 与 主函数 main() ; 定义的接口如下 : 要点 1 形参指针间接赋值 : 主要是获取子串大小 , 通过 int *sub_count 参数的 间接赋值 , 实现函数结果返回...: 定义 局部 临时 指针变量 , 接收 函数形参变量 , 尽量不修改 函数 形参 的值 ; 形参指针判空 : 凡是传入的指针 , 一律判定指针是否合法 ; 形参返回值处理 : 返回值不要直接修改 ,...先定义临时局部变量保存返回值 , 最后执行完毕 , 再将返回值 通过 间接赋值 赋值给 形参中的 返回值指针 指向的 内存地址 ; /* * 获取字符串中子串个数接口 * char *main_str..., 先不要修改 sub_count 指针指向的值 , 最后计算完毕后再修改 int sub_count_tmp = 0; // 判定指针是否合法 // 如果形参指针为 NULL..., 先不要修改 sub_count 指针指向的值 , 最后计算完毕后再修改 int sub_count_tmp = 0; // 判定指针是否合法 // 如果形参指针为 NULL
指针数组 1.1 基本概念 指针数组是指一个数组,其中的每个元素都是指针。 这意味着数组中的每个元素都存储一个地址,该地址指向内存中的某个位置。...指针数组的声明形式为: data_type *array_name[size]; //示例: int *p[10];//该指针数组包含10个整型地址 1.2 简单示例 以下是一个简单的示例,演示了如何声明和使用指针数组...指针数组做main形参 2.1 int main(int argc, char *argv[]); 指针数组的一个重要应用是做main函数的形参。...如果main函数带参数的话,则第一个参数必须是int型,第二个参数必须是字符指针数组 char *xx[],参数只能由操作系统给出。...【谭浩强】C语言自学\output\mytest.exe */
问题 C 语言中的函数指针是怎么用的?...回答 我们先定义一个函数以方便接下来的讲解, int addInt(int n, int m) { return n+m; } 再定义一个可以指向函数 addInt 的函数指针, int (*functionPtr...)(int, int); 现在我们就可以给这个函数指针赋值了, functionPtr = addInt; // functionPtr = &addInt 也是可以的 函数指针有了指向的内容,就可以这么使用...{ int (*functionPtr)(int, int) = addInt; return functionPtr; } 我们还可以使用 typedef 关键字来更优雅地实现函数指针
最近在写链表的时候,定义了一个指针,当指针作为函数参数传参的时候出现了问题: 定义了一个空指针: int * end=NULL; 指针作为参数,目的可以指向申请的内存: void func(int...* P) { int * P_1 = (int *)malloc(sizeof(int)); P=P_1; } 但是当该函数被调用后,该指针end依旧为NULL,通过上述例子,我们可以看到...,一级指针作为函数参数时,在函数体内对指针做变动,当函数被调用结束后,原始指针不会产生任何变化。...但是指针作为函数值返回时则没有问题: int * P = func(); int * func() { int * P_1 = (int *)malloc(sizeof(int)); return...,引入变量地址来解决交换,现在也一样,我们想改变一级指针,自然就需要二级指针来解决问题,所以,你明白了吗。
文章目录 一、二级指针 二、完整代码示例 一、二级指针 ---- 指针 作为 函数输入 : 调用者 负责 分配内存 ; 指针 作为 函数输出 : 函数 负责 分配内存 , 一般 传入二级指针 , 函数负责生成内存..., 并 使用 二级指针 指向 一级指针, 一级指针 指向 在 函数中 分配好内存 ; 如果要在 函数中 分配内存 , 则 需要 传入二级指针 , 在函数内部调用 malloc 函数 , 分配内存 ,...返回一个 一级指针 变量 ; 令 二级指针 形参 指向 该 一级指针变量 , 即可通过间接赋值 返回相关结果 ; 代码示例如下 : /* * 生成 2 个字符串, 然后返回 */ int get_str...间接赋值 给 一级指针 *str2 = s2; return 0; } 二级指针 最终 指向的内存释放 : 释放二级指针 指向的 一级指针 指向的内存的地址 , 释放后 将指针指向的地址置空...return -1; } // 释放二级指针 指向的 一级指针 指向的内存的地址 // 释放指针 free(*str); // 将指针指向的地址置空
执行do_work(pData, 128); 这里传递的参数是pData本身,所以进入void do_work(char *p, int size)函数之后,实参pData的内容就赋值给形参p,所以指针...到这里就已经看到程序崩溃的原因了:虽然给指针p赋值了,但是实参pData中的内容一直为空,因此从do_malloc函数返回之后,pData仍然是一个空指针,所以就崩溃了。...在do_malloc函数中,调用系统函数malloc成功之后返回所分配空间的首地址,关键是要把这个首地址送给pData指针,也就是说要让pData指针变量中的值等于这个堆空间的首地址。...p此时是一个二级指针,参数赋值之后,p里面的内容就变成了pData这个指针变量的地址,也就是说p指向了pData这个变量。...执行*p = (char *)malloc(size + 1); 这句话首先搞明白*p是啥意思,刚才说了,p是一个指针,它指向了pData这个变量。
C++问题: 使用函数调用,排序string字符串数组从小到大,没有使用指针和引用,为什么实参也会改变?...string> using namespace std; int main() { void sort(string []); string array[3] = {"l" , "love" , "c+...0;j<2-i;j++) { if(s[j + 1] < s[j]) { temp = s[j]; s[j] = s[j+1]; s[j+1] = temp; } } } } 改变的值是实参的值...,也就是说实参对形参传的是地址,此时形参与实参为同一个地址,形参在改变形参也会改变,所以string类与数组做形参时一样,string类的形参是一个指针,接受的是字符串首个字符地址,其中数组类型在存贮数据是连续线性存贮的...这是关于C++中string类比C语言中数组类型的改进。
文章目录 一、一维数组形参退化 二、二维数组形参退化 三、数组形参等价关系 一、一维数组形参退化 ---- C 中将 一维数组 作为参数 , 传递到函数中 , 该 一维数组 会退化为 指针 ; 将 int...---- 实参为 一维数组 int array[10] , 等效的 形参为 一级指针 int *array ; 一维数组 , 直接退化为 指向 数组元素的指针 , 数组元素是 普通类型 , 指向普通类型的指针..., 即 一级指针 ; 实参为 指针数组 int *array[10] , 等效的 形参为 一级指针 int **array ; 指针数组 是 数组的元素 都是 指针变量 ; 数组退化为 指针 , 指针指向的元素...也是 指针 , 则形参为 二级指针 ; 实参为 二维数组 int array[10][20] , 等效的 形参为 一级指针 int (*array)[20] ; 二维数组 的 数组的元素 是 一维数组...; 外围数组 ( 第二维 ) 退化为 指针 , 指针 指向的元素 是 一维数组 , 则形参为 指向 一维数组 的指针 , 每个一维数组有 20 个元素 ;
; 字符串翻转模型 业务函数 要点 : 形参返回值 : 函数的返回值 , 一般使用 函数形参 间接赋值 进行返回 ; 下面的代码中 char *str 是返回值 ; int inverse(char *...str) 函数返回值 : 函数的返回值 , 反映的是函数的执行结果状态 , 返回 0 执行成功 , 返回 -1 执行失败 ; 函数形参处理 : 在 函数中 , 如果涉及到修改 形参 指针变量 , 一般不直接使用形参..., 创建一个临时局部变量 , 接收形参 , 然后再执行相关操作 ; // 创建临时变量接收 函数形参 , 不要直接改变形参的函数指向 char *str_tmp = str; 形参指针判空...: 函数的第一项任务就是 判定 形参指针是否合法 , 如果任何一个指针为空 , 直接返回 -1 ; // 判断传入的字符串指针是否为空 if(str_tmp == NULL)...= c; // 指向头部的指针自增 p_start++; // 指向尾部的指针自减 p_end--; } return
NULL的用法; NULL的源代码: 可以看到是NULL的值是0,这是一个特殊的地址 #ifndef NULL #ifdef __cplusplus #define NULL...0 #else #define NULL ((void *)0) #endif #endif 在C语言或者C++中,NULL指针也是经常使用的。...//2、空指针NULL int *pn = NULL; printf("%#x \n",&pn);//0xaf7df7c8 *pn = 10;//error 会报错 Process finished...*pn = NULL; printf("%#x \n",&pn);//0xaf7df7c8 if(pn) { *pn = 10;//error 会报错 Process...; 2、空指针NULL的用法; 3、注意避免产生野指针;
#include //指针变量测试 //指针变量存储的值是另一个变量的地址,也就是说改指针变量指向了另一个变量 int main(){ int a=10;...//2.定义指针变量时必须带*,定义并初始化,b的值是a的内存地址 int* b=&a; //3.打印出指针变量本身的地址 printf("%#X \n...;//输出 0XBFA0ED70 //5.给指针变量赋值时,不用带* b=&c; //6.通过指针变量获取数据时要带*,使用指针是间接获取数据...printf("%d \n",*b); //7.通过指针变量修改内存上的数据 *b=30; printf("%d \n",c);...表示获取指针指向的数据,是一种间接操作,例如int a, b, *p = &a; *p = 100; b = *p; */ }
什么是指针 C语言中指针是一种数据类型,指针是存放数据的内存单元地址。...需要注意的是,虽然地址是一个整数,但是C语言中不允许把整数看成“地址常量”,所以此处的“地址型表达式”不能是整数。 2. 使用指针变量 格式:指针变量名 需要使用地址时,可以直接引用指针变量名。...指针变量作为函数参数,形参和实参之间的数据传递方式本质上是值传递,只是在调用函数时传递的内容是地址,这样使得形参变量和实参变量指向同一个变量。...若被调函数中有对形参所指变量内存的改变,实际上是改变了实参所指变量的内容。 数组名作为函数形参时,接收实参数组的首地址;数组名作为函数实参时,将数组的首地址传递给形参数组。...形参为指针变量、实参为数组名; 4. 形参为数组名、实参为指针变量 C语言中,函数可以返回整型、实型、字符型数据,也可以返回指针类型数据,即返回一个地址。
有这样一小段代码,如: int *p=(int *)malloc(sizeof(int)); free(p); 这一段代码,程序会在堆中分配一个整形长度的内存,比如这段内存的首地址是1000,那么指针变量...p的值为1000,当调用函数free释放这段内存时,指针变量p的值任然是1000,虽然这段内存已被释放,但这段内存中任然可能包含原值,但此生指针p已指向的不是一个有效的对象,因为这段内存可能会被重新利用...,里面的数据也是不确定的,由于大部分运行时系统不会阻止对后续的访问与修改,所以如果我们试图解引一个已释放的指针,其行为是未定义的,那么将可能引起很多问题,如:如果再次访问这段内存,其行为是不可预期的、潜在的安全隐患...,行为是不可预期的,虽然你向这段内存中写入了数据,但是这段内存已被释放,这段内存可以重新被利用,所以虽然写入了10,但可能会被其他利用这段内存程序改变,因此行为不可逾期。...小编给大家推荐一个学习氛围超好的地方,C/C++交流企鹅裙:870963251!适合在校大学生,小白,想转行,想通过这个找工作的加入。
1、“野指针”(wild pointer) “野指针”(wild pointer):是没有被初始化过的指针,所以不确定指针具体指向。...例如以下示例代码: void *p; // 此时 p 是“野指针” 因为“野指针”可能指向任意内存段,因此它可能会损坏正常的数据,也有可能引发其他未知错误。...在实际的C语言程序开发中,定义指针时,一般都要尽量避免“野指针”的出现,可通过赋初值方式解决: void *p = NULL; void *data = malloc(size); 2、“悬空指针”(dangling...pointer) “悬空指针”(dangling pointer):是指针最初指向的内存已经被释放了的一种指针。...例如以下示例代码: void *p = malloc(size); assert(p); free(p); // 现在 p 是“悬空指针” C语言中的“悬空指针”会引发不可预知的错误,而且这种错误一旦发生
领取专属 10元无门槛券
手把手带您无忧上云