只不过是拿老程序的壳子执行新程序的代码。 站在被替换进程的角度:本质上是这个程序被加载到内存。使用exec系列函数加载,exec系列函数类似一种Linux上的加载函数。...所以为什么上述现象中,原来的进程中printf("testexec end! ...\n"); 没有执行的原因是,调用execl函数后,去执行ls程序了,原来的代码和数据被替换了。...使用所有的替换方法,并且认识函数的参数含义 execl int execl(const char *path, const char *arg, ...); execl中,l:list,列表 path:...需要执行的路劲,需要带路劲 后面的参数:在命令行中怎么执行 例如: execl("/usr/bin/ls","ls","-l","-a",NULL); execv execv(const char...PATH,用户可以不传要执行的路劲(但是文件名要传),直接告诉要执行谁即可 if(id==0) { sleep(2); char* const argv
"; char str2[] = "hello bit."; const char *str3 = "hello bit."; const char *str4 = "hello bit....3.使用 1.使用的情景 一般情况下,用在一维数组时并不方便,所以我们一般多用在二维数组、多维数组。 注意:既然数组指针指向的是数组,那数组指针中存放的应该是数组的地址。...定义: void test(const char* str) { printf("%s\n", str); } int main() { //函数指针pfun void(*pf)(const char...如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。...但由于篇幅原因,在这一篇文章中仍不能将所有的知识全部总结完,因此后续还是会不断补充关于C语言中的指针的内容,希望大家继续支持。
八、指针的使用和传址调用 1、strlen的模拟实现 strlen 返回类型为size_t 打印时为%zd 库函数strlen的功能是求字符串⻓度,统计的是字符串中 \0 之前的字符的个数。...Swap1函数在使⽤的时候,是把变量本⾝直接传递给了函数,这种调⽤函数的⽅式我们之前在函数的时候就知道了,这种叫传值调⽤。...那么就可以使⽤指针了,在main函数中将a和b的地址传递给Swap函数,Swap函数⾥边通过地址间接的操作main函数中的a和b,并达到交换的效果就好了。...传址调用,可以让函数和主调函数之间建立真正的联系,在函数内部可以修改主调函数中的变量;所以未来函数中只是需要主调函数中的变量值来实现计算,就可以采⽤传值调⽤。...如果函数内部要修改主调函数中的变量的值,就需要传址调⽤。
当把数组名赋值给一个指针后,再对指针使用sizeof运算符,返回的是指针的大小。 这就是为什么我么将一个数组传递给一个函数时,需要另外用一个参数传递数组元素个数的原因了。...「函数的参数和指针」 C 语言中,实参传递给形参,是按值传递的,也就是说,函数中的形参是实参的拷贝份,形参和实参只是在值上面一样,而不是同一个内存数据对象。...这就意味着:这种数据传递是单向的,即从调用者传递给被调函数,而被调函数无法修改传递的参数达到回传的效果。...,在简单的情况下是可以的,但是如果返回值有其它用途(例如返回函数的执行状态量),或者要回传的数据不止一个,返回值就解决不了了。...既然是存放在内存中,那么函数也是有自己的指针的。C 语言中,函数名作为右值时,就是这个函数的指针。
在 Debug 中使用,在 Release 版本中选择禁用 assert 就可以,在像VS这样的集成开发环境中,在 Release 版本中,直接就被优化掉了。...这样在debug版本中有利于程序员排查问题,在 Release 版本中不影响用户使用时程序的效率。...b的值,不过x的地址和a的地址不⼀样,y的地址和b的地址不⼀样,相当于x和y是独⽴的空间,那么在Swap1函数内部交换x和y的值,⾃然不会影响a和b,当Swap1函数调⽤结束后回到main函数,a和b的没法交换...Swap1函数在使⽤的时候,是把变量本⾝直接传递给了函数,这种调⽤函数的⽅式我们之前在函数的时候就知道了,这种叫传值调⽤。...所以未来函数中只是需要主调函数中的变量值来实现计算,就可以采用传值调用。如果函数内部要修改主调函数中的变量的值,就需要传址调用。
= NULL) { *P = 200; } return 0; }*/ //在vs版本中,Debug中assert()语句是可以使用的,但是在Release版本中直接优化掉了...,用char*s接收 {//添加const不希望字符串被修改,直接将每次传来的实参固定死 //不加const的话原先字符串的长度就被修改了 size_t count = 0; assert...int b = 20; int c=Add(a, b); printf("%d\n", c); //传值调用 return 0; } //当使用传值调用时,实际上是将参数值复制到函数内部的一个局部变量中...// 这意味着函数内部对参数值所做的任何修改都不会影响原始变量。 //原始数据不会被修改,传值调用通常被认为是安全的 //传址调用涉及将参数的内存地址传递给函数。...传值调用:实际上是将参数值复制到函数内部的一个局部变量中,这意味着函数内部对参数值所做的任何修改都不会影响原始变量,原始数据不会被修改 传址调用:涉及将参数的内存地址传递给函数,这意味着函数可以直接访问和修改原始变量
日常开发中,字符串处理是最常见操作之一。C++提供了std::string和char*两种字符串类型。然而,在某些场景下,它们可能会带来性能问题或设计上的局限性。...那std::string_view解决了std::string和char*的什么问题呢 不必要的内存复制:当 std::string 被传递给函数时,通常会发生一次深拷贝操作,即复制整个字符串内容。...return0; } 注意: 在上述代码中,当 std::string 被传递给 process_string 函数时,整个字符串的数据会被复制到该函数的局部变量中。...使用 const char* 传递:使用 const char* 作为参数类型,可以避免不必要的复制。...因此,在使用 std::string_view 时,必须确保其引用的原始数据在整个生命周期内有效。
因此,虽然我们常说是“程序替换”,但实际上更准确地说是将新程序加载到内存中,替换掉原有的程序,以实现进程的功能切换和更新。 程序运行要加载到内存;为什么?冯诺依曼体系规定;如何加载的呢?...它的原型如下: int execle(const char *path, const char *arg, ..., char *const envp[]); path 是要执行的可执行文件的路径,arg...进程程序替换不会替换环境变量的 想要子进程继承全部的环境变量,不用管,直接就能拿到 单纯新增环境变量,在父进程里使用putenv()函数,会影响子进程 putenv 是 C 语言中的一个库函数...,它定义在 头文件中。...int putenv(const char *string); 使用全新的环境变量,就使用execle()函数,那么替换后的代码切换后的环境变量就只是我们传入的表里的内容 也可以调用其他语言的程序 code.c
我们回归到计算机中来,每次房间相当于一个字节,char刚刚好就是一个字符,但酒店也有大房间,有四个字节的int,八个字节的long.....而这些地址在C语言当中就被叫做指针。...定义:解引用操作符(*)用于访问指针所指向的内存地址中存储的值。当使用解引用操作符对指针进行解引用时,实际上是在访问指针所指向的内存单元。...但为什么我们要大费周章的改,不直接对a就行更改呢?有没有意义? 那肯定是有的,对a的修改,多了一种途径,写代码就会更加灵活。...Swap1函数在使⽤ 的时候,是把变量本⾝直接传递给了函数,这种调⽤函数的⽅式我们之前在函数的时候就知道了,这 种叫传值调⽤。 既然传值解决不了问题那只能用传地解决。...递给了函数,这种函数调⽤⽅式叫:传址调⽤。
0; } 二、字符转换函数 C语⾔提供了2个字符转换函数: int tolower ( int c ); //将参数传进去的⼤写字⺟转⼩写 int toupper ( int c ); //将参数传进去的...char * str ); 3.1 使用的注意事项 1、字符串以 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前⾯出现的字符个数(不包含 '\0' )。...-*str2; } 十、strstr的使用和模拟实现 char * strstr ( const char * str1, const char * str2); 10.1 使用的注意事项 1、函数返回字符串...str2在字符串str1中第⼀次出现的位置 2、字符串的⽐较匹配不包含 \0 字符,以 \0 作为结束标志 10.2 strstr的模拟实现 char* my_strstr(const char* str1...strerror函数需要使用error.h的头文件,因为传参传的是erron这个变量,他比较不粗暴,是暂时将该错误信息存储起来,我们可以把它写进文件里,也可以先记录但是暂时不打印,比较灵活。
1 回调函数 回调函数是通过函数指针调用的函数。 如果你把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被用来调用其所指向的函数 时,被调用的函数就是回调函数。...在上一篇中模拟实现加减乘除的计算器中,我们使用了函数指针数组,也就是转移表,这种方法也较为快捷,但是实际上,回调函数也是非常快捷的。...在我们学会回调函数之后,就可以减少代码量,看起来不冗杂了。...2 qsort函数使用及举例 首先我们要知道qsort函数是用来对数据类型排序的,然后在函数的篇目中我们提到,学习一个函数,要从函数的返回类型,返回值,参数个数,参数类型,功能这几个方面去看,这里我推荐的是...但是比较名字的时候我们需要注意了,名字是字符串,我们需要用到strcmp函数,为什么呢?其实你要是模拟实现这个函数也行,可太麻烦了,留给你下来自己试试。
模板中的&&—万能引用 首先我们来看这样一段代码: 这里有4个函数,我们很容易能看出来它们是一个重载的关系 然后我们给这样一个函数模板 大家看这个函数模板的参数,T&& t 这里有两个...模板中的&&不代表右值引用,而是万能引用,其既能接收左值又能接收右值。 我们实例化这个函数模板的时候 可以传左值,也可以传右值。...为什么全部匹配的都是左值引用啊! 那这里为什么会这样呢?...在第一次传递给push_back 的参数,右值的话就调用右值引用版本的push_back ,但是push_back里面调用insert第二次传递,就变成左值了 所以最终不论是右值还是左值的push_back...ch) { string tmp(*this); tmp += ch; return tmp; } const char* c_str() const { return
指针是我们学习C语言中绕不开的一个话题。那么指针究竟是什么?为什么它如此重要?它的用法有哪一些呢?接下来进行指针的详解。 注:接下来针对指针的讲解都基于C语言展开以便于更好的理解。...同理,在64位计算机中就是8个字节。 所以我们可以得知,指针变量的大小取决于地址的大小而不取决于类型。无论是int、char等等,指针变量大小都是一个地址的大小。...(2)传值调用 设想:通过调用函数来打印值 在传值调用中,函数参数的值被复制到函数的形参中。这意味着在函数内部对形参的修改不会影响到实参的值。...如果我们需要解决这个问题,就需要用到传址调用。 结果就是: 在传址调用中,函数参数的地址被传递给函数的形参。这意味着在函数内部对形参的修改会影响到实参的值。...传递给函数的是实参的地址,函数内部对形参的修改会影响到实参。
右值和左值的基本概念 在 C++ 中,表达式的值可以分为左值和右值两种类型: 左值:表示一个持久存在的对象或者内存位置,通常在赋值语句的左侧出现,以及有可以取地址的特性。...在右值引用出现之前,左值引用还是无法解决在某些场景下需要传值返回的问题,而右值引用的出现,实现了移动语义和完美转发,显著提高C++程序在对象的的拷贝和传递的性能。...有人可能会疑惑,为什么右值引用的函数能传入左值a? 因为这里的 && 其实不代表右值引用,当你传左值时,函数会将其识别成左值的引用 T& ,然后触发引用折叠,成为一个左值引用。...输出 "const 右值引用" } 在这个例子中,forwarder(T&& arg) 是一个函数模板,使用了 T&& ,可以接受任何类型的参数(无论左值和右值)。...引用折叠在这里的作用是,确保当我们在模板中使用右值引用时,最终传递给func 的参数是合适的引用类型。 拜拜,下期再见 摸鱼ing✨
) 作用域必须相同 函数重载与函数的返回值无关 哪些情况不构成重载、构成重载 ①顶层const不构成重载,所以下面的两个函数不构成重载 int add(int a,int b); int add(const...常量引用或者常用指针构成重载,所以下面两组函数都构成重载(因为const对象不能转换为其它类型,所以只能将const对象传递给const形参。...下面的代码不规范(不应该在一个函数中声明一个函数)。...但是不能用函数内的局部变量初始化 int a=10; int b=20; char c='a'; void func(int num1=a,int num2=b,char s=c); 注意事项...,main函数中调用到某函数时,跳到栈对应的函数位置,并返回结果 普通函数的调用与内联函数的内存模型 ?
Swap1函数在使用的时候,是把变量本身直接传递给了函数,这种调用函数的方式我们之前在函数的时候就知道了,这种叫传值调用。...那么就可以使用指针了,在main函数中将a和b的地址传递给Swap函数,Swap函数里边通过地址间接的操作main函数中的a和b,并达到交换的效果就好了。...,顺利完成了任务,这里调用Swap2函数的时候是将变量的地址传递给了函数,这种函数调用方式叫:传址调用。...传址调用,可以让函数和主调函数之间建立真正的联系,在函数内部可以修改主调函数中的变量;所以未来函数中只是需要主调函数中的变量值来实现计算,就可以采用传值调用。...如果函数内部要修改主调函数中的变量的值,就需要传址调用。
回调函数 如果你把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被⽤来调⽤其所指向的函数 时,被调⽤的函数就是回调函数 回调函数在指针3的转移表我们就用到了回调函数 回调函数是就一个函数 下面在代码我们可以看到...qsort函数我们需要传4个参数(指向数组第1个元素的指针(首元素),元素个数值,元素类型大小,比较函数) 比较函数的参数为什么使用void*类型呢,因为void*可以接收全部参数,,但是比较数值必须要强制类型转换...排序整行 整行排序我们可以使用减法 返回数值这个函数,为什么要用减法呢 因为x如果大于y,x减y的话就会得到大于0的数字 如果x小于y,x减y就会得到小于0的数值, 等于的话x减y就是0了 //返回数值..., 为什么不用int指针类型的呢,因为如果用int的话,加1跳过4个字节,我们交换char类型的时候,char是1个字节,如果我们用int就会跳4个字节,所以我们要用char指针类型的 size_f是类型大小...,这数组是int指针类型的我们就需要循环4次 //比较函数 int fh(const void*x,const void*y) { //强制类型转换成char*然后解引⽤ return (*(char
指针的使用和传址调用 8.1 strlen的模拟实现 库函数strlen的功能是求字符串⻓度,统计的是字符串中 \0 之前的字符的个数。...Swap1函数在使用 的时候,是把变量本身直接传递给了函数,这种调用函数的方式叫传值调用。 结论:实参传递给形参的时候,形参会单独创建⼀份临时空间来接收实参,对形参的修改不影响实 参。...那么就可以使用指针了,在main函数中将a和b的地址传递给Swap函数,Swap 函数里边通过地址间接的操作main函数中的a和b,并达到交换的效果就好了。...,顺利完成了任务,这里调用Swap2函数的时候是将变量的地址传递给了函数,这种函数调用方式叫:传址调用。...传址调用,可以让函数和主调函数之间建立真正的联系,在函数内部可以修改主调函数中的变量;所 以未来函数中只是需要主调函数中的变量值来实现计算,就可以采用传值调用。
还有一点:C语言中的一切函数调用中,实参传递给形参的机理都是“按值传递(pass by value)”,如果我们要在函数中修改被传递过来的对象,就必须通过这个对象的指针来完成。 指针是什么?...空指针 指向空,或者说不指向任何东西。在C语言中,我们让指针变量赋值为NULL表示一个空指针,而C语言中,NULL实质是 ((void*)0) , 在C++中,NULL实质是0。...当把数组名赋值给一个指针后,再对指针使用sizeof运算符,返回的是指针的大小。 这就是为什么我么将一个数组传递给一个函数时,需要另外用一个参数传递数组元素个数的原因了。...函数的参数和指针 C语言中,实参传递给形参,是按值传递的,也就是说,函数中的形参是实参的拷贝份,形参和实参只是在值上面一样,而不是同一个内存数据对象。...这就意味着:这种数据传递是单向的,即从调用者传递给被调函数,而被调函数无法修改传递的参数达到回传的效果。
1.左值引用 在C++中,左值引用和右值引用是用来声明变量的引用类型的两种方式。...右值可以用于初始化一个变量、传递给函数或者返回给调用者。 右值具有如下特点: 右值可以是字面量、临时对象、表达式的结果或者一些函数的返回值。 右值没有持久性,它们不能出现在赋值运算符的左侧。...,出了函数作用域就不存在了,就不能使用左值引用返回,只能传值返回。...例如:将整型转换为string类型的函数:string to_string(int value)函数中可以看到,这里只能使用传值返回,传值返回会导致至少1次拷贝构造(如果是一些旧一点的编译器可能是两次拷贝构造...const左值引用可以引用右值,右值引用可以引用move后的左值;右值一般是临时对象,是将亡值,所以我们就可以在类中专门写一个供右值对象使用的拷贝构造和赋值重载函数,来置换它们的资源,从而减少不必要的深拷贝
领取专属 10元无门槛券
手把手带您无忧上云