编写通用程序
- 利用通用指针类型
void*
和强制类型转换
,实现“泛型”
编程
通用的交换程序
// 两整数交换
/* # include <stdio.h>
void swap( int *x , int *y ){
int tmp = *x ;
*x = *y ;
*y = tmp ;
}
int main(){
int x , y ;
scanf("%d%d",&x,&y) ;
swap( &x , &y ) ;
printf("%d %d\n",x,y) ;
return 0 ;
} */
// 利用通用指针类型void*和强制类型转换,实现“泛型”编程
// 同类型数据交换
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
// memcpy : 按字节拷贝函数
void swap( void *x , void *y , int size ){
char *buffer = (char*)malloc(sizeof(char)*size) ;
memcpy( buffer , x , size ) ;
memcpy( x , y , size ) ;
memcpy( y , buffer , size ) ;
return ;
}
int main(){
int x , y ;
// int类型交换
/* scanf("%d%d",&x,&y) ;
swap( &x , &y , sizeof(int) ) ;
printf("%d %d\n",x,y) ;
*/
// double类型交换
/* double x1 , y1 ;
scanf("%lf%lf",&x1,&y1) ;
swap( &x1 , &y1 , sizeof(double) ) ;
printf("%lf %lf\n",x1,y1) ;
*/
// 字符串交换
/* strdup() : 字符串拷贝库函数,一般和free()函数成对出现。
内部调用malloc()为变量分配内存,返回一个指向 为复制字符串分配的空间 的指针 */
char *sa = strdup("saaa") ;
char *sb = strdup("sbbbb") ;
/*
// 传入的是指向字符串所在位置的指针的地址 , 交换指针指向
swap( &sa , &sb , sizeof(char*) ) ;
printf("%s %s",sa,sb) ;
// sbbbb saaa
*/
// 传入的是字符串所在位置的首地址 , 逐字节交换字符串内容
// swap( sa , sb , sizeof(char*) ) ;
// printf("%s %s\n",sa,sb) ;
// sbbb saaab
// 只能复制4个字节(4个字母)
// printf("%d",sizeof(char*)) ; // 我的指针占 4 字节
return 0 ;
}
通用的线性搜索
# include<stdio.h>
# include<stdlib.h>
# include<string.h>
// 线性搜索
/* int lsearch( int key , int *arr , int size ){
for( int i = 0 ; i < size ; i++ ){
if( arr[i] == key ){
return i ;
}
}
return -1 ;
} */
// 适用于float、double、int、char等基本类型的搜索
/* int lsearch( void *key , void *base , int n , int elemsize ){
for( int i = 0 ; i < n ; i++ ){
void *elem_addr = (char*)base + i * elemsize ;
// memcmp(const void *str1, const void *str2, size_t n));
// 将存储区 str1 和存储区 str2 的前 n 个字节进行比较。该函数是按字节比较的
if( memcmp( key , elem_addr , elemsize ) == 0 ) {
return i ;
}
}
return -1 ;
}
*/
// 对于字符型指针 ,字符串 ,结构体里有指针成员 ,函数指针(内存中的指针成员)等适用.
// 需要自己编写对应的比较函数
/* int cmp( void *a, void *b ){ // 比较整型
int *e1 = (int*)a ;
int *e2 = (int*)b ;
return ( *e1 - *e2 );
}
*/
int cmp( void *a , void *b ){ // 比较字符串
char *e1 = *(char**)a ;
char *e2 = *(char**)b ;
return strcmp(e1,e2) ;
}
int lsearch( void *key , void *base , int n , int elemsize , int (*cmp)(void* , void*) ){
for( int i = 0 ; i < n ; i++ ){
void *elem_addr = (char*)base + i * elemsize ;
// int (*cmp)(void* , void*)是指向函数的指针
if( cmp( key , elem_addr ) == 0 ) {
return i ;
}
}
return -1 ;
}
int main(){
int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } ;
int key = 5 ;
// printf("%d\n",lsearch(&key, a, 10 , sizeof(int) , cmp ));
// warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
// 传给函数的 字面常量(整形常量,字符型常量,字符串常量)是没法被修改的,把参数类型修改为const char *
const char *b[] = { "aaa", "bbb", "ccc" } ;
const char *key_str = "bbb" ;
printf("%d\n",lsearch( &key_str, b, 3, sizeof(char*), cmp ));
return 0 ;
}
- 无类型指针:只存放地址,不能进行指针运算,不能进行间接引用
void *p ;
int x = 500 , y ;
p =& x ; //ok,整型变量地址
y =* p ; //error: 不能进行间接引用