c语言指针

数据结构(二) -- 数组和链表

一曲冷凌霜 提交于 2020-02-13 14:04:37
/*--> */ /*--> */ /*--> */ /*--> */ 数据结构(二) -- 数组和链表 数据结构主要可以分为两大模块: 线性结构 非线性结构 本文主要开始讲线性结构。 什么是线性结构 线性结构,顾名思义,就是这些数据所有节点都能被一根线(指针)联系起来的一种结构。 线性结构的存储方式: 连续存储:【数组】 离散存储:【链表】 线性结构的常见应用方式: 栈 队列 专题 :【递归】 数组和链表 本小节学习数组和链表,从底层去了解和实现数组与链表,并分析两者对应的优缺点 数组 数组是最常见的链式存储结构,它是一段连续的内存空间,在内存中我们可以简单表示为下图样式 通过上图我们可以把代码中 int arr[6] = {1,2,3,4,5,6}; 执行的操作从内存中脑补出来,同时我们可以简单分析一下,数组应该有的一些基本使用。如 初始化、 添加新元素、 插入新元素、 删除某个元素、 判断是否为空数组、 是否是满数组、 排序 倒序 查询是否包含某个元素 ······ 本小节就带着你手把手实现一个简单的数组的封装,借此来了解数组的数据结构以及内部的一些基本算法知识。这里就简单的以一个 int 类型的数组来示例,后面学到泛型的时候便可更加好的理解数组的实现。 首先简单分析一下数组中基本的属性,我们有上面的数组内存中的逻辑图可以确定数组有对应的内存空间,有一个内存起始地址

c++之智能指针,异常处理,枚举

拈花ヽ惹草 提交于 2020-02-13 11:15:32
智能指针,文件IO 二、智能指针&动态内存 1. 指针潜在问题 c++ 把内存的控制权对程序员开放,让程序显式的控制内存,这样能够快速的定位到占用的内存,完成释放的工作。但是此举经常会引发一些问题,比如忘记释放内存。由于内存没有得到及时的回收、重复利用,所以在一些c++程序中,常会遇到程序突然退出、占用内存越来越多,最后不得不选择重启来恢复。造成这些现象的原因可以归纳为下面几种情况: 野指针: 内存已经被释放、但是指针仍然指向它。这时内存有可能被系统重新分配给程序使用,从而会导致无法估计的错误 重复释放:程序试图释放已经释放过的内存,或者释放已经被重新分配过的内存,就会导致重复释放错误. 内存泄漏: 不再使用的内存,并没有释放,或者忘记释放,导致内存没有得到回收利用。 忘记调用delete 随着多线程程序的广泛使用,为了避免出现上述问题,c++提供了智能指针,并且c++11对c++98版本的智能指针进行了修改,以应对实际的应用需求。 2. 智能指针 在98版本提供的 auto_ptr 在 c++11得到删除,原因是拷贝是返回左值、不能调用delete[] 等。 c++11标准改用 unique_ptr | shared_ptr | weak_ptr 等指针来自动回收堆中分配的内存。智能指针的用法和原始指针用法一样,只是它多了些释放回收的机制罢了。 智能指针位于 头文件中

必会,详细剖析11道嵌入式Linux C语言面试题

丶灬走出姿态 提交于 2020-02-13 00:43:15
预处理器(Preprocessor) 1 . 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题) 答: #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL 我在这想看到几件事情: 1) #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等) 2) 懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。 3) 意识到这个表达式将使一个16位机的整型数溢出, 因此要用到长整型符号L, 告诉编译器这个常数是长整型数。 4) 如果你在表达式中用到UL(表示无符号长整型),那么可能这就给面试者留下了很好的第一印象。记住第一印象很重要。 2 . 写一个"标准"宏MIN ,这个宏输入两个参数并返回较小的一个。 答: #define MIN(A,B) ((A) <= (B) ? (A) : (B)) 这个测试是为下面的目的而设的: 1) 标识#define在宏中应用的基本知识。这是很重要的。因为在 嵌入(inline)操作符 变为标准C的一部分之前,宏是方便产生嵌入代码的唯一方法,对于嵌入式系统来说,为了能达到要求的性能,嵌入代码经常是必须的方法。 2) 懂得在宏中小心地把参数用括号括起来 3) 我也用这个问题开始讨论宏的副作用,例如

【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;

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

C++面向过程编程

