指针

为什么返回值为数值时,返回局部变量可以。而返回值为引用时,不能返回局部变量

99封情书 提交于 2020-02-12 21:07:41
最重要的一点: 函数不能返回指向栈内存的指针! https://blog.csdn.net/weixin_40539125/article/details/81367466 为什么? 因为返回的都是值拷贝! 一般的来说,函数是可以返回局部变量的。 局部变量的作用域只在函数内部,在函数返回后,局部变量的内存已经释放了。因此,如果函数返回的是局部变量的值,不涉及地址,程序不会出错。但是如果返回的是局部变量的地址(指针)的话,程序运行后会出错。因为函数只是把指针复制后返回了,但是指针指向的内容已经被释放了,这样指针指向的内容就是不可预料的内容,调用就会出错。准确的来说,函数不能通过返回指向栈内存的指针(注意这里指的是栈,返回指向堆内存的指针是可以的)。 我们知道,局部变量的作用域是函数内部,函数一旦执行结束,栈上的局部变量会进行销毁,内存得到释放。因此,此时函数返回的是该局部变量的值拷贝,这是没有问题的。但是如果返回的是局部变量的地址,那么返回的只是该局部变量指针的拷贝,而随着函数运行结束,该拷贝指针所指向的栈内存已经被释放,那么指向一个未知区域就会导致调用的错误。 那如果返回的指针指向的是堆内存,又会怎么样? 这样的使用是没有问题的,在函数内new空间,在函数外delete空间。但是这样并不是一种好的编程风格,尽量在同一个作用域内进行new和delete操作

C/C++ C++11智能指针

*爱你&永不变心* 提交于 2020-02-12 12:21:12
在使用基本指针类型时,因为要手动释放指针指向的内存,常常容易造成内存泄漏,特别是异常分支很多的情况下。而智能指针类型就是将基本指针类型封装成模板类,以便更好地管理内存。 智能指针都包含一个explicit构造函数,因此基本指针类型不能隐式转换成智能指针,需要显式调用。 shared_ptr<double> sp_d; double *p_d = new double; sp_d = p_d; // 错误,隐式转换。 sp_d = shared_ptr<double>(p_d); // 正确,显式转换。 shared_ptr<double> sp_d = p_d; // 错误,隐式转换。 shared_ptr<double> sp_d(p_d); // 正确,显式转换。 1、auto_ptr 1)由C++98提出,C++11中已经弃用。 std::auto_ptr<int> sp_i1(new int); *sp_i1 = 10; std::auto_ptr<int> sp_i2 = sp_i1; // 所有权转给sp_i2,sp_i1变成空指针 std::cout << *sp_i1 << std::endl; // 运行崩溃 2、shared_ptr 3、weak_ptr 4、unique_ptr 引用计数 循环引用 /*--> */ /*--> */ 来源: https:/

【C语言】函数指针扫盲

限于喜欢 提交于 2020-02-12 11:44:33
首先看看函数指针,函数名,以及它们分别与*和&结合后的值 程序清单 #include<stdio.h> void func(void){puts("成功调用");}; int main() { void(*p_func)(void)=func; puts("func是函数名,p_func是指向该函数的指针,那么有:"); printf("func=%p\n*func=%p\n&func=%p\ \np_func=%p\n*p_func=%p\ \n&p_func=%p",func,*func,&func,p_func,\ *p_func,&p_func); //puts("\n接着我们尝试用上述变量调用函数:"); //func(); //(*func)(); //(&func)(); //(p_func)(); //(*p_func)(); return 0; } 执行结果 func是函数名,p_func是指向该函数的指针,那么有: func=004015C0 *func=004015C0 &func=004015C0 p_func=004015C0 *p_func=004015C0 &p_func=0061FECC 可见==func==,== func==,==&func==,==p_func==,== p_func==代表的值都是func()函数的地址 ( &p

C++ 引用总结

丶灬走出姿态 提交于 2020-02-12 07:51:43
一、 概念 引用( reference )是 c++ 对 c 语言的重要扩充;引用就是某一变量或对象的一个别名,对引用的操作与对变量直接操作完全一样 。 二、 语法 格式为: 类型 & 引用变量名 = 已定义过的变量名 例如: int a; int &b = a; //b 即 a 的引用(别名) 三、 特点 一个变量可取多个别名。 引用必须初始化。 引用只能在初始化的时候引用一次 ,不能更改为转而引用其他变量。 操作引用就是操作对象本身,反之亦然 数组没有引用 void 没有引用 四、 用法 基础引用 void TestReference1 () { int a = 1; int & b = a; cout<<"a:address->" <<&a<< endl; cout<<"b:address->" <<&b<< endl; a = 2; b = 3; int & c = b;// 引用一个引用变量,别名的别名 c = 4; } const 引用 void TestReference2 () { int d1 = 4; const int & d2 = d1; d1 = 5;//d1改变,d2的值也会改变。 //d2 = 6;//不能给常量(不能被修改的量)赋值。 const int d3 = 1; const int & d4 = d3; //int&d5 = d3;

新手学习python(五)文件操作

