user-0 提问: 自定义类型的输出

回复:
user: user-1
content: 解决方法： 1.宏+条件编译 2.定义输出函数 3.转向面向对象语言，对自定义类型重载运算符>>和<<

user: user-0
content: 楼上的大神，小生受教了，谢谢大家啊

user: user-2
content: 仅供参考：//带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*s1,*s2,*s3,*s4,*s; int i,j,k,n,t,m; int main() {     srand(time(NULL));      //填写头节点数据     H.data=-1;     H.next=NULL;     head=&H;      //创建10个节点的单链表     p=head;     for (i=0;i<10;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) return 1;         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         p->next=q;         p=q;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将值为5的结点插入到单链表的第k个结点前     k=3;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) return 1;             q->data=5;             q->next=p->next;             p->next=q;             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //删除第k个节点     k=5;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=p->next;             if (q) {                 p->next=q->next;                 free(q);             }             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //从小到大排序     for (p=head;p!=NULL && p->next!=NULL;p=p->next) {         for (q=p->next;q!=NULL && q->next!=NULL;q=q->next) {             if (p->next->data > q->next->data) {                  //交换data //              printf("swap %02d %02d\n",p->next->data,q->next->data); //              t=p->next->data;p->next->data=q->next->data;q->next->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->next->data,q->next->data);                 s1=p->next;                 s2=p->next->next;                 s3=q->next;                 s4=q->next->next;                  if (s2!=s3) {                      p->next=s3;                     s3->next=s2;                      q->next=s1;                     s1->next=s4;                 } else {                      p->next=s3;                     s3->next=s1;                            q=s3;                     s1->next=s4;                 }                  //输出整个单链表 //              s=head->next; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将单链表中前 m 个结点和后 n 个结点进行互换,m+n为链表总长10     m=4;     n=6;     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m+1==k) {             q=p;         }         s=p;         p=p->next;     }     s1=head->next;     head->next=q->next;     s->next=s1;     q->next=NULL;      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head->next;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //18->94->58->17->27->20->43->57->75->78-> //18->94->05->58->17->27->20->43->57->75->78-> //18->94->05->58->27->20->43->57->75->78-> //05->18->20->27->43->57->58->75->78->94-> //43->57->58->75->78->94->05->18->20->27-> //   十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495

user: user-3
content: 我就想不明白了，你既然定义了是 int，那为什么要输出 char 呢？不是难为自己吗

user: user-4
content: 引用 22 楼 zhao4zhong1 的回复:[quote=引用 20 楼 sholber 的回复:] [quote=引用 19 楼 zhao4zhong1 的回复:] 操作符重载是语法糖。 语法糖越甜，编译调试查错越苦！ 把有限的生命浪费在品尝/品鉴无穷多种的语法糖中，我认为不值当。 我正式宣布， 支持赵老湿！！！嘎嘎~~[/quote] [/quote]  我一贯是反对赵老湿的，今天突然宣布支持赵老师， 反观赵老湿，突然遭到表扬，还有点小小的不适应哈，嘎嘎~~

user: user-2
content: 引用 20 楼 sholber 的回复:[quote=引用 19 楼 zhao4zhong1 的回复:] 操作符重载是语法糖。 语法糖越甜，编译调试查错越苦！ 把有限的生命浪费在品尝/品鉴无穷多种的语法糖中，我认为不值当。 我正式宣布， 支持赵老湿！！！嘎嘎~~[/quote]

user: user-2
content: 引用 20 楼 sholber 的回复:[quote=引用 19 楼 zhao4zhong1 的回复:] 操作符重载是语法糖。 语法糖越甜，编译调试查错越苦！ 把有限的生命浪费在品尝/品鉴无穷多种的语法糖中，我认为不值当。 我正式宣布， 支持赵老湿！！！嘎嘎~~[/quote]

user: user-4
content: 引用 19 楼 zhao4zhong1 的回复:操作符重载是语法糖。 语法糖越甜，编译调试查错越苦！ 把有限的生命浪费在品尝/品鉴无穷多种的语法糖中，我认为不值当。 我正式宣布， 支持赵老湿！！！嘎嘎~~

user: user-2
content: 操作符重载是语法糖。 语法糖越甜，编译调试查错越苦！ 把有限的生命浪费在品尝/品鉴无穷多种的语法糖中，我认为不值当。

