user-0 提问: 形参不可以是void类型吗

回复:
user: user-1
content: void*可以吧

user: user-2
content: sizeof是关键字

user: user-3
content: 你先想想要写什么东西，用void干什么

user: user-4
content: C 基本上不支持泛型 不过有几种方式，可以大约实现泛型  一种是 函数指针，  一种是宏 void *则 可以储存任何类型的地址 其实，C标准库的 qsort 就是 C泛型的一个例子 另外 如果想实现，一个标准的泛型，可以自己写个泛型的预处理器， 就像 C++的早期实现那样， 写个 CFront 就可以了 不过这个必要性不大

user: user-5
content: 可以的，可以是void

user: user-6
content: 引用 18 楼 zouyuncheng 的回复:你需要定义的是多个函数,传递数据类型以判断调用哪个函数, 顺便说一句,之所以不能用void做参数的原因是,C函数的参数类型作用是确定数据长度,说白了,你提供给它一个明确的存储数据所需的空间大小就可以了,,,可VOID是多大?,,,,,所以,不能用void做参数,而上面人说的void*,这个是明确的指针,而在一个系统中,指针大小是确定的.所以可以做参数. 而sizeof是运算符,它被规到运算符中,完全是因为它的作用和使用方法,而它的级别甚至和宏相当,一般是在编译前就处理完了,所以无法在运行时用它去确定任何类型的大小  而想像C++那样去直接实现用参数类型来确定调用哪个函数,,,估计用复杂的宏也许能实现,但像你这样调用,是肯定不行的, 可行的方法是 void * max(char *, void *, void *);  int main(void) { 	int a=10, b=50; 	double c=15.47, d=17.92; 	 	printf ("%d\t%g\n", *(int *)max("int", &a, &b), *(double*) max("double", &c, &d)); 	 	return 0; }  double * dmax(double * c, double * d) { 	return *c > *d ? c : d; }  int * imax(int * a, int * b) { 	return *a > *b ? a : b; }  void * max ( char * st, void * x, void * y) { 	if (strcmp(st, "double") == 0) 		return dmax(x,y); 	if (strcmp(st, "int") == 0) 		return imax(x,y); } 当然你在同一个函数中实现也没事,不过是把一个函数的代码更复杂一些而已,

user: user-7
content: sizeof（void *），在32位机器上的结果是4，因为指针占用4个字节，得到的结果跟你想要的可能会不一致  引用 3 楼 robertbo 的回复:可以是void *

user: user-6
content: 你需要定义的是多个函数,传递数据类型以判断调用哪个函数, 顺便说一句,之所以不能用void做参数的原因是,C函数的参数类型作用是确定数据长度,说白了,你提供给它一个明确的存储数据所需的空间大小就可以了,,,可VOID是多大?,,,,,所以,不能用void做参数,而上面人说的void*,这个是明确的指针,而在一个系统中,指针大小是确定的.所以可以做参数. 而sizeof是运算符,它被规到运算符中,完全是因为它的作用和使用方法,而它的级别甚至和宏相当,一般是在编译前就处理完了,所以无法在运行时用它去确定任何类型的大小  而想像C++那样去直接实现用参数类型来确定调用哪个函数,,,估计用复杂的宏也许能实现,但像你这样调用,是肯定不行的, 可行的方法是 void * max(char *, void *, void *);  int main(void) { 	int a=10, b=50; 	double c=15.47, d=17.92; 	 	printf ("%d\t%g\n", *(int *)max("int", &a, &b), *(double*) max("double", &c, &d)); 	 	return 0; }  double * dmax(double * c, double * d) { 	return *c > *d ? c : d; }  int * imax(int * a, int * b) { 	return *a > *b ? a : b; }  void * max ( char * st, void * x, void * y) { 	if (strcmp(st, "double") == 0) 		return dmax(x,y); 	if (strcmp(st, "int") == 0) 		return imax(x,y); }

