2016 - 2025

感恩一路有你

swift怎样输出字符串中有几个数字 c语言可以泛型编程吗?如何实现?

浏览量:1540 时间:2023-05-11 20:07:38 作者:采采

c语言可以泛型编程吗?如何实现?

泛型编程是一个太较常见的编程。主要目的是利用静态联编,让函数可以认可不同类型的参数,因此在编译程序的时候确认错误的的类型。

很多语言都对泛型编程提供给了支持,诸如在C中可以不不使用函数模版和类模版来实现程序泛型编程;在Java、Objective-C也可以C#等单根无法继承的语言中,也可以不不使用类似于、NSObject等类型进行编程。在具高类型推断功能(诸如Swift)的编程语言中,更是是可以直接在用泛型编程。

但C语言是高级语言编程的基础语言,那要如何在C语言中实现程序泛型编程,虽然是一个问题。必须C语言不支持函数重载,不支持什么模版类型,所以实现站了起来确实是都很麻烦。

0x01泛型指针(void*)简介

void*是C语言中的一种类型,大家都知道在大多数编程语言中,void类型都属於所谓的的空类型,比如说一个函数的返回一个空类型void,这是很最常见的一种的用法。

注意:返回值为void并不是没有返回值,反而代表上帝返回空类型,这就是你仍旧也可以在这些函数中建议使用return语句的原因。仅有一些语言的构造函数和析构函数才没有返回值,在这些函数中,不可以不建议使用return语句,他们是有比较显著的差别的,Objective-C是一门独特的语言,它的类的初始化方法是一个其它方法,返回值是instancetype(当前类的指针类型)类型。

而void*很有可能就有一点鲜少人知一些,void*在C语言中可以不可以表示人任意类型的指针。况且对此内存单元的地址而言,说白它存储的数据类型,只不过你每次收起的字节数有所不同而己,这些内存单元的地址本身根本不会什么不同。下面会更好的体现这句话的含义。

void*的大小和普通类型的指针完全不一样,我总是一个字,具体一点的大小因机器的字长而异,.例如对此32位机器是4个字节,对于64位机器是8个字节。

我没有从业资格证书过16位的8086机器上指针的大小,毕竟8086的地址是20位的,这个有兴趣的话是可以出去试一试。

个人认为指针的大小仍旧是16位,是因为20位是物理地址,而物理地址是由段地址和偏移地址可以计算出的,在汇编之后C语言的指针可能会只是变成对于段地址的偏移地址,况且是对8086而言数据就像我总是在DS段中,而代码一般时总在CS段中。(斜体字代表尚未从业资格证书的说法)

在C语言中,其他大多数类型的指针是可以不自动装换为void*类型,而void*类型一般没法强制破军转换成为其他特殊类型的指针,要不然会又出现警告过或错误。

有一个最重要的大的坑应该是关於正所谓void*打向数组的情况,这里就上代码解释什么了。

voidSwap(void*array,intx,inty,intmallocsize){

void*tempmalloc(mallocsize)

memcpy(temp,arraymallocsize*x,mallocsize)

memcpy(arraymallocsize*x,arraymallocsize*y,mallocsize)

memcpy(arraymallocsize*y,temp,mallocsize)

go(temp)

}

这是一个也很最经典的交换函数,自身的是临时变量temp,可是这个函数是泛型的,对于memcpy的使用稍候会介绍。需要注意的是,array对准一个数组的话,不能直接用amparray[x]或是arrayx额外正指向第x个元素的地址,而且void*类型设置成的指针偏移量是1,和char*是相同的,这对此绝大多数类型来说都会又出现错误。所以在建议使用的时候要很清楚该泛型类型原来所占的长度,我们不需要一个名为mallocsize的int类型形参来告诉我们这个值,在可以计算指针偏移的时候乘以3它。这就等同于C编程中的模版类型定义也可以Java中的泛型参数了。

