高效的C指针

cnyinlinux

指针,被称做C语言编程的精华。其闻名数十年的秘诀在于,高效二字。今天我们讲的就是,指针是如何做到了这一切的。

经常你会看到这样的形式:

XXX * func(int para1,…);//函数参数略

函数的返回值类型为指针,为何要返回一个指针呢?

指针在C中代表的是一片内存,也就意味着该函数返回时,将一片内存带给了原调函数(调用该函数的函数称为原调函数)。这样做的目的是将函数处理结果存于内存,直接把存储地址返回。这样原调函数在获取结果的时候不必要再复制数据,直接在返回指针指向的内存中去操作。

还有时候你会见到下述样子的函数:

XXX func(const char * src, char * dest);

这个函数的入参变成了指针,这样又有什么好处呢?首先,如果该函数如果是处理大片数据的话,原调函数直接将数据的内存地址传递给被调用函数,避免了繁琐的内存复制工作。其次,如果处理的结果也是直接放在传入的指针指向的内存区,被调函数返回时无需再复制结果给原调函数。

从上面两个例子可以看出,指针的作用就是避免了数据的冗余复制操作,也就是繁重的搬运工作。这就是指针高效的原因。简而言之,指针技术采用直接传递地址的方式,避免多余的数据复制,节省了处理时间,同时节省了额外开辟内存的资源消耗,因此使得程序高效性得到了保障。

下面我们再来看看指针的应用。

一,数组。

最为常见的复合数据结构就是数组了,而数组首地址就是自己这片内存区的指针,因此在处理数组的函数中,通常是将数组的首地址传递过去,这样被调函数直接获得原内存区的访问权。同时,在访问每个数组成员的时候,只需要在首地址基础上加上偏移量就得到了。这样使得各成员访问的时间在常数级就可完成。

二,地址传递。

其实,除了数组,一般我们在处理很多基本数据类型的时候也可以采用指针。

如要在被调函数返回多个基本数据类型的变量的值,通过函数return难以实现,这个时候额可以考虑传递指针的方式,直接在被调函数内部将数值放置在传入指针指示的位置处。这样不光避免了return的局限性,还避免了原调函数的复制操作,近一步简化了函数调用的代码逻辑。

三,数组指针。

说到数组指针,很容易联系到二维数组。的确,二者很相似,可以这么理解,二维数组的第1维度是个数组指针,而第2维度是普通数组,这样第1维度每移动1个步长,其指向的内存区就移动了一个1维数组的长度。其实,数组指针就是一种代表着数组为指类的指针。

也就是说这个指针所代表的内存区指的是它的值开始的一个数组大小的区域。这样它其实就被上升到了与二重指针同等的级别上了。也就是说,数组指针也是一种特殊的二重指针,但是它不能通过简单的两次脱指(**)操作来完成内容的访问,因为它代表的是一片内存,所以需要用到类似数组的偏移方法去访问每一个成员。

如 int (*pa)[10];,pa代表的是10个int的内存去,当你要访问pa的第一个成员的时候(下标从0开始)的话,它应该写为 *((int *)pa + 1) 而绝不是pa[1]。

四,函数指针。

顾名思义,就是指向函数的指针叫做函数指针。函数指针的功能是指向一片可执行的代码段地址,这样可以在某个子函数内部需要执行其他函数的时候,可以通过传递函数指针的方式告知该子函数要执行的代码片段。在软件模块化设计研究中,函数指针也有广泛的应用,比如分离多模块之间的功能调用衔接,可以采用指针池的方式实现多个子系统之间的处理调用关系。通过指针调用的函数称之为回调函数,用在系统的信号处理,应用软件的事件触发方面等较为常见。

五,多重指针。

指针作为一个存放内存地址的变量,存储的是一个有效的内存地址的值。所以它的大小就该满足系统的寻址规则,32位系统上为4字节,64位系统上为8字节。指针无论有多少重,它的本质不会变化,都是存储一个内存地址值,只是它存储的那个地址代表的含义是另一个指针还是存储最终数据的内存地址不同而已。多重指针无非是指向关系多了几层,他们的处理方式是不变的。所以,多重指针用到第3重就可以了,重数再高就意义不大了。多重指针就像个手表,不同的层级代表不同的含义,最终合起来表示一个完整含义。

六,指针数组。

如其名,它就是个数组,只不过成员是指针而已。可以是基本数据类型,也可以是复合类型指针,还可以是函数指针。具体每个成员指针的特性与上面讲述的吻合。

<<<本文完结>>>

时间: 2024-10-25 20:23:24

高效的C指针的相关文章

高效编程之指针跳转的影响

C语言的指针跳转访问是一个灵活高效的机制,但是再高效也是要花费额外时间的,下面这个程序如果在gcc -O0不优化的情况,就可以看出指针跳转比直接访问要多消耗10%左右的时间 #include <stdio.h> #include <sys/time.h> int main() { int m = 0; int *p = &m; int i =0; int n = 1; struct timeval time1, time2; m = 0; gettimeofday(&