user: user-8
content: /* Copyright (C) 1991-2014 Free Software Foundation, Inc.    This file is part of the GNU C Library.    Written by Douglas C. Schmidt (schmidt@ics.uci.edu).     The GNU C Library is free software; you can redistribute it and/or    modify it under the terms of the GNU Lesser General Public    License as published by the Free Software Foundation; either    version 2.1 of the License, or (at your option) any later version.     The GNU C Library is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    Lesser General Public License for more details.     You should have received a copy of the GNU Lesser General Public    License along with the GNU C Library; if not, see    <http://www.gnu.org/licenses/>.  */  /* If you consider tuning this algorithm, you should consult first:    Engineering a sort function; Jon Bentley and M. Douglas McIlroy;    Software - Practice and Experience; Vol. 23 (11), 1249-1265, 1993.  */  #include <alloca.h> #include <limits.h> #include <stdlib.h> #include <string.h>  /* Byte-wise swap two items of size SIZE. */ #define SWAP(a, b, size)						      \   do									      \     {									      \       size_t __size = (size);						      \       char *__a = (a), *__b = (b);					      \       do								      \ 	{								      \ 	  char __tmp = *__a;						      \ 	  *__a++ = *__b;						      \ 	  *__b++ = __tmp;						      \ 	} while (--__size > 0);						      \     } while (0)  /* Discontinue quicksort algorithm when partition gets below this size.    This particular magic number was chosen to work best on a Sun 4/260. */ #define MAX_THRESH 4  /* Stack node declarations used to store unfulfilled partition obligations. */ typedef struct   {     char *lo;     char *hi;   } stack_node;  /* The next 4 #defines implement a very fast in-line stack abstraction. */ /* The stack needs log (total_elements) entries (we could even subtract    log(MAX_THRESH)).  Since total_elements has type size_t, we get as    upper bound for log (total_elements):    bits per byte (CHAR_BIT) * sizeof(size_t).  */ #define STACK_SIZE	(CHAR_BIT * sizeof(size_t)) #define PUSH(low, high)	((void) ((top->lo = (low)), (top->hi = (high)), ++top)) #define	POP(low, high)	((void) (--top, (low = top->lo), (high = top->hi))) #define	STACK_NOT_EMPTY	(stack < top)   /* Order size using quicksort.  This implementation incorporates    four optimizations discussed in Sedgewick:     1. Non-recursive, using an explicit stack of pointer that store the       next array partition to sort.  To save time, this maximum amount       of space required to store an array of SIZE_MAX is allocated on the       stack.  Assuming a 32-bit (64 bit) integer for size_t, this needs       only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes).       Pretty cheap, actually.     2. Chose the pivot element using a median-of-three decision tree.       This reduces the probability of selecting a bad pivot value and       eliminates certain extraneous comparisons.     3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving       insertion sort to order the MAX_THRESH items within each partition.       This is a big win, since insertion sort is faster for small, mostly       sorted array segments.     4. The larger of the two sub-partitions is always pushed onto the       stack first, with the algorithm then concentrating on the       smaller partition.  This *guarantees* no more than log (total_elems)       stack size is needed (actually O(1) in this case)!  */  void _quicksort (void *const pbase, size_t total_elems, size_t size, 	    __compar_d_fn_t cmp, void *arg) {   char *base_ptr = (char *) pbase;    const size_t max_thresh = MAX_THRESH * size;    if (total_elems == 0)     /* Avoid lossage with unsigned arithmetic below.  */     return;    if (total_elems > MAX_THRESH)     {       char *lo = base_ptr;       char *hi = &lo[size * (total_elems - 1)];       stack_node stack[STACK_SIZE];       stack_node *top = stack;        PUSH (NULL, NULL);        while (STACK_NOT_EMPTY)         {           char *left_ptr;           char *right_ptr;  	  /* Select median value from among LO, MID, and HI. Rearrange 	     LO and HI so the three values are sorted. This lowers the 	     probability of picking a pathological pivot value and 	     skips a comparison for both the LEFT_PTR and RIGHT_PTR in 	     the while loops. */  	  char *mid = lo + size * ((hi - lo) / size >> 1);  	  if ((*cmp) ((void *) mid, (void *) lo, arg) < 0) 	    SWAP (mid, lo, size); 	  if ((*cmp) ((void *) hi, (void *) mid, arg) < 0) 	    SWAP (mid, hi, size); 	  else 	    goto jump_over; 	  if ((*cmp) ((void *) mid, (void *) lo, arg) < 0) 	    SWAP (mid, lo, size); 	jump_over:;  	  left_ptr  = lo + size; 	  right_ptr = hi - size;  	  /* Here's the famous ``collapse the walls'' section of quicksort. 	     Gotta like those tight inner loops!  They are the main reason 	     that this algorithm runs much faster than others. */ 	  do 	    { 	      while ((*cmp) ((void *) left_ptr, (void *) mid, arg) < 0) 		left_ptr += size;  	      while ((*cmp) ((void *) mid, (void *) right_ptr, arg) < 0) 		right_ptr -= size;  	      if (left_ptr < right_ptr) 		{ 		  SWAP (left_ptr, right_ptr, size); 		  if (mid == left_ptr) 		    mid = right_ptr; 		  else if (mid == right_ptr) 		    mid = left_ptr; 		  left_ptr += size; 		  right_ptr -= size; 		} 	      else if (left_ptr == right_ptr) 		{ 		  left_ptr += size; 		  right_ptr -= size; 		  break; 		} 	    } 	  while (left_ptr <= right_ptr);            /* Set up pointers for next iteration.  First determine whether              left and right partitions are below the threshold size.  If so,              ignore one or both.  Otherwise, push the larger partition's              bounds on the stack and continue sorting the smaller one. */            if ((size_t) (right_ptr - lo) <= max_thresh)             {               if ((size_t) (hi - left_ptr) <= max_thresh) 		/* Ignore both small partitions. */                 POP (lo, hi);               else 		/* Ignore small left partition. */                 lo = left_ptr;             }           else if ((size_t) (hi - left_ptr) <= max_thresh) 	    /* Ignore small right partition. */             hi = right_ptr;           else if ((right_ptr - lo) > (hi - left_ptr))             { 	      /* Push larger left partition indices. */               PUSH (lo, right_ptr);               lo = left_ptr;             }           else             { 	      /* Push larger right partition indices. */               PUSH (left_ptr, hi);               hi = right_ptr;             }         }     }    /* Once the BASE_PTR array is partially sorted by quicksort the rest      is completely sorted using insertion sort, since this is efficient      for partitions below MAX_THRESH size. BASE_PTR points to the beginning      of the array to sort, and END_PTR points at the very last element in      the array (*not* one beyond it!). */  #define min(x, y) ((x) < (y) ? (x) : (y))    {     char *const end_ptr = &base_ptr[size * (total_elems - 1)];     char *tmp_ptr = base_ptr;     char *thresh = min(end_ptr, base_ptr + max_thresh);     char *run_ptr;      /* Find smallest element in first threshold and place it at the        array's beginning.  This is the smallest array element,        and the operation speeds up insertion sort's inner loop. */      for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size)       if ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, arg) < 0)         tmp_ptr = run_ptr;      if (tmp_ptr != base_ptr)       SWAP (tmp_ptr, base_ptr, size);      /* Insertion sort, running from left-hand-side up to right-hand-side.  */      run_ptr = base_ptr + size;     while ((run_ptr += size) <= end_ptr)       { 	tmp_ptr = run_ptr - size; 	while ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, arg) < 0) 	  tmp_ptr -= size;  	tmp_ptr += size;         if (tmp_ptr != run_ptr)           {             char *trav;  	    trav = run_ptr + size; 	    while (--trav >= run_ptr)               {                 char c = *trav;                 char *hi, *lo;                  for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo)                   *hi = *lo;                 *hi = c;               }           }       }   } }