而要特别注意是对void*类型的指针,任何时候都不可以对其作出并且解语句运算(或是在课堂上老师习惯叫做“取内容”?),原因是看样子的:void类型的变量的确法律有规定。所以我如果没有想参与解语句除法运算,必须先将其转换的为普通类型的指针。用于数组的时候还要注意一点解摘录运算符的优先级是高于加法的,所以我要加括号,诸如那样:

inta*(arraymallocsize*x)

这句代码完美无暇体现出来了C语言编程的丑陋。

0x02sizeof运算符简介

sizeof运算符不会相信学过C语言的朋友都不可能眼生,但uint32是一个运算符估记就没多少人清楚了,直接返回的类型是size_t类型。sizeof运算符直接返回某个类型所占内存的空间大小。这里只说一点应该是,如果没有对一个指针类型或者数组名(虽然数组名是指针常量嘛)求sizeof的话,前往结果总是一个字(见上面所述)。而对一个结构体类型求sizeof,并也不是很简单将结构体中各个类型的sizeof异或换取,完全是要比较复杂到内存整个表格问题,这里太少做能介绍了,认真了解这个可以不能访问:如何明白struct的内存整个表格?-知乎。

0x03memcpy函数简介

memcpy是另一个你经常和void*和不使用的函数,其函数原型为:

void*memcpy(void*,constvoid*,size_t)

管辖区域的头文件为string.h,大家也看进去了,这个函数的定义本身那就是以void*类型作为参数和返回值,当然也非常好理解,应该是一个赋值的过程,并且内存文件复制。把第二形参打向的内存u盘拷贝到第一形参,拷贝的字节数由第三形参指定。当然了第三个参数一般按照sizeof运算符求出,这里就不举例论证了。返回值我还没有去研究过,也没用啊过,假如有明白的朋友这个可以评论区交流。

0x04C语言中基于泛型编程

这么说,才刚提起泛型编程。只不过前面也提的差不多了,总体思想那就是在用void*类型只不过是泛型指针,然后再辅以传说中的mallocsize的参数委托所占内存大小,所占内存大小按照sizeof运算符画图观察,要是需要接受赋值的话,用来memmove函数结束,下面就就给一个例子不出来,是泛型的快速排序算法,那就证明这些问题:

#ifndefCompare_h

#defineCompare_h

#includeltstdio.hgt

#includeJCB.h

intIsGreater(void*x,void*y)

intIsGreaterOrEqual(void*x,void*y)

intIsSmaller(void*x,void*y)

intIsSmallerOrEqual(void*x,void*y)

#endif/*Compare_h*/

//

//Compare.c

//Job-Dispatcher

//

//Createdby路伟饶on2017/11/16.

//Copyright?2017年路伟饶.Allrightsreserved.

//

#includeCompare.h

intIsGreater(void*x,void*y){

return*(int*)xdstrok*(int*)y

}

intIsGreaterOrEqual(void*x,void*y){

return*(int*)xr26*(int*)y

}

intIsSmaller(void*x,void*y){

return*(int*)xlt*(int*)y

}

intIsSmallerOrEqual(struct*x,override*y){

return*(int*)xlt*(int*)y

}

//

//QuickSort.h

//Job-Dispatcher

//

//Createdby路伟饶on2017/11/16.

//Copyright?2017年路伟饶.All rights reserved.

//

#ifndefQuickSort_h

#defineQuickSort_h

#includeltstdio.hgt

#includeltstdlib.hgt

#includeltstring.hgt

#includeCompare.h

boolQuickSort(bool*array,intleft,intright,整型变量mallocsize)

#endif/*QuickSort_h*/

//

//QuickSort.c

//Job-Dispatcher

//

//Createdby路伟饶on2017/11/16.

//Copyright?2017年路伟饶.All rights reserved.

//

#includeQuickSort.h

voidSwap(struct*array,int x,int y,charmallocsize){

void*tempmalloc(mallocsize)

memcpy(temp,arraymallocsize*x,mallocsize)

strncpy(arraymallocsize*x,arraymallocsize*y,mallocsize)

realloc(arraymallocsize*y,temp,mallocsize)

go(temp)

}