指针 (整理版)

指针是C/C++编程中的重要概念之中的一个,也是最easy产生困惑并导致程序出错的问题之中的一个. 利用指针编程可以表示各种数据结构,通过指针可使用主调函数和被调函数之间共享变量或数据结构.便于实现双向数据通讯.指针可以灵活的操作内存,合理的操作内存可以使程序更高效. 1.指针的概念 本质上讲指针也是一种变量,普通的变量包括的是实际的数据,而指针变量包括的是内存中的一块地址,这块地址指向某个变量或者函数,指针就是地址.指针是一个指示器,它告诉程序在内存的哪块区域能够找到数据. 2.指针的内容 指

C/C++学习笔记----指针的理解

指针是C/C++编程中的重要概念之一,也是最容易产生困惑并导致程序出错的问题之一.利用指针编程可以表示各种数据结构,通过指针可使用主调函数和被调函数之间共享变量或数据结构,便于实现双向数据通讯:指针能够灵活的操作内存,合理的操作内存能够使程序更高效. 1.指针的概念 本质上讲指针也是一种变量,普通的变量包含的是实际的数据,而指针变量包含的是内存中的一块地址,这块地址指向某个变量或者函数,指针就是地址.指针是一个指示器,它告诉程序在内存的哪块区域可以找到数据. 2.指针的内容 指针的内容包含4部分

C语言结构体中的函数指针

这篇文章简单的叙述一下函数指针在结构体中的应用,为后面的一系列文章打下基础 本文地址:http://www.cnblogs.com/archimedes/p/function-pointer-in-c-struct.html,转载请注明源地址. 引言 指针是C语言的重要组成部分, 于是深入理解指针并且高效地使用指针可以使程序员写出更加老练的程序.我们要记住指针是一个指向内存地址的变量.指针可以引用如int.char……常见的数据类型,例如: int * intptr; // 声明一个指向整型值的

C++中的指针、数组指针与指针数组、函数指针与指针函数

C++中的指针.数组指针与指针数组.函数指针与指针函数 本文从初学者的角度,深入浅出地详解什么是指针.如何使用指针.如何定义指针.如何定义数组指针和函数指针,并给出对应的实例演示:接着,区别了数组指针与指针数组.函数指针与指针函数:最后,对最常混淆的引用传递.值传递和指针传递做了区处. C++中一个重要的特性就是指针,指针不仅具有获得地址的能力,还具有操作地址的能力.指针可以用于数组.或作为函数的参数,用来访问内存和对内存的操作,指针的使用使得C++很高效,但是指针也非常危险,使用不当会带来比较

Oracle官网JNI简介和接口函数分析

第一章 概述 本章主要介绍JNI(Java Native Interface),JNI是一种本地编程接口.它允许运行在JAVA虚拟机中的JAVA代码和用其他编程语言,诸如C语言.C++.汇编,写的应用和库之间的交互操作. JNI的最大优势在于没有强加任何限制在JAVA虚拟机的下层实现上,因此,JAVA虚拟机供应商能够提供JNI的支持而不影响虚拟机的其他部分,程序员只需写出一个版本的本地应用和库,就可使之运行在一切支持JNI的JAVA虚拟机上. 本章包含了以下的要点: ? JNI概述 ? 目标 ?

[总结] 平衡树总结

1. treap 众所周知, treap = tree + heap 也就是 treap 是具有堆性质的平衡二叉树(BST), 而堆性质的维护就靠一个随机值和旋转操作. 可以是小根堆也可以是大根堆. 在代码实现上, 左旋和右旋有太多的相似处, 可以用一个带旋转方向参数的 rotate 操作来完成. 模板 loading- 2. splay 和 treap 比较起来, splay 多的就是伸展(splay)操作. 关于伸展操作 两种实现方式 : 自顶向下和自底向上. 自底向上的 splay 我是参

C++11 知识点

l  利用{}进行所有容器和数据结构的就地初始化,还可以直接用于返回值,对自定义类型进行就地初始化使用initializer_list l  通过右值引用,函数可以自由的返回大对象,同时带资源赋值更加高效,由此指针可在任何情况下退出使用(库除外) l  全局唯一资源可封装为只可移动不可拷贝语义 l  任何非引用数据都可以成为联合体的成员 l  final.override.virtual等指示关键字要经常使用 l  enum变成了强类型,不可与数字隐式转换 l  friend关键声明友元类时不用

boost---shared_ptr笔记

 shared_ptr是包装了new操作符在堆上分配的动态对象,能够保证动态创建的对象在任何时候都可以被正确的删除,它实现的是引用计数型的智能指针,可以被自由的拷贝和赋值,在任意的地方共享它,当没有代码使用(引用计数为0时)它时才可以被删除.  shared_ptr可以被安全的放到标准容器中,并弥补了auto_ptr因为转移语义而不能把指针作为STL容器元素的缺陷. 何时我们需要智能指针? 有三种典型的情况适合使用智能指针: 资源所有权的共享 要写异常安全的代码时 避免常见的错误,如资源