user: user-4
content: 引用 17 楼 lincolnandlinda 的回复:[quote=引用 16 楼 sholber 的回复:] [quote=引用 15 楼 lincolnandlinda 的回复:] 用C语言是没法解决这个问题的, 通过C++的操作符重载可以实现.  本来懒得发言的，既然你这么说，我就来抬个杠。 实际上，C解决这个问题一点问题都没有，因为C11引入了泛型。以下是我的方案，嘎嘎~ # include <stdio.h>  typedef float Elemtype; # define print(x) printf ( \                     _Generic (x, \                        char : "%c\n", \                        int : "%d\n", \                        float : "%f\n" \                        ), x)  int main (void) {     Elemtype x = 2.0f;     print (x);      char c = 'x';     print (c);      int i = 10010;     print (i);      print (10086); }  是不是很有意思啊？嘎嘎~~我是用CLANG编译的。VS就不要做梦了…… [/quote] 受教了.但是有个问题: 如果用户把ElementType定义为一个自定义的结构体,或者增加一种新的类型,  那这需要修改宏的定义是不是?  [/quote] 对。 不过不是修改宏，是修改泛型选择表达式。它是可以扩充的嘛。

user: user-5
content: 引用 16 楼 sholber 的回复:[quote=引用 15 楼 lincolnandlinda 的回复:] 用C语言是没法解决这个问题的, 通过C++的操作符重载可以实现.  本来懒得发言的，既然你这么说，我就来抬个杠。 实际上，C解决这个问题一点问题都没有，因为C11引入了泛型。以下是我的方案，嘎嘎~ # include <stdio.h>  typedef float Elemtype; # define print(x) printf ( \                     _Generic (x, \                        char : "%c\n", \                        int : "%d\n", \                        float : "%f\n" \                        ), x)  int main (void) {     Elemtype x = 2.0f;     print (x);      char c = 'x';     print (c);      int i = 10010;     print (i);      print (10086); }  是不是很有意思啊？嘎嘎~~我是用CLANG编译的。VS就不要做梦了…… [/quote] 受教了.但是有个问题: 如果用户把ElementType定义为一个自定义的结构体,或者增加一种新的类型,  那这需要修改宏的定义是不是?

user: user-4
content: 引用 15 楼 lincolnandlinda 的回复:用C语言是没法解决这个问题的, 通过C++的操作符重载可以实现.  本来懒得发言的，既然你这么说，我就来抬个杠。 实际上，C解决这个问题一点问题都没有，因为C11引入了泛型。以下是我的方案，嘎嘎~ # include <stdio.h>  typedef float Elemtype; # define print(x) printf ( \                     _Generic (x, \                        char : "%c\n", \                        int : "%d\n", \                        float : "%f\n" \                        ), x)  int main (void) {     Elemtype x = 2.0f;     print (x);      char c = 'x';     print (c);      int i = 10010;     print (i);      print (10086); }  是不是很有意思啊？嘎嘎~~我是用CLANG编译的。VS就不要做梦了……

user: user-5
content: 用C语言是没法解决这个问题的, 通过C++的操作符重载可以实现.

user: user-6
content: 我感觉一般用到这种typedef的，，基本都是接口里，一般都是写好几个仅供使用的函数直接用的，所以在具体的调用接口的程序里，输出的话，单独写个输出的函数，然后在改接口里的typedef定义的类型的时候，直接改输出函数里的格式控制符就好了。个人愚见，说的不好的话，，请喷！

user: user-7
content: 楼主是不会学会了printf就可以包打天下了？就没有别的要学的了吗？知道sprintf不？

user: user-8
content: typedef int Elemtype; Elemtype作了int的别名，就不能再作char的别名~~~

user: user-9
content: 感觉C语言不好去实现，用类吧。

user: user-10
content: 引用 3 楼 kuangbao9 的回复:楼主是不是想要下面的这种呀？用cout就可以了。 #include<iostream> using namespace std; int main() { 	typedef int Elemtype; 	Elemtype a; 	cout<<a<<endl; 	return 0; }  这里讨论的是C语言，不是C++。 typedef会为已有的类型名取一个别名，这么干的唯一好处是，当类型发生变化时，只修改typedef 这一句即可，

user: user-11
content: 自己写一个输出函数呗

user: user-12
content: typedef  只是给int起了一个别名， 本质还是int， printf("%d\n", i);