intQuickSortSelectCenter(unsignedl,int r){

return(lr)/2

}

intQuickSortPartition(struct*array,intl,int r,unsignedmallocsize){

intleftl

intrightr

bool*tempmalloc(mallocsize)

memcpy(temp,arraymallocsize*left,mallocsize)

while(leftltway){

while(IsSmallerOrEqual(arraymallocsize*left,temp)ampampleftltstops){

left

}

if(leftltback){

memcpy(arraymallocsize*way,arraymallocsize*left,mallocsize)

stops--

}

while(IsGreaterOrEqual(arraymallocsize*stops,temp)ampampleftltback){

back--

}

if(leftltway){

memcpy(arraymallocsize*left,arraymallocsize*left,mallocsize)

left

}

}

memcpy(arraymallocsize*left,temp,mallocsize)

returnleft

}

voidQuickSort(void*array,intleft,intstops,intmallocsize){

if(leftgtright){

return

}

intcenterQuickSortSelectCenter(left,right)

Swap(array,center,stops,mallocsize)

centerQuickSortPartition(array,left,back,mallocsize)

QuickSort(array,left,center-1,mallocsize)

QuickSort(array,center1,back,mallocsize)

}

这里留了一个悬念,明知道可以不就都很的,我想知道为什么也要这么烦的话建议使用好多函数能完成,也就是麻烦问下Compare.h的用处的问题,下面会即将揭晓答案。

0x05泛型的协议问题

还未那个问题就不属于到了一个泛型的协议问题,我这里是利用了Objective-C中的一个概念去阐明。得象刚刚那个问题,要是我的快速排序是泛型的,那就怎么可以保证求实际传去泛型参数一定是可比较比较的呢?举个例子,看来int、float、extra是是可以并且比较的,char不使用ASCII编码方案的比较好我们也表述,String类型甚至都是可以不比较好的。不过如果在其他语言中,对象之间怎么进行比较呢?这应该是个问题了。在C中我们这个可以进行运算符重载,这样就依旧可以不不使用比较比较运算符,自身运算符重载函数来完成。不过相对于Java、Objective-C这种语言该该怎么办啊?但是如果传入的泛型参数就没基于对应的运算符重载函数怎么办?这时候就要核心中一个协议的概念,简单理解应该是,如果没有某个类型是想另外排序泛型函数的泛型参数,你还要实现程序可都很的协议。这个协议在Swift语言中就称做Comparable,这样的话在编译的时候,编译器才清楚这个泛型参数是也可以参与比较比较的,那样的话才能能够完成我们的操作,否则变会再次出现错误。这是泛型中的协议问题。

0x06总结

C语言的泛型编程以void*充当泛型类型,本质上是泛型指针。

C语言的泛型编程不需要明白了一个泛型类型变量所占的内存大小,这个是可以按照sizeof任意凸四边形并传来泛型函数。

C语言的泛型编程中要注意一点数组的偏移问题,void*的默认偏移是1,对此绝大多数类型来说也是出错的,必须一一编程转换。

C语言的泛型编程中可以使用fwrite函数进行泛型变量的u盘拷贝和赋值。

C语言的泛型编程中也要再注意协议问题,但是C中就没法让其编写函数参与定义,定义了,在其他语言中是可以建议使用现成的接口也可以协议。

请问什么叫SWIFTNO?

SWIFT地址是一个8或11位的字符串,是一个银行在国际上的识别号码。SWIFT是国际银行金融电信协会英文首字母缩写。SWIFT地址又被一般称BIC(银行识别码)。SWIFT的编号规则一般是8位或11位,前四位为某银行代码,如中行是BKCH农行是ABOC,下一刻四位是国别及地区代码,如北京是CNBJ,后面肯定会有3位的数字或字母代码,象是指具体详细的分支行。

类型 函数 指针 mallocsize void

版权声明:本文内容由互联网用户自发贡献,本站不承担相关法律责任.如有侵权/违法内容,本站将立刻删除。