試著忘記壹切 提交于 2020-02-11 18:47:55
前言 C语言是面向过程的编程语言,C++是面向对象的编程语言,这是两种不同的编程语言。C语言是C++的子集,C++是C语言的超集,C++进一步扩充和完善了C语言,其中大部分是对于面向对象编程的拓展。C++既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行以继承和多态为特点的面向对象的程序设计。 从“Hello world!”讲起 传承学习编程语言的优良传统,我们来写一段“Hello world!”: #include <iostream> using namespace std; int main() { cout << "Hello World"; return 0; } 类 类(class)是用户自定义的数据类型,是一种构造类型,与C语言结构体类似,但是进行了一些扩展,类的成员不但可以是变量,还可以是函数,通过类定义出来的变量也有特定的称呼,叫做“对象”。类一般分为两部分,分别写在不同的文件当中,其一是头文件,用来声明这种类所提供的功能,另一个文件包含了完成这些操作的代码。想要使用类,就必须现在程序中包含头文件。 标准“输入/输出库” 在 C++ 标准的“输入/输出库”名为“ iostream ”,iostream 这个单词是由3个部分组成的,即 i-o-stream ,意为输入输出流。在 iostream

c++ new 与malloc有什么区别

◇◆丶佛笑我妖孽 提交于 2020-02-11 09:26:03
转自:https://www.cnblogs.com/ywliao/articles/8116622.html new与malloc的10点区别 1. 申请的内存所在位置 new操作符从自由存储区(free store)上为对象动态分配内存空间,而malloc函数从堆上动态分配内存。自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区。而堆是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分配,C语言使用malloc从堆上分配内存,使用free释放已分配的对应内存。 那么自由存储区是否能够是堆(问题等价于new是否能在堆上动态分配内存),这取决于operator new 的实现细节。自由存储区不仅可以是堆,还可以是静态存储区,这都看operator new在哪里为对象分配内存。 特别的,new甚至可以不为对象分配内存!定位new的功能可以办到这一点: new (place_address) type place_address为一个指针,代表一块内存的地址。当使用上面这种仅以一个地址调用new操作符时,new操作符调用特殊的operator new,也就是下面这个版本: void * operator new (size_t,void *) //不允许重定义这个版本的operator new

C语言指针总结

╄→尐↘猪︶ㄣ 提交于 2020-02-11 07:15:44
C语言中的精华是什么,答曰指针,这也是C语言中唯一的难点。 C是对底层操作非常方便的语言,而底层操作中用到最多的就是指针,以后从事嵌入式开发的朋友们,指针将陪伴我们终身。 本文将从八个常见的方面来透视C语言中的指针,当然,还有其他没有具体提到的方面,像指针表达式、指针安全等问题,以后有机会我再慢慢补充。 还是那句老话,重要的是实践,多写代码,才是学好C语言的关键。 1.指针类型分析 分析指针,可以从变量名处起,根据运算符优先级结合,一步一步分析. int p; //这是一个普通的整型变量 int *p; //首先从P处开始,先与*结合,所以说明P是一个指针,然后再与int结合,说明指针所指向的内容的类型为int 型.所以 P是一个返回整型数据的指针 int p[3]; //首先从P处开始,先与[]结合,说明P 是一个数组,然后与int结合,说明数组里的元素是整型的,所以 P是一个由整型数据组成的数组 int *p[3]; //首先从P处开始,先与[]结合,因为其优先级比*高,所以P是一个数组,然后再与*结合,说明数组里的元素是指针类型,然后再与 int结合,说明指针所指向的内容的类型是整型的,所以是一个由返回整型数据的指针所组成的数组 int (*p)[3]; //首先从P处开始,先与*结合,说明P是一个指针然后再与[]结合(与"()"这步可以忽略,只是为了改变优先级)

C语言 ---- 指针 iOS学习-----细碎知识点总结

萝らか妹 提交于 2020-02-11 07:15:27
内存的访问形式:1、直接访问:通过变量名进行访问。2、间接访问:先找到变量存放的地址,然后根据地址去访问对应的内存空间。 指针--- // 定义一个整形指针变量,用来存储num1在内存中的地址 int *p = NULL; // 定义一个整形指针变量,指向0x0,NULL恒等于0 printf("%p\n", p); // 输出指针变量的值,使用"%p" printf("&num1 = %p\n", &num1); // 取址运算符,取得变量所在的内存地址 p = &num1; // 给整形指针变量重新赋值 printf("p = %p\n", p); printf("*p = %d\n", *p); // "*"取值运算符,取出地址里面存储的数据 // 当我们定义指针变量的时候,"*"只是起一个标识作用,告诉我们这个变量是一个指针变量。 // 当我们使用指针变量的时候,"*"表示的是从当前地址里面取出存储的数据。 // 指针的算术运算,只有加和减 int num1 = 100; int num2 = 200; int *p = &num2; printf("*p = %d\n", *p); printf("*(p + 1) = %d\n", *(p + 1)); // p + 1是指针向高位移动n个字节,n指的是指针指向的数据类型所占有的字节数(int *p移动4个字节,