变量类型为 char *,表示该变量是一个指向字符型数据的指针。我们可以通过 *str 来访问该指针所指向的内存单元中存储的值。 ...数组指针的应用 1.指向已有数组的指针 int arr[5]; int (*ptr)[5] = &arr ; 在该例子中,我们首先定义了一个整型数组arr,然后使用&arr获取该数组的地址,并将其赋值给指针变量...指针数组的声明 type *array_name[size]; 其中,type是指针数组中每个元素的类型,array_name是指针数组的名称,size是数组的大小。...int(*parr)[10] = &arr;//parr是指向数组的指针,存放的是数组的地址 int (*pf)(int, int) = &Add;//pf就是一个函数指针变量 return 0;...函数指针数组的初始化 函数指针的说明 return_type (*array_name[size]) 其中,return_type 是函数指针所指向函数的返回值类型,array_name 是函数指针数组的名称
通过简洁的下标索引,我们可以快速定位和访问其中的任意元素,如同在仓库中精准找到特定的货物一般便捷。 而函数,则是 C 语言的灵魂所在。...数组基础 2.1 数组的定义与初始化 数组是同类型数据的集合,可以使用以下语法定义和初始化数组: type array_name[size]; 示例代码 #include int...如果未完全初始化,未赋值的元素默认为0。...%d][%d] = %d\n", i, j, matrix[i][j]); } } return 0; } 2.4 数组与指针的关系 数组名本质上是指向第一个元素的指针...); printf("num = %d\n", num); // 输出 10 return 0; } 指针传递 函数接收的是指针,能修改原值。
它表示signal是一个函数,接受两个参数:一个int类型的参数和一个指向接受int类型参数并返回void的函数指针的参数。...该函数返回一个指向接受int类型参数并返回void的函数指针的结果 二.函数指针数组 1.讲解与实例 函数指针数组: 函数指针数组是一个数组,其中的每个元素都是一个函数指针。...(*array_name):函数指针数组的名称。它是一个指针,指向一个数组。 [size]:函数指针数组的大小。它表示数组中函数指针的数量。...指向函数指针数组的指针是一个 指针,指针指向一个数组 ,数组的元素都是函数指针 指向函数指针数组的指针的语法如下: return_type (*(*pointer_name)[size]...如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。
指针数组 1.1 基本概念 指针数组是指一个数组,其中的每个元素都是指针。 这意味着数组中的每个元素都存储一个地址,该地址指向内存中的某个位置。...指针数组的声明形式为: data_type *array_name[size]; //示例: int *p[10];//该指针数组包含10个整型地址 1.2 简单示例 以下是一个简单的示例,演示了如何声明和使用指针数组...1. main函数的原型通常定义为 int main(int argc, char *argv[]); 说明: 其中,argc 表示命令行参数的数量,argv 是一个指针数组,每个元素都是一个指向以 null...如果main函数带参数的话,则第一个参数必须是int型,第二个参数必须是字符指针数组 char *xx[],参数只能由操作系统给出。...2.2 简单示例 下面例子中,argc 表示命令行参数的数量,而 argv 是一个指针数组,其中每个元素都是一个指向字符串的指针。程序通过循环遍历 argv 数组,输出每个命令行参数的内容。
不能 shared_ptr vs weak_ptr shared_ptr 使用条件:有多个使用者共同使用同一个对象 假如 一个类成员 是指针,这个普通类 可以被值拷贝。...一个类成员 是指针是浅拷贝,避免更大开销 可以使用shared_ptr 多线程多读少写 读写一致性 利用shared_ptr和互斥锁来模拟读写锁 shared_ptr 不使用条件(需要改写):双向链表...对象所有权 在编程语言中,对堆对象的内存管理是一个麻烦又复杂的问题。一不小心就会带来问题(堆上数据通过指针来访问。) C++里多个变量指向同一块内存导致重复释放。..., 为什么发明三个 而不是一个,来一统天下。 unique_ptr 代替全部原始指针吗? 答:不是的,如果使用不当会造成 core 或者 不执行析构函数。 在类的成员,或者函数参数传递。...boost\smart_ptr\weak_ptr.hpp 如果 weak_ptr 指向某一 shared_ptr 指针拥有的堆内存, 则 weak_ptr 也指向该块存储空间(可以访问,但无所有权) weak_ptr
,而不是单引号 ',不要看错了哦。...以下是一个基本的 while 循环,测试条件是:如果 int 小于等于 5,那么条件返回真。int 从 1 开始,每次循环处理时,int 加 1。运行上述脚本,返回数字 1 到 5,然后终止。...-gt 检测左边的数是否大于右边的,如果是,则返回 true。 -lt 检测左边的数是否小于右边的,如果是,则返回 true。...-ge 检测左边的数是否大于等于右边的,如果是,则返回 true。 -le 检测左边的数是否小于等于右边的,如果是,则返回 true。 使用示例如下: #!...4、 修改指针 $ var=100 $ ptr=var $ eval echo \$$ptr 100 $ eval $ptr=50 $ echo $val 50
ptr 是一个指向对象的指针,而 *ptr 表示指针所指向的对象。因此,ptr 和 *ptr 的意思是不同的。 当你想通过指针访问对象的成员时,可以使用 -> 运算符。...为什么对象指针需要解引用,而对象引用就不需要 对象指针和对象引用的工作方式不同。对象指针存储的是对象的地址,而不是对象本身。...因此,当你想通过指针访问对象时,需要先解引用指针,才能获取指针所指向的对象。 例如,假设你有一个指向 MyClass 对象的指针 ptr。...如果你想通过引用访问该对象的 x 成员,可以直接这样写: int a = ref.x; 为什么->运算符可以简化代码 -> 运算符是一种特殊的运算符,用于通过指针访问对象的成员。...C++风格 而C++程序员在“类型”中思考 int* pValue; 读取“pValue 的类型是指向 int 的指针”。 当然,编译器完全没有看到任何区别。
智能指针/迭代器……采用浅拷贝的原因:本质资源不是自己的,代为持有,方便访问修改数据。他们拷贝的时候期望指向同一个资源,所以浅拷贝!...不可以,我们这里要求每份资源分配一个计数,而这里是每指向一份资源调用的智能指针就分配一个计数,也就是我们要求的是公共计数,而不是每个智能指针单独的计数。 可以采用静态成员变量来解决这个问题吗?...而我们的需求是每个资源配一个引用计数,而不是全部是一个引用计数。...所以这里只释放了一份资源,另一份资源没有释放 正确的解法是每个对象存一个指向计数的指针,而指针指向的内容只在构造的时候进行初始化构造单独这一份,拷贝的时候,++计数,智能指针析构的时候--计数,只有当引用计数减到...其实也并不是。 很坑的赋值重载函数 这里的sp1 = sp4,会将sp1的指针指向sp4指向的资源,但是原来sp1指向的资源需要--引用计数,不然会引起内存泄露!!!
: 0xc000048080 *ptr 指针的值: 100 *ptr 指针的值: 200 *ptr 没有操作,为什么值发生了变化 ptr 是指针类型,并被赋予了 num 的内存地址,当num值发现变化时...指针说明 (1) 指针:指针是一个变量,只不过这个变量存储的是一个地址,指向内存的一个“存储单元”,即指针是一个实体;而引用跟原来的变量实质上是同一个东西,只不过是原变量的一个别名而已。...如: int a=1; int *p=&a; 上面2 行代码,定义了一个整形变量和一个指针变量p,该指针变量指向a的存储单元,即p的值是a存储单元的地址。...1.值引用赋值 比如 a:=b,这样修改a.name=“ls”,不会影响到b.name,值引用是复制结构体,开辟一块新的内存空间, a只是b的一个副本,而不是指向b的引用。...总结2:值引用只是复制的一个副本,不是指向内存地址的引用;指针引用,指针是指向内存地址的引用,因此使用它操作的不是结构体的副本而是本身。
《为何优先选用unique_ptr而不是裸指针?》中说到,如果有可能就使用unique_ptr,然后很多时候对象是需要共享的,因此shared_ptr也就会用得很多。...下面是三种常见的定义方式: shared_ptrint> sp;//声明一个指向int类型的智能指针 sp.reset(new int(42)); auto sp1 = make_shared("hello");//sp1是一个智能指针 shared_ptr sp2(new int(42)); 而make_shared方式是推荐的一种,它使用一次分配,比较安全。...关于参数传值的问题,可以参考《传值与传指针》和《令人疑惑的引用和指针》。 reset 调用reset会减少计数: sp.reset() 而如果sp是唯一指向该对象的,则该对象被销毁。...*/ delete p;/*不要这样做*/ return 0; } 如果对象不是new分配的,请传递删除器 与unique_ptr类似,它可以指定删除器,默认是使用delete。
指针指向一个变量的内存地址。使用指针可以使很多操作变得简单,但同样提高了编程的难度和程序的可读性。C语言的指针是使得很多初学者头疼的一个重要点。...那么p1就是一个指针的指针。 Go语言的指针概念上基本等同于C语言的指针,写法上也完全一致,同样使用*标识,同样使用&作为取地址运算符。我想指针和结构体,是为什么Go被称为类C语言的原因。...你可以把nil看作一个特殊的值,而不是一种类型。...{ fmt.Println("p1是空指针") } else { fmt.Println("p1不是空指针") } } // p1指向的地址为:0 // p1是空指针 指针数组 指针数组指的是数组的元素类型是指针...++ { fmt.Printf("arr[%d]的地址是%x,存储的值是%d\n", i, ptr[i], *ptr[i]) } } 指针的指针 如果一个指针变量存放的是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量
: 1) #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等) 2) 懂得预处理器将为你计算常数表达式的值,因此直接写出你如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的...如果一个应试者给出这个作为方案,我将用这个作为一个机会去探究他们这样做的基本原理。 如果他们的基本答案是:"我被教着这样做,但从没有想到过为什么。"这会给我留下一个坏印象。...a) 一个整型数(An integer) b)一个指向整型数的指针( A pointer to an integer) c)一个指向指针的的指针,它指向的指针是指向一个整型数( A pointer to...第三个意味着a是一个指向常整型数的指针。 第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)。 最后一个意味着a是一个指向常整型数的常指针。...这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码: int square(volatile int *ptr) {
另外,同一个类实例化出来多个对象,它们是共用一张虚函数表的,如果每个对象里面都放一张虚函数表,是不是有点浪费啊。 它们的虚函数指针都是一样的,指向同一张虚函数表。 2....那第二个为什么必须是父类的指针或引用去调用虚函数呢? 因为父类的指针和引用是不是既可以指向子类对象,也可以指向父类对象啊,我们之前学过,它支持赋值转换(切片)嘛。...所以this指针应该指向子类对象的起始地址,那现在ptr1刚好就指向子类对象的起始,所以它可以直接去正常的调,而ptr2的指向是不是不对啊,他现在指向子类对象中父类Base2部分的起始位置。...所以要对ptr2的指向进行修正。 而上面的sub ecx ,8这句汇编其实就是在修正this指针的位置。...sub这个指令用于执行减法操作,所以它的意思是给this指针-8,而ptr2现在执行Base2,它前面有一个base1,Base1这个类的大小刚好就是8,这样一减,刚好就指向子类对象的起始位置了。
3.指针的值----或者叫指针所指向的内存区或地址 指针的值是指针本身存储的数值,这个值将被编译器当作一个地址,而不是一个一般的数值。...如果上例中,ptr 是被减去5,那么处理过程大同 小异,只不过ptr 的值是被减去5 乘sizeof(int),新的ptr 指向的地址将比原来的ptr 所指向的地址向低地址方向移动了20 个字节。...好了,当一个指针表达式的结果指针已经明确地具有了指针自身占据的内存的话,这个指针表达式就是一个左值,否则就不是 一个左值。在例七中,&a 不是一个左值,因为它还没有占据明确的内存。...[10],但如果把array 看做指针的话,它指向数组的第0 个单元, 类型是int* 所指向的类型是数组单元的类型即int。...实际上,sizeof(对象)测出的都是对象自身的类型的大小,而不是别的什么类型的大小。
还有一个例子,Java 中往容器中放对象,实际放入的是引用,不是真正的对象,而 C++ 在 vector 中 push_back 采用的是值拷贝。...这样两个指针将指向不同的对象,其中的一个对象是另一个对象的副本,缺点是浪费空间,所以智能指针都未采用此方案。 建立所有权(ownership)概念。...如果你的编译器没有提供 shared_ptr,可使用 Boost 库提供的 shared_ptr。 (2)如果程序不需要多个指向同一个对象的指针,则可使用 unique_ptr。...如果函数使用 new 分配内存,并返还指向该内存的指针,将其返回类型声明为 unique_ptr 是不错的选择。...另外,如果按值而不是按引用给 show() 传递对象,for_each() 将非法,因为这将导致使用一个来自 vp 的非临时 unique_ptr 初始化 pi,而这是不允许的,编译器将发现错误使用 unique_ptr
如果不是知道这里用的是一个函数指针,乍一看想要看明白估计不太容易。...到这里还没结束,还有更恐怖的,如果我们想要定义一个指向这个数组的指针,应该怎么办呢?如果使用auto可以写成: auto ptr = &pt; 如果不使用auto呢?...首先我们可以想到,这个声明是基于pt的,我们需要在pt的声明上加上一个*,但问题是加在哪里呢? 进一步分析,会发现我们需要指出这是一个指针,而不是数组。...意味着核心的部分应该写成(*ptr)[3],表示这是一个指向长度为3的数组的指针。因为[]的优先级更高,所以需要使用括号。如果写成*ptr[3]表示这是长度为3的指针数组。...而且这还不是最复杂的情况,比如函数的返回类型又是一个指向一个函数的指针……明摆着告诉我们含义我们仍然要推敲一会,如果在一段不明的代码当中遇到,可能会直接抓狂吧…… 也正因此,C++11当中推出了auto
左值一样,导致原来的自定义对象变为空了,这就不是将亡值的施舍了,是活生生的夺舍: 就像文档里面提到的,推荐使用unique_ptr而不是auto_ptr,因为是指针,所以需要重载函数使得该类有指针的对应行为...在C++11引入智能指针的时候就借鉴了boost的智能指针,但是有一个指针改了一个名,scoped_ptr改成了unique_str,为什么改呢,咱也不知道,学就完事儿了。...每创建一个对象就++一次,看起来好像可以,但是我们如果指向的空间不是一个呢?new了两个空间,就会导致两个空间公用一个计数,更不行了。...所以解决办法是创建一个指针,每创建一个对象,指针指向的空间,即计数空间就++: template class shared_ptr { public: shared_ptr(T* ptr...; std::atomicint>* _pcount; 还有一个问题就是,如果是交叉指向,就会导致无法析构: struct Node { //std::shared_ptr _next
因为此时p2指向p1的内存地址,而p1则改为指向其他地址(实测指向0地址) unique_ptr (替换auto_ptr)unique_ptr实现独占式拥有或严格拥有概念,保证同一时间内只有一个智能指针可以指向该对象...为了解决循环引用导致的内存泄漏,引入了弱指针weak_ptr,weak_ptr 是一种不控制对象生命周期的智能指针, 它指向一个 shared_ptr 管理的对象....把类A里面的shared_ptr pb_,改为weak_ptr pb_即可 12、野指针 野指针就是指向一个已删除的对象或者所指向的空间是访问受限的空间的指针。...为什么C++默认的析构函数不是虚函数 析构函数设置为虚函数可以保证我们new一个子类时,可以使用基类指针指向该子类对象,释放基类指针时可以释放掉子类的空间,防止内存泄漏。...17、函数指针 有了指向函数的指针变量后,可用该指针变量调用函数 int Func(int x); /*声明一个函数*/ int (*p) (int x); /*定义一个函数指针*/ p =
我们为什么需要智能指针 所谓资源就是,一旦用了它,将来必须还给系统。C++中内存资源的动态分配经由new与delete实现。问题在于,无论是有意无意,我们有时候总会忘记释放内存中的资源。...这里以auto_ptr为例,在某个时刻下,只能有一个auto_ptr指向一个给定的对象。...shared_ptr则允许多个指针指向同一个对象,而weak_ptr指向的是shared_ptr所管理的对象,它是一种弱引用。 shared_ptr的实现基于引用计数技术。...为什么要摒弃auto_ptr 上面说到auto_ptr是C++98提供的智能指针,现在已经被摒弃,原因在于为了维护独占性,auto_ptr进行了不正常的复制/赋值行为。...weak_ptr有何作用 weak_ptr是一种不控制所指向对象生命期的智能指针,它指向由一个shared_ptr管理的对象。
领取专属 10元无门槛券
手把手带您无忧上云