孤者浪人 提交于 2020-02-12 03:16:40
文件有利于数据的长久保存,因此文件操作是一个比较重要的操作。 文件打开有三种方式:读模式(默认)‘r’,写模式'w',追加模式‘a’。 再加三种双重操作模式:读写模式‘r+’,写读模式‘w+’,追加读写模式‘a+’。 ========================================================== 具体说下这6种模式的不同: 读模式 r :以只读方式打开文件。文件指针将会放在文件的开头。这是默认模式。(文件不能写入,文件不存在的时候,会报错) 写模式 w:打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。(文件不能读) 追加模式 a:打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。(文件不能读) 读写模式 r+:打开一个文件用于读写。文件指针将会放在文件的开头。 写读模式 w+:打开一个文件用于读写。如果该文件已存在,将其覆盖(即会清空文件之前的内容)。如果该文件不存在,将创建新文件。 追加读写模式 a+ :打开一个文件用于读写。如果该文件已经存在,文件指针放在文件的末尾,文件打开会是追加模式。如果该文件不存在,创建新文件用于读写。 ====================================== f

C++总结(二)

ε祈祈猫儿з 提交于 2020-02-12 02:31:24
一、this指针 1、概念 :类非静态成员函数的第一个隐藏的参数,该参数使用指向调用当前函数的对象 2、特性 : this指针类型:T* const 普通类型成员函数:T* const 可以修改对象的内容,可以调用普通和const类型的成员函数 const类型成员函数:const T* const:this指向不能修改并且指向对象中的内容也不能修改,只能调用const类型的成员函数 this是非静态成员函数的第一个隐藏参数,隐藏:用户在编写函数时不用给出this的参数,该参数是编译器自己维护,调用该函数也不需要手动传递,this指针的传参也是编译器自己进行 this指针只存在于正在运行的成员函数中,this指针不会存在于对象中,不会影响类对象的大小 静态成员函数:没有this指针 this指针的传递:一般情况exc寄存器(this_call:调用约定),也可能通过参数压栈的方式进行传递:push 对象地址(比如:类中如果包含不定参数的成员函数) 3、this指针是否可以为NULL 如果成员函数是通过对象的方式进行调用,this指针一定不会为NULL: 如果成员函数是通过类类型的指针方式进行调用,this指针可能会为NULL: 4、this指针位置:栈 类的编译过程: 1、识别类名 2、识别类中的成员 3、识别类中的成员函数,并对成员函数进行改写 二、类中六个默认的成员函数 1

初见Python<6>:文件读写

青春壹個敷衍的年華 提交于 2020-02-12 01:20:57
1、open函数语法: python通过open函数打开文件,建立程序与文件之间的连接。 open函数语法:open(filename[,mode[,buffering]]) 其中filename是指要进行操作的文件名称,由文件名称和路径组成,需要加引号。 mode为操作模式参数,包括读、写、追加等。 buffering是缓冲参数,控制着文件的缓冲。当buffering=0或者False时,I/O就是无缓冲的,所有的读写操作都是直接针对硬盘的,如果是1或者True,I/O就是有缓冲的,python是用内存来代替硬盘,使得程序运行更快。大于1代表缓冲区的大小,单位为字节,-1或者其他任意负数代表使用默认的缓冲区大小。 只有filename参数是必须指定的,mode和buffering参数则是可选的,mode参数的缺省值为'r'。 2、参数mode的取值: (1)基本取值: r、w、a为打开文件的基本模式,分别表示只读、只写(覆盖写)、追加(追加写)。 b、t、+、U,与上面三个基本模式组合使用。 注意:文本模式用于打开文本文件,二进制模式用户打开二进制文件。 (2)常见的mode组合取值: (3)举例说明: 现在window系统PC机硬盘上存在文件G:\file1.txt,对其进行演示操作。 ①r模式: 报错的原因是路径中包含的'\'被识别为转义符,因此造成文件路径错误。

LeetCode All in One 题目讲解汇总(持续更新中...)

谁说我不能喝 提交于 2020-02-12 00:23:10
A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null. Return a deep copy of the list. Example 1: Input: {"$id":"1","next":{"$id":"2","next":null,"random":{"$ref":"2"},"val":2},"random":{"$ref":"2"},"val":1} Explanation: Node 1's value is 1, both of its next and random pointer points to Node 2. Node 2's value is 2, its next pointer points to null and its random pointer points to itself. Note: You must return the copy of the given head as a reference to the cloned list. 这道链表的深度拷贝题的难点就在于如何处理随机指针的问题,由于每一个节点都有一个随机指针

指针求两个有序数组的第一个相同元素

此生再无相见时 提交于 2020-02-12 00:20:36
first common element // 给定两个递增有序表,输出两表第一个相同的元素 # include <stdio.h> # include <string.h> int * fst_common_val ( int * a , int an , int * b , int bn ) { int * ptra , * ptrb ; ptra = a ; ptrb = b ; while ( ptra < a + an && ptrb < b + bn ) { if ( * ptra < * ptrb ) ptra ++ ; else if ( * ptra > * ptrb ) ptrb ++ ; else return ptra ; } return ptra ; } int main ( ) { int * a [ ] = { 1 , 3 , 5 , 7 , 9 , 11 , 13 , 17 , 19 } ; int * b [ ] = { 2 , 4 , 6 , 8 , 11 , 56 , } ; int * value ; int ( * func ) ( ) ; func = fst_common_val ; printf ( "the elements of a are: \n" ) ; for ( int i = 0 ; i < sizeof ( a )

LeetCode All in One 题目讲解汇总(持续更新中...)

走远了吗. 提交于 2020-02-12 00:17:17
You are given a circular array nums of positive and negative integers. If a number k at an index is positive, then move forward k steps. Conversely, if it's negative (- k ), move backward k steps. Since the array is circular, you may assume that the last element's next element is the first element, and the first element's previous element is the last element. Determine if there is a loop (or a cycle) in nums . A cycle must start and end at the same index and the cycle's length > 1. Furthermore, movements in a cycle must all follow a single direction. In other words, a cycle must not consist of