user: user-9
content: 你要写的这个不是模版函数吗。。。用c好像很为难啊。。。

user: user-10
content: 我觉得应该是可以，只不过你在函数里面还要把它转成你要的类型。。 要不你就用泛型。。

user: user-4
content: #define  add (a,b,c)   ( c) = (a)+(b)   int main {  int a =0,b=1,c=2; double r=3,s=4,t=5; add(a,b,c); add(r,s,t); printf("%d %lf\n",c,t); return 0; }

user: user-11
content: 不可以，但可以是void*

user: user-12
content: 引用 6 楼 fuqingyun 的回复:[quote=引用 3 楼 robertbo 的回复:] 可以是void * 哥，还是不行  #include<stdio.h> add(void *x, void *y); void main() { 	int a=1; 	int b=2; 	printf("%d\n",add(&a,&b)); } int add(void *x, void *y) { 	int z; 	//printf("%d",sizeof(x)); 	z=x+y; 	return z; } //error C2110: cannot add two pointers加了*号了，还说指针不能相加  [/quote] 你需要的是C++的泛型，C不能很方便的解决这个问题。

user: user-13
content: 不可以 sizeof是运算符

user: user-14
content: LZ貌似要C++泛型  可以用void*  你代码相加 也是 z= *((int*)x)+*((int*)y);

user: user-15
content: 引用 6 楼 fuqingyun 的回复:[quote=引用 3 楼 robertbo 的回复:] 可以是void * 哥，还是不行  #include<stdio.h> add(void *x, void *y); void main() { 	int a=1; 	int b=2; 	printf("%d\n",add(&a,&b)); } int add(void *x, void *y) { 	int z; 	//printf("%d",sizeof(x)); 	z=x+y; 	return z; } //error C2110: cannot add two pointers加了*号了，还说指针不能相加  [/quote]谁说可以直接这样相加了，只是说可以用void*作为形参，你可以通过再加一个参数来表示某种类型，然后在函数内部根据第三个参数将对应的形参指针强制转化为对应的类型，从而取得正确的数值。比如第三个定义成枚举类型

user: user-0
content: 引用 3 楼 robertbo 的回复:可以是void * 哥，还是不行  #include<stdio.h> add(void *x, void *y); void main() { 	int a=1; 	int b=2; 	printf("%d\n",add(&a,&b)); } int add(void *x, void *y) { 	int z; 	//printf("%d",sizeof(x)); 	z=x+y; 	return z; } //error C2110: cannot add two pointers加了*号了，还说指针不能相加

user: user-16
content: sizeof 是运算符

user: user-0
content: 引用 3 楼 robertbo 的回复:可以是void * 谢谢，太有用了 那sizeof可以那么用吗？