通过qsort(void * lineptr[], int left, int rifht, int (*comp)(void *, void *))解读指针函数和void指针
原函数是《The C programint language 》5.11文本行排序的程序,如下:
void qsort(void *v[], int left, int right, int (*comp)(void *,void *))
{
int i,last; if( left >= right)
return; swap(v,left,(left+right)/2);
last = left;
for(i = left + 1; i <= right; ++i)
if(comp(v[i],v[left]) < 0)
swap(v,++last,i);
swap(v,left,last);
qqsort(v,left,last-1,comp);
qqsort(v,last+1,right,comp);
}
该函数有以下特点:
1. 参数 void *v[] ,这是把main函数传递的实参转换为通用的void * * 类型的形参,那对于实参的需要自己强制转换,比如把 char * lineptr[] 传递给 v,必须这样(void ** )lineptr,
那为什么能这样转化
1. 任意的类型都可以赋给相应的void类型的
2. 该void的类型也可以强制转换为该类型
那为什么要这样转换
1. 这样转换可以满足函数通用性的要求,任何类型都可以转换为相应的void类型,相对于这个程序,把char 转换为 void,只要在comp模型中提供了comp(char *,char *)去调用,就把void 转换为 char 类型进行运算,符合程序通用化的要求;
2. 之所以可以用void的1阶以上指针,是因为各种类型的地址字节都是固定了,win32用4个字节表示指针,所以只要该函数内的void类型的运算都是对地址的运算都可以,不能对相应的void的类型进行四则和取值运算,因为它虽然指向对应变量的首地址,但是他不知道该地址指向的数据类型,所以除了地址运算其他的都不能进行,也就是说使用这种转换函数,必须保证该函数内除了地址运算外,不能进行其他的运算。
还有对于 形参void * v [] 去代替实参 (void **)lineptr,对于一个指向void * 的数组来说,之所以行,是因为v[1]是可以计算,数组中存的都是指针,固定4个字节,v[1] 的地址 v + 4就行了,由因为它指向的是地址,v[1]指向一个地址,改地址又是4个字节的大小,只有这些是可以确定,其他的不行,不能对v[1][1],因为v[1]是个地址,但是这个地址指向的内容的类型不能判定,不知道把改地址指向的那块数据取几个字节,转换什么类型,都不得而知。
还有个强制转换问题:
char s[3][3];
void ** p = s;
把p转换为s的 ((char (*)[3])p)[0] = s[0]
完整的程序见:http://blog.csdn.net/chenyiming_1990/article/details/9382177
通过qsort(void * lineptr[], int left, int rifht, int (*comp)(void *, void *))解读指针函数和void指针的更多相关文章
- public void onItemClick(AdapterView arg0, View view, int position,long arg3)详解【整理自网络】
参考自: http://blog.csdn.net/zwq1457/article/details/8282717 http://blog.iamzsx.me/show.html?id=147001 ...
- signal函数:void (*signal(int,void(*)(int)))(int);
http://blog.chinaunix.net/uid-20178794-id-1972862.html signal函数:void (*signal(int,void(*)(int)))(int ...
- Java JNA (四)—— void**、void*、char**、char*、int*等类型映射关系及简单示例
ByReference类有很多子类,这些类都非常有用. ByteByReference.DoubleByReference.FloatByReference. IntByReference.LongB ...
- 编写Java应用程序。首先,定义描述学生的类——Student,包括学号(int)、 姓名(String)、年龄(int)等属性;二个方法:Student(int stuNo,String name,int age) 用于对对象的初始化,outPut()用于输出学生信息。其次,再定义一个主类—— TestClass,在主类的main方法中创建多个Student类的对象,使用这些对象来测 试Stud
package zuoye; public class student { int age; String name; int stuNO; void outPut() { System.out.pr ...
- (int &)a 和(int)a
[cpp] view plain copy float a = 1.0f; cout < < (int)a < < endl; cout < < ...
- C++中int *p[4]和 int (*q)[4]的区别
这俩兄弟长得实在太像,以至于经常让人混淆.然而细心领会和甄别就会发现它们大有不同. 前者是指针数组,后者是指向数组的指针.更详细地说. 前: 指针数组;是一个元素全为指针的数组.后: 数组指针;可以直 ...
- open_clientfd(char* hostname,int port)和open_listenfd(int port)
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h&g ...
- 5.编写Java应用程序。首先,定义描述学生的类——Student,包括学号(int)、 姓名(String)、年龄(int)等属性;二个方法:Student(int stuNo,String name,int age) 用于对对象的初始化,outPut()用于输出学生信息。其次,再定义一个主类—— TestClass,在主类的main方法中创建多个Student类的对象,使用这些对象来测 试St
Student类: package com.bao; public class Student { int stuNo;String name,sex;int age,weight; Student( ...
- int *p[4]与int (*q)[4]的区别
以上定义涉及两个运算符:“*”(间接引用).“[]”(下标),“[]”的优先级别大于“*”的优先级别. 首先看int *p[4],“[]”的优先级别高,所以它首先是个大小为4的数组,即p[4]:剩下的 ...
随机推荐
- 全球最快的JS模板引擎:tppl
废话不多说,先上测试: 亲测请访问:[在线测试地址]单次结果不一定准确,请多测几次. tppl 的编译渲染速度是著名的 jQuery 作者 John Resig 开发的 tmpl 的 43 倍!与第二 ...
- Maven学习笔记(一) : 简单介绍
近期在学习<maven实战>,写点东西记录一下.^_^ 何为Maven: Maven主要服务于基于java平台的项目构建.依赖管理和项目信息管理. Maven是优秀的构建工具: ...
- HTTP2协议之HPACK--之头部压缩规范介绍
接下来打算把HTTP2协议的头部压缩算法给翻译下,敬请等候. HPACK - Header Compression for HTTP/2 HPACK:HTTP/2头部压缩 概要说明 这个规范定义了HP ...
- C#中抽象类和接口的区别
原文:C#中抽象类和接口的区别 大家在编程时都容易把抽象类和接口搞混,下面为大家从概念上讲解抽象类和接口的区别: 一.抽象类: 含有abstract修饰符的class即为抽象类,抽象类是特殊的类,只是 ...
- leetcode第26题--Remove Duplicates from Sorted Array
problem: Given a sorted array, remove the duplicates in place such that each element appear only onc ...
- 基于jQuery的上下无缝滚动应用(单行或多行)
工作中遇到的一个js代码,现在对.trigger('mouseleave'),仍一知半解... <script>$(function(){//单行应用var _wrap=$('ul.lin ...
- 开源文档管理系统LogicalDOC测试报告---安装篇
开源文档管理系统LogicalDOC测试报告---安装篇 分类: Linux2011-06-22 15:40 7436人阅读 评论(3) 收藏 举报 文档管理测试mysql数据库installerja ...
- Delphi的注册表操作
转帖:Delphi的注册表操作 2009-12-21 11:12:52 分类: Delphi的注册表操作 32位Delphi程序中可利用TRegistry对象来存取注册表文件中的信息. 一.创 ...
- oracle_base和oracle_home 的区别
oracle_base和oracle_home 的区别 $ORACLE_BASE和$ORACLE_HOME 的区别 2009-06-22 11:25:34| 分类: Oracle |字号 订阅 ...
- asp.net mvc请求响应模型原理回顾
根据讲师所讲总结了一下(可能存在些描述错误) -------------mvc进入asp.net管道原理: (在执行httpapplication管道之前mvc和asp.net是相同的,不同之处在于管 ...