Question: 求C语言螺旋向外遍历的算法代码

你的这个需求很像建立螺旋数组的逆过程。建议参考： https://blog.csdn.net/qq_27183003/article/details/49699463 可以逆序一下。

Do not let me think!#include <stdio.h> #define MAXN 100 int m[MAXN+2][MAXN+2]; char d; int x,y,k,n,w; char str[10]; void main() {     while (1) {         printf("Input n(1..%d):",MAXN);         fflush(stdout);         rewind(stdin);         if (1==scanf("%d",&n)) {             if (1<=n && n<=MAXN) break;         }     }     y=0  ;for (x=0;x<=n+1;x++) m[y][x]=1;     y=n+1;for (x=0;x<=n+1;x++) m[y][x]=1;     x=0  ;for (y=0;y<=n+1;y++) m[y][x]=1;     x=n+1;for (y=0;y<=n+1;y++) m[y][x]=1;     for (y=1;y<=n;y++) {         for (x=1;x<=n;x++) {             m[y][x]=0;         }     }     x=1;     y=1;     k=0;     d='D';     while (1) {         k++;         if (k>n*n) break;         m[y][x]=k;         switch (d) {             case 'D':                 if (0==m[y+1][x])  y++;                 else              {x++;d='R';}             break;             case 'R':                 if (0==m[y][x+1])  x++;                 else              {y--;d='U';}             break;             case 'U':                 if (0==m[y-1][x])  y--;                 else              {x--;d='L';}             break;             case 'L':                 if (0==m[y][x-1])  x--;                 else              {y++;d='D';}             break;         }     } 	w=sprintf(str,"%d",n*n);     for (y=1;y<=n;y++) {         for (x=1;x<=n;x++) {             printf(" %0*d",w,m[y][x]);         }         printf("\n");     } }

#include <stdio.h> #include <math.h> #define M 5 #define N 5 void fun(); int main() { 	fun(); 	return 0; } //m*m void fun() {    int arry[M][N] = {0};        int i,j,k;    int cnt = M*N;//1--M*M    //for(i = 0;i < (int)(M*1.0/2 +0.5);i++){ 	for(i = 0;i < ceil(sqrt(M*M+N*N)/2);i++) {   	   for(j=i,k=i;k < N-i;k++){ 		   arry[j][k] = cnt; 		   cnt--; 	   } 	   for(j=i+1,k=N-1-i;j<M-i;j++){ 		   arry[j][k] = cnt; 		   cnt--; 	   } 	   for(j=M-1-i,k=N-2-i;k>=0+i;k--){ 		   arry[j][k] = cnt; 		   cnt--; 	   } 	   for(j=M-2-i,k=0+i;j>=1+i;j--){ 		   arry[j][k] = cnt; 		   cnt--; 	   }    }    for(i=0;i < M;i++){      for(j=0;j < N;j++) 		 printf("%02d ",arry[i][j]);      printf("\n");    } }


Question: 求助，约瑟夫环问题，删除函数中有逻辑错误导致运行结果不对

#include<stdio.h> #include<stdlib.h> #include<string.h>  struct node {     int num;     char name[20];     struct node *next; };  struct node *create_singly_link(int num) {     struct node *head, *prev, *cur;     int i;      head = NULL;     for(i = 0; i < num; i++) {         cur = (struct node *)malloc(sizeof(struct node));         if (!cur) {             printf("Malloc error!");             return NULL;         }         cur->next = NULL;         cur->num = i+1;         snprintf(cur->name, 20-1, "%c", 'A'+i);         if (!head) {             head = cur;             prev = cur;         } else {             prev->next = cur;             prev = prev->next;         }     }     prev->next = head;     return head; }  static void test_print(struct node *phead) {     struct node *pcur = phead->next;      printf("num = %d\t name = %s\n", phead->num, phead->name);     while (pcur != phead) {         printf("num = %2d\t name = %s\n", pcur->num, pcur->name);         pcur = pcur->next;     } }  int output( struct node *head, int start, int step, int total) {     struct node *p, *q;     int count = 0;     int num = 0, i;      q = head;      for(i = 0; i < start; i++)         q = q->next;      while(count < total-1) {         p = q->next;         num++;         if(!(num % step)) {             q->next = p->next;             printf("%s\n", p->name);             free(p);             count++;         } else {             q = p;         }     }     printf("num = %d\t, name = %s\n", q->num, q->name);     free(q);      return 0; } int main(int argc, const char *argv[]) {     int total, step, start;     struct node *head;      printf("Please input total test number: ");     scanf("%d", &total);     head = create_singly_link(total);     test_print(head);      printf("Please input start position and steps: ");     scanf("%d%d", &start, &step);      output(head, start, step, total);      return 0; } 参考一下吧

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  百度搜相关关键字。

#include <stdio.h> #include <string.h> #include <stdlib.h>  typedef struct list //定义链表类型 { 	int number, code; 	struct list *next; } LIST, *ZLIST;  //计算环形链表元素个数 int count(ZLIST p_head) { 	if(p_head == NULL) 	{ 		return 0; 	} 	int i = 1; 	ZLIST p_tmp = p_head; 	while(p_tmp->next != p_head) 	{ 		p_tmp = p_tmp ->next; 		++i; 		// printf(" %d  ",i); 	} 	return i; }  void deletelist(ZLIST p_head, int n, int m) //找出每轮出列的人并删除，t为尾指针，n为总人数，m为初始报数上线 { 	// int i, k = m; 	// ZLIST p, pre; 	// pre = t; 	// while (pre->next != pre)				--》结束条件有问题 	// { 	// 	for (i = 0; i < k; i++) 	// 		pre = pre->next; 	// 	p = pre->next; //找到要删除元素 	// 	printf("%4d", p->number); 	// 	k = p->code;		 //记录密码 	// 	pre->next = p->next; //链接				 	// 	free(p); 	// } 	int k = m; 	ZLIST p_node ; 	ZLIST p_mid = p_head; 	ZLIST p_end; 	while(1) 	{ 		for(int i = 0; i < k -1 ; ++i) 		{ 			p_node = p_mid; 			p_mid = p_mid ->next; 		} 		p_end = p_mid -> next;			//这里要把链表连起来不能断了 		p_node->next = p_end; 		printf("%-4d",p_mid->number); 		k = p_mid->code; 		free(p_mid); 		p_mid = p_end; 		if ( count(p_mid) == 2) 		{ 			break; 		} 	} 	printf("p_mid :[%d], p_mid->next:[%d]", p_mid->number, p_mid->next->number); }  ZLIST CreateList(int num) { 	ZLIST p_head = NULL, p_tmp = NULL; 	for (int i = 0; i < num; ++i) 	{ 		ZLIST newNode = (ZLIST)malloc(sizeof(LIST)); 		if (newNode == NULL) 		{ 			printf("分配内存失败 "); 			return NULL; 		} 		newNode->number = i + 1; 		newNode->code = 3; 		newNode->next = NULL; 		if ( p_head != NULL) 		{ 			p_tmp->next = newNode; 			p_tmp = p_tmp->next; 		} 		else 		{ 			p_head = newNode; 			p_tmp = p_head; 		} 	} 	p_tmp -> next = p_head; 	return p_head; }  void print(ZLIST p_head) { 	ZLIST p_tmp = p_head; 	do 	{ 		printf("number:[%d],code:[%d]\n",p_tmp->number, p_tmp->code); 	}while(p_head != (p_tmp = p_tmp->next)); }  int main() { 	ZLIST p_list; 	print(p_list = CreateList(41)); 	deletelist(p_list, 41, 3); 	return 0; }


Question: 如何获取 tcp header

用sock试试

recv获取到的是应用层的数据得不到tcp header。 个人建议可以使用Libpacp库获得从物理层得到的数据，然后层层解析，就可以得到你想要的tcp header

数据已经到应用层了, 肯定取不到TCP header, 如果想取TCP数据, 需要先将网卡设置成混杂模式, 然后创建PF_PACKET 类型socket, 这样你才能取到tcp的数据.  例子可以参照下面楼我写的demo, 修改一下网卡名TARGET_INTERFACE就可以用了.  #include <sys/types.h> #include <sys/socket.h> #include <sys/ioctl.h>  #include <net/if.h> #include <netinet/in.h> #include <linux/if_ether.h> #include <linux/tcp.h>  #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h>   #include <errno.h>  ////////////////////////////////////////////////////////////////////////////// #define TARGET_INTERFACE "eth0"  typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; typedef unsigned long long int uint64_t;  //////////////////////////////////////////////////////////////////////////////  typedef enum _tcpFlag { 	TH_FIN	= 0x01, /* finish, no more data from sender(Last package from sender) */ 	TH_SYN	= 0x02, /* Synchronize sequence numbers */ 	TH_RST	= 0x04, /* Reset the connection */  	TH_PUSH = 0x08, /* Push function, Asks to push the buffered data to the receiving application */  	TH_ACK	= 0x10, /* indicates that the ACKnowledgment field is significant (Sometimes abbreviated by tcpdump as ".") */  	TH_URG	= 0x20, /* ndicates that the URGent pointer field is significant */  	TH_ECE	= 0x40, /* ECN Echo */ 	TH_CWR	= 0x80, /* ECN Cwnd Reduced */ }tcpFlag_t;  /* Structure of an Ethernet header.*/ typedef struct _eth_hdr { 	uint8_t 	dstmac[6];	/* dest mac addr */ 	uint8_t 	srcmac[6];	/* source mac addr */ 	uint16_t	type;		/* Ethernet type */ } eth_hdr;  /* Structure of an internet header, naked of options */ typedef struct _ip_hdr { #ifdef LITTLE_ENDIAN 	uint8_t 	ip_hlen:4;	/* Internet Header Length(means the count of 32bit words) */ 	uint8_t 	ip_ver:4;	/* version */ #else /* LITTLE_ENDIAN */ 	uint8_t 	ip_ver:4;	/* version */ 	uint8_t 	ip_hlen:4;	/* Internet Header Length */ #endif /* LITTLE_ENDIAN */ 	uint8_t 	ip_tos; 	/* type of service */ 	uint16_t	ip_len; 	/* total length */ 	uint16_t	ip_id;		/* identification */ 	uint16_t	ip_off; 	/* fragment offset field */ 	uint8_t 	ip_ttl; 	/* time to live */ 	uint8_t 	ip_p;		/* protocol */ 	uint16_t	ip_sum; 	/* checksum */ 	uint32_t	ip_src; 	/* source address */ 	uint32_t	ip_dst; 	/* dest address */ 	uint8_t 	options[0]; /* ip options */ } ip_hdr;  /* Structure of an TCP header */ typedef struct _tcp_hdr { 	uint16_t	th_sport;	/* source port */ 	uint16_t	th_dport;	/* destination port */ 	uint32_t	th_seq; 	/* sequence number */ 	uint32_t	th_ack; 	/* acknowledgement number */ #ifdef LITTLE_ENDIAN 	uint8_t 	th_rsvd:3;	/* reversed */ 	uint8_t 	th_ns:1;	/* ns flag */ 	uint8_t 	th_oft:4;	/* data offset */ #else  /* LITTLE_ENDIAN */ 	uint8_t 	th_oft:4;	/* data offset */ 	uint8_t 	th_rsvd:3;	/* reversed */ 	uint8_t 	th_ns:1;	/* ns flag */ #endif /* LITTLE_ENDIAN */ 	uint8_t 	th_flags;	/* tcp flag */ 	uint16_t	th_win; 	/* window */ 	uint16_t	th_sum; 	/* checksum */ 	uint16_t	th_urp; 	/* urgent pointer */ 	uint8_t 	options[0]; /* tcp options */ } tcp_hdr;  /* Structure of an TCP session, used for calc relative seq and ack */ typedef struct _tcp_sess_hash { 	struct _tcp_sess_hash* next; 	uint64_t ip; 	uint32_t seq; 	uint32_t ack; 	uint8_t* data; 	uint16_t data_len; } tcp_sess_hash_t;  #define TCP_SESS_HASH_COUNT (1000) static tcp_sess_hash_t tcp_sess_hash_bucket[TCP_SESS_HASH_COUNT];  typedef struct _tcp_show { 	uint8_t direction; 	uint8_t optlen; /* tcp option lenght */ 	uint16_t length; /* real data length */ 	uint32_t seq; /* relative seq */ 	uint32_t ack; /* relative ack */ 	uint32_t abs_seq; /* orgin seq */ 	uint32_t abs_ack; /* orgin ack */ } tcp_show_t;  /* these two macros for print mac address */ #define PNTMAC(mac) \ 	((unsigned char*)&mac)[0], \ 	((unsigned char*)&mac)[1], \ 	((unsigned char*)&mac)[2], \ 	((unsigned char*)&mac)[3], \ 	((unsigned char*)&mac)[4], \ 	((unsigned char*)&mac)[5] #define PNTMAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"  /* these two macros for print ipv4 address */ #define NIPQUAD(addr) \ 	((unsigned char *)&addr)[0], \ 	((unsigned char *)&addr)[1], \ 	((unsigned char *)&addr)[2], \ 	((unsigned char *)&addr)[3] #define NIPQUAD_FMT "%u.%u.%u.%u"  ///////////////////////////////////////////////////////////////////////////// int setPromiscuous(int sock, char* ethx); void procPacket(char* buf, ssize_t len);  ////////////////////////////////////////////////////////////////////////////// int main(void) { 	int sock; 	ssize_t sRet = 0; 	char buf[4096];  	//create a PACKET socket 	sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); 	if (sock < 0) { 		perror("socket failed"); 		exit(EXIT_FAILURE); 	}  	//set promiscuous mode,if you are root 	sRet = setPromiscuous(sock, TARGET_INTERFACE); 	if (sRet < 0) { 		close(sock); 		perror("ioctl failed"); 		exit(EXIT_FAILURE); 	}  	//receive packet 	while (1) { 		sRet = recv(sock, buf, sizeof(buf), 0); 		if (sRet < 0) { 			perror("recv failed"); 			break; 		} 		else if(0 == sRet) { 			printf("peer point performed an shutdown\n"); 			break; 		} 		else { 			procPacket(buf, sRet); 		} 	} 	 	close(sock);  	return 0; }   ////////////////////////////////////////////////////////////////////////////// int setPromiscuous(int sock, char* ethx) {	 	uid_t uid = 0; 	struct ifreq ethreq;  	uid = getuid(); 	if (uid != 0) { 		printf("You are not root, can't change %s to Promiscuous Mode\n", ethx); 		return 0; 	}  	strncpy(ethreq.ifr_name, ethx, IFNAMSIZ); 	 	if (ioctl(sock, SIOCGIFFLAGS, ðreq) < 0) { 		return -1; 	} 	 	ethreq.ifr_flags |= IFF_PROMISC; 	if( ioctl(sock, SIOCSIFFLAGS, ðreq) < 0) { 		return -2; 	}  	return 0; }  ////////////////////////////////////////////////////////////////////////////// static char* getTcpFlags(uint8_t flag) { 	static char buf[32];  	memset(buf, 0x00, sizeof(buf)); 	if (flag & TH_FIN)	strcat(buf, "F"); 	if (flag & TH_SYN)	strcat(buf, "S"); 	if (flag & TH_RST)	strcat(buf, "R"); 	if (flag & TH_PUSH)	strcat(buf, "P"); 	if (flag & TH_URG) 	strcat(buf, "U"); 	if (flag & TH_ECE)	strcat(buf, "E"); 	if (flag & TH_CWR)	strcat(buf, "W"); 	if (flag & TH_ACK)	strcat(buf, "."); 	 	return buf; }   static char* getTcpOptions(uint8_t* option, tcp_show_t* show) {  	uint8_t i = 0; 	uint8_t loop = 0; 	int loop_flag = 1; 	uint8_t count = 0; 	uint32_t s,e; 	char tmp[32]; 	static char buf[1024];  	if (show->optlen == 0) { 		return ","; 	}  	memset(buf, 0x00, sizeof(buf)); 	strcpy(buf, ", options ["); 	while (loop_flag) {  		if (loop >= show->optlen) { 			goto FINISH; 		}  		switch (option[loop]) { 		case 0: /* EOL : End of Option List */ 			loop_flag = 0; 			break; 		 		case 1: /* NOP : No-Operation */ 			strcat(buf, "nop,"); 			loop++; 			break; 			 		case 2: /* MSS : Maximum Segment Size */ 			sprintf(tmp, "mss %u,", ntohs(*(uint16_t*)(option + loop + 2))); 			strcat(buf, tmp); 			loop += option[loop + 1]; 			break; 			 		case 3: 			sprintf(tmp, "wscale %u,", (*(uint8_t*)(option + loop + 2))); 			strcat(buf, tmp); 			loop += option[loop + 1]; 			break; 			 		case 4: 			strcat(buf, "sackOK,"); 			loop += option[loop + 1]; 			break; 			 		case 5: 			count = (option[loop + 1] - 2) / 8; 			sprintf(tmp, "sack %d ", count); 			strcat(buf, tmp); 			for (i = 0; i < count; i++) { 				s = ntohl(*(uint32_t*)(option + loop + 2 + i * 8)); 				e = ntohl(*(uint32_t*)(option + loop + 6 + i * 8)); 	 				if (show->direction) { 					sprintf(tmp, "{%u,%u}", s - show->abs_seq, e - show->abs_seq); 				} else { 					sprintf(tmp, "{%u,%u}", s - show->abs_ack, e - show->abs_ack); 				} 				strcat(buf, tmp); 			} 			strcat(buf, ","); 			loop += option[loop + 1]; 			break; 			 		case 8: 			strcat(buf, "TSOPT,"); 			loop += option[loop + 1]; 			break;  		default: 			loop += option[loop + 1]; 			break; 		} 	}  FINISH: 	strcpy(buf + strlen(buf) - 1, "],"); 	return buf; }   int procSession(ip_hdr* ip, tcp_hdr* tcp, tcp_show_t* show) { 	tcp_sess_hash_t* sess = NULL; 	uint64_t ip_combine = 0; 	uint32_t hash = 0; 	 	static char buf[128] = {0};  	show->seq = ntohl(tcp->th_seq); 	show->ack = ntohl(tcp->th_ack); 	 	if (tcp->th_sport > tcp->th_dport) { 		show->direction = 1; 		hash = ((uint32_t)tcp->th_dport << 16 + tcp->th_sport) % TCP_SESS_HASH_COUNT; 		ip_combine = (uint64_t)ip->ip_dst << 32 + ip->ip_src; 	} 	else { 		show->direction = 0; 		hash = ((uint32_t)tcp->th_sport << 16 + tcp->th_dport) % TCP_SESS_HASH_COUNT; 		ip_combine = (uint64_t)ip->ip_src << 32 + ip->ip_dst; 	}  	for (sess = &tcp_sess_hash_bucket[hash]; sess->next; sess = sess->next) { 		if (sess->ip == ip_combine) { 			break; 		} 	}  	if (!sess->next || (tcp->th_flags & TH_SYN)) { 		if (!sess->next) { 			sess->next = (tcp_sess_hash_t*)calloc(1, sizeof(tcp_sess_hash_t)); 			if (!sess->next) { 				printf("<ERROR> calloc failed\n"); 				return -1; 			} 		}  		sess->ip = ip_combine; 		if (show->direction) { 			sess->seq = show->ack - 1; 			sess->ack = show->seq; 		} else { 			sess->seq = show->seq; 			sess->ack = show->ack - 1; 		} 	} else { 		if (show->direction) { 			show->seq -= sess->ack; 			show->ack -= sess->seq; 		} else { 			show->seq -= sess->seq; 			show->ack -= sess->ack; 		} 	}  	show->length = ntohs(ip->ip_len)- (ip->ip_hlen + tcp->th_oft) * 4; 	show->optlen = (tcp->th_oft - 5) * 4; 	show->abs_ack = sess->ack; 	show->abs_seq = sess->seq;  	sess->data_len += show->length;  	return 0; }  void procPacket(char* buf, ssize_t len) { 	eth_hdr* eth = (eth_hdr*)buf; 	ip_hdr* ip = (ip_hdr*)(buf + sizeof(eth_hdr)); 	tcp_hdr* tcp = (tcp_hdr*)((void*)ip + sizeof(ip_hdr)); 	tcp_show_t show;   	/* just process the IPv4 TCP packet */ 	if ((ip->ip_p != IPPROTO_TCP) || (ip->ip_ver != 4)){ 		return; 	} 	procSession(ip, tcp, &show); 	printf("[TCP] "NIPQUAD_FMT".%d > "NIPQUAD_FMT".%d: Flags [%s], seq %u, ack %u, win:%u%s length %u\n", \ 		NIPQUAD(ip->ip_src), ntohs(tcp->th_sport), \ 		NIPQUAD(ip->ip_dst), ntohs(tcp->th_dport), \ 		getTcpFlags(tcp->th_flags),  \ 		show.seq, show.ack, ntohs(tcp->th_win), \ 		getTcpOptions(tcp->options, &show), \ 		show.length); }

顶.............


Question: C语言fopen函数问题

电脑内存或文件内容或传输内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容或传输内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  对电脑而言没有乱码，只有二进制字节；对人脑才有乱码。啊 GBK:0xB0 0xA1,Unicode-16 LE:0x4A 0x55,Unicode-16 BE:0x55 0x4A,UTF-8:0xE5 0x95 0x8A

二进制文件本有时也会有类似文本文件的特性，比如你存的是字符'1'，存入文件的与文本文件是一样的，记事本打开字然也是对应的文本，如果你存数字1，打开就会是乱码，此外，WINDOWS下文本文件换行符为\r\n，如果写入\n，二进制文件写入\n，文本文件写入\r\n  二进制或文本文件都是区分给人的，SDK实现层都是一样的

因为你写入的都是ascii码, 你写几个汉字试试就知道了

若打开的文件，用fwrite写入的就可能是乱码； fopen以ab+只是以二进制（追加）形式打开文件，没说文件就是二进制文件。


Question: c指针求教

这个是memcpy的百度介绍，你可以看看，这个要拷贝指针空间的话，建议使用memcpy这个可以更加便捷的拷贝过去，使用指针的话，只是一个地址的传递，可能会在后面一不小心就失误而丢掉了这个地址，所以这个地址传递最好用memcpy函数代替。

int a[5] = {1,2,3,4,5}; int b[5] = {6,7,8,9,0};  void copy_a(int *p) { 	//p=a; 	memcpy(p, a, sizeof(a)); }  int show_b(int *p, int len) { 	int i=0; 	for(; i<len; i++) 		printf("%d ", p[i]); 	printf("\n"); }  int main(int argc, char **argv) { 	printf("a:"); 	show_b(a, 5); 	printf("b:"); 	show_b(b, 5); 	 	copy_a(b); 	printf("\ncopy afer b:"); 	show_b(b, 5); 	 	return 0; } 经过验证，这种方法是可行的，你可以参照下

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……

直接赋值、引用不就完了吗？

引用 5 楼 weixin_39587157 的回复:#include <stdio.h>  int a[5] = {1,2,3,4,5}; int b[5] = {9,8,7,6,5};  void copy_a(int *p) { p = a;//这个a都没定义，况且它是局部变量来的，与int a[5] = {1,2,3,4,5}; 中的a一点关系都没有 } int main() { copy_a(b); }   改为 #include <stdio.h>  int a[5] = {1,2,3,4,5}; int b[5] = {9,8,7,6,5};  void copy_a(int *p，int  *a)  { p = a; } int main() { copy_a(b,a); } 这样改一样不可以。 建议使用memcpy或者 void copy_a(int *p，int  *a， int size)  {     int i;     for (i = 0; i < size; i++)         p[i] = a[i]; } int main() { copy_a(b, a, 5); }

引用 15 楼 xiejianjun417 的回复:[quote=引用 5 楼 weixin_39587157 的回复:] #include <stdio.h>  int a[5] = {1,2,3,4,5}; int b[5] = {9,8,7,6,5};  void copy_a(int *p) { p = a;//这个a都没定义，况且它是局部变量来的，与int a[5] = {1,2,3,4,5}; 中的a一点关系都没有 } int main() { copy_a(b); }   改为 #include <stdio.h>  int a[5] = {1,2,3,4,5}; int b[5] = {9,8,7,6,5};  void copy_a(int *p，int  *a)  { p = a; } int main() { copy_a(b,a); } a本来就是全局变量，何来的未定义？请弄清楚，全局变量与局部变量的定义和区别[/quote]  好吧！ 嘻嘻，可能几不清楚咯！ 普通局部变量，作用于他定义的函数中，用完就释放它开辟的内存 静态局部变量，作用于它定义的函数中，用完不释放内存，一直占用着 普通全局变量，作用于程序所有地方，一直存在，直到程序结束后释放内存 静态全局变量，作用于程序所有地方，一直存在，直到关闭程序后释放内存 有点模模糊糊 不知道记不记错

引用 5 楼 weixin_39587157 的回复:#include <stdio.h>  int a[5] = {1,2,3,4,5}; int b[5] = {9,8,7,6,5};  void copy_a(int *p) { p = a;//这个a都没定义，况且它是局部变量来的，与int a[5] = {1,2,3,4,5}; 中的a一点关系都没有 } int main() { copy_a(b); }   改为 #include <stdio.h>  int a[5] = {1,2,3,4,5}; int b[5] = {9,8,7,6,5};  void copy_a(int *p，int  *a)  { p = a; } int main() { copy_a(b,a); } a本来就是全局变量，何来的未定义？请弄清楚，全局变量与局部变量的定义和区别

引用 楼主 ZK880127 的回复:想把a里的东西考进b里，这样为什么不行？  #include <stdio.h>  int a[5] = {1,2,3,4,5}; int b[5] = {9,8,7,6,5};  void copy_a(int *p) { 	p = a; } int main() { 	copy_a(b); } 你这样的做法，只是将临时指针变量p指向了a数组的首地址。函数调用参数传递，本质都是值传递，对于指针而言，只不过传递的是地址而已。 举例： 执行copy_a(b);时，会分配一个指向int型的指针变量p(栈变量(临时变量))，然后会把数组b的首地址赋值给变量p，而执行p=a时，只是将a的地址赋值给p。而数组a和b的数据未做任何改变

代码及测试结果如下： #include <stdio.h>  int a[] = {1,2,3,4,5}; int b[] = {9,8,7,6,5};  void copy_a(int *pB, int *pA, int count) {     for (int i = 0; i < count; i++)     {         pB[i] = pA[i];     } }  void printArray(const char *msg, int *array, int count) {     printf("%s: ", msg);     for (int i = 0; i < count; i++)     {         printf("%d ", array[i]);     }     printf("\n"); }  int main(void) {     printArray("b", b, 5);     copy_a(b, a, 5);     printArray("b", b, 5);     return 0; }

引用 11 楼 cfjtaishan 的回复:[quote=引用 7 楼 weixin_39587157 的回复:] [quote=引用 6 楼 cfjtaishan 的回复:] [quote=引用 5 楼 weixin_39587157 的回复:] #include <stdio.h>  int a[5] = {1,2,3,4,5}; int b[5] = {9,8,7,6,5};  void copy_a(int *p) { p = a;//这个a都没定义，况且它是局部变量来的，与int a[5] = {1,2,3,4,5}; 中的a一点关系都没有 } int main() { copy_a(b); }   改为 #include <stdio.h>  int a[5] = {1,2,3,4,5}; int b[5] = {9,8,7,6,5};  void copy_a(int *p，int  *a)  { p = a; } int main() { copy_a(b,a); } 这样改一样不可以。 建议使用memcpy或者 void copy_a(int *p，int  *a， int size)  {     int i;     for (i = 0; i < size; i++)         p[i] = a[i]; } int main() { copy_a(b, a, 5); } [/quote]  还是不对 p[i] = a[i]; 这里只是改变指针p的指向，没有给main函数的b赋值 要改为*p[i] = *a[i];[/quote] 个人建议，理论应该和实践多做结合。对与不对，试了就知道了。[/quote] 嗯嗯，你的是对的。不好意思没注意p[i]等于*(p+i)嘻嘻，不过总的来说 要想改变主调函数中变量的值，必须传变量的地址，而且还得通过*+地址 去赋值，只是写的形式不同而已。

引用 7 楼 weixin_39587157 的回复:[quote=引用 6 楼 cfjtaishan 的回复:] [quote=引用 5 楼 weixin_39587157 的回复:] #include <stdio.h>  int a[5] = {1,2,3,4,5}; int b[5] = {9,8,7,6,5};  void copy_a(int *p) { p = a;//这个a都没定义，况且它是局部变量来的，与int a[5] = {1,2,3,4,5}; 中的a一点关系都没有 } int main() { copy_a(b); }   改为 #include <stdio.h>  int a[5] = {1,2,3,4,5}; int b[5] = {9,8,7,6,5};  void copy_a(int *p，int  *a)  { p = a; } int main() { copy_a(b,a); } 这样改一样不可以。 建议使用memcpy或者 void copy_a(int *p，int  *a， int size)  {     int i;     for (i = 0; i < size; i++)         p[i] = a[i]; } int main() { copy_a(b, a, 5); } [/quote]  还是不对 p[i] = a[i]; 这里只是改变指针p的指向，没有给main函数的b赋值 要改为*p[i] = *a[i];[/quote] 弱弱的问一下，你有没有在编译环境里试一试？这是一重指针，为啥要用*p[i] = *a[i]呢？ 但从理论分析上，*p[i]是什么？p是一重指针，那么p[i]就是*(p + i);就是b数组第i的下表对应的值，加上*怎么理解了呢？

引用 7 楼 weixin_39587157 的回复:[quote=引用 6 楼 cfjtaishan 的回复:] [quote=引用 5 楼 weixin_39587157 的回复:] #include <stdio.h>  int a[5] = {1,2,3,4,5}; int b[5] = {9,8,7,6,5};  void copy_a(int *p) { p = a;//这个a都没定义，况且它是局部变量来的，与int a[5] = {1,2,3,4,5}; 中的a一点关系都没有 } int main() { copy_a(b); }   改为 #include <stdio.h>  int a[5] = {1,2,3,4,5}; int b[5] = {9,8,7,6,5};  void copy_a(int *p，int  *a)  { p = a; } int main() { copy_a(b,a); } 这样改一样不可以。 建议使用memcpy或者 void copy_a(int *p，int  *a， int size)  {     int i;     for (i = 0; i < size; i++)         p[i] = a[i]; } int main() { copy_a(b, a, 5); } [/quote]  还是不对 p[i] = a[i]; 这里只是改变指针p的指向，没有给main函数的b赋值 要改为*p[i] = *a[i];[/quote] 个人建议，理论应该和实践多做结合。对与不对，试了就知道了。

总的来说 要想改变主调函数中变量的值，必须传变量的地址，而且还得通过*+地址 去赋值。

引用 6 楼 cfjtaishan 的回复:[quote=引用 5 楼 weixin_39587157 的回复:] #include <stdio.h>  int a[5] = {1,2,3,4,5}; int b[5] = {9,8,7,6,5};  void copy_a(int *p) { p = a;//这个a都没定义，况且它是局部变量来的，与int a[5] = {1,2,3,4,5}; 中的a一点关系都没有 } int main() { copy_a(b); }   改为 #include <stdio.h>  int a[5] = {1,2,3,4,5}; int b[5] = {9,8,7,6,5};  void copy_a(int *p，int  *a)  { p = a; } int main() { copy_a(b,a); } 这样改一样不可以。 建议使用memcpy或者 void copy_a(int *p，int  *a， int size)  {     int i;     for (i = 0; i < size; i++)         p[i] = a[i]; } int main() { copy_a(b, a, 5); } [/quote]  还是不对 p[i] = a[i]; 这里只是改变指针p的指向，没有给main函数的b赋值 要改为*p[i] = *a[i];

http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素

引用 2 楼 松下三三的回复:p指向了a，b传进去，b没有指向a是吗？指针也存在值传递的情况吗  [quote=引用 1 楼 paschen 的回复:] p = a只是在赋值，让p指向a的内存，不是在拷贝，而且你形参p与实参b也不是同一个变量   如果你要拷贝，copy_a函数改成：memcpy(p, a, sizeof(a)); 引用 1 楼 paschen 的回复:p = a只是在赋值，让p指向a的内存，不是在拷贝，而且你形参p与实参b也不是同一个变量   如果你要拷贝，copy_a函数改成：memcpy(p, a, sizeof(a));[/quote] p是指向了a，但p和b是不是一个变量，你函数参数是按值传递的，也就是说参数只是复制的一个对象，你对他赋值了只会影响它自己，和b没什么关系

引用 2 楼 ZK880127 的回复:p指向了a，b传进去，b没有指向a是吗？指针也存在值传递的情况吗  [quote=引用 1 楼 paschen 的回复:] p = a只是在赋值，让p指向a的内存，不是在拷贝，而且你形参p与实参b也不是同一个变量     如果你要拷贝，copy_a函数改成：memcpy(p, a, sizeof(a)); 引用 1 楼 paschen 的回复:p = a只是在赋值，让p指向a的内存，不是在拷贝，而且你形参p与实参b也不是同一个变量   如果你要拷贝，copy_a函数改成：memcpy(p, a, sizeof(a));[/quote]  1.包括指针在内的传递实质上都是值传递，用指针作实参传递时传递的是指针的内容也即地址，再通过*pointer就能操作指针所指向的地址里的内容，在这个过程中也是生成一个指针副本，将实参值传递给副本 2.你的b是一个常量指针，你所希望的对b进行赋值的操作是错误的

p指向了a，b传进去，b没有指向a是吗？指针也存在值传递的情况吗  引用 1 楼 paschen 的回复:p = a只是在赋值，让p指向a的内存，不是在拷贝，而且你形参p与实参b也不是同一个变量   如果你要拷贝，copy_a函数改成：memcpy(p, a, sizeof(a)); 引用 1 楼 paschen 的回复:p = a只是在赋值，让p指向a的内存，不是在拷贝，而且你形参p与实参b也不是同一个变量   如果你要拷贝，copy_a函数改成：memcpy(p, a, sizeof(a));


Question: 我想计算五位数的位数，请问这代码哪里有错误，萌新~

学学 Java 源码中的思想：#include <stdio.h>  int getIntegerLength(int n) { 	int i = 0; 	int arr[] = { 0, 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999 }; 	while (n > arr[i]) { 			i++; 	} 	return i; }  int main() { 	printf("%d\n", getIntegerLength(1)); 	printf("%d\n", getIntegerLength(9)); 	printf("%d\n", getIntegerLength(11)); 	printf("%d\n", getIntegerLength(99)); 	printf("%d\n", getIntegerLength(111)); 	printf("%d\n", getIntegerLength(999)); 	return 0; }

#include<stdio.h> int main(){ 	int a,i; 	i =0; 	printf("Plese input \n"); 	scanf("%d",&a);  	for(;a!=0;i++){ 		a=a/10; 	}  	printf("%d",i);  	return 0;  }

编译器问题~~~~

k = a / 10; // 这里 a 永远不变

说错了 是去掉for语句中的i=i+1

引用 3 楼 qq_34851925 的回复:嗯嗯好像是这么一回事2L，我是想输入一个五位以下的数字，然后计算出它到底是几位。该怎么改 你只需要去掉if语句中的i=i+1 有什么问题继续问 我会回答你

//六位以下数有几位 int main() {     int a,t=0,k;     scanf("%d",&a);     if(a>99999)printf("error!\n");     else{     for(k=a;k>0;k/=10)t++;         printf("%d\n",t);}     return 0; }

现在C/C++中的int变量支持超过 32767以上的数字了？

调用这个函数试试！ int get_num_bits(int num) { 	int i=0; 	if (num>99999) 	{ 		printf("the number >99999, is worng!\n"); 		return 0; 	} 	while(num) 	{ 		num=num/10; 		i++; 	} 	return i; }

for (A;B;C) D; //等价于 {  A;  while (1) {   if (!(B)) break;   D;   C;  } }

先搞清楚for循环是怎么用的

引用 3 楼 qq_34851925 的回复:嗯嗯好像是这么一回事2L，我是想输入一个五位以下的数字，然后计算出它到底是几位。该怎么改 #include <stdio.h>  int main(void) {     int a, cnt = 0;      scanf("%d", &a);      while (a) {         a /= 10;         cnt++;     }      printf("cnt = %d\n", cnt);     return 0; } 参考一下吧 你用for循环也是可以的。既然知道是多了i = i + 1;为啥不去掉再试试呢。

for循环里已经有i = i + 1;为什么在循环体里也有i = i + 1; 楼主的问题是不是计算的位数不对，变大了。应该是i自增了两次。

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。


Question: 这是否是C语言自身的问题？

#include <stdio.h> main() { float a,b,c; int i1,i2; a=0.1; c=0.000000; scanf("%f",&b); for(i1=0;i1<7;i1++) { for(i2=0;i2<10;i2++) { if(b>=a)    b-=a;    //你输入b=0.25 经过两次减0.1 还剩b=0.05 ,后面b肯定不为0 } if(b==c)    //这个条件就不成立  printf("****\n"); if(c==0) printf("&&&&\n"); a/=10; printf("--------\n"); printf("b=%f\n",b); printf("\n"); printf("a=%f\n",a); printf("--------\n"); } }

明白了，多谢各位的解答

注意浮点数与0的比较

if (fabs(b) <= 1e-6)   //单精度判断是否为0 if (fabs(b) <= 1e-15) //双精度判断是否为0

if(b==c) printf("****\n"); 你下面的代码里，是b == c不是b == 0; 这是一个问题。 第二个问题，也是主要问题，浮点数判断是否等于0，不是直接和0比较。而是 if (fabs(b) < 1e-6) //表示b等于0，针对单精度 详细信息请查阅这个博客： https://blog.csdn.net/gogokongyin/article/details/51105745


Question: 关于链表的题

对比一下找不同的地方，分析一下；

数据结构对单链表进行数据排序 http://bbs.csdn.net/topics/392201633

引用 1楼自信男孩 的回复:#include<stdio.h> #include<stdlib.h>  struct node {     int data;     struct node *next; };  int main() {     int n,m,x,y,i,j;     scanf("%d %d",&m,&n);     struct node *head1,*head2,*q,*p,*t,*q1,*q2,*k;     head1=(struct node*)malloc(sizeof(struct node));     head1->next=NULL;     head2=(struct node*)malloc(sizeof(struct node));     head2->next=NULL;     q1 = head1;     q2 = head2;     for(i=1; i<=m; i++)     {         p = (struct node*)malloc(sizeof(struct node));         scanf("%d",&p->data);         p->next = NULL;         q1->next = p;         q1 = p;     }     for(i = 1; i<=n; i++)     {         p=(struct node*)malloc(sizeof(struct node));;         scanf("%d",&p->data);         p->next=NULL;         q2->next = p;         q2 = p;     }     q1 = head1->next;     q2 = head2->next;     t = head1;      while (q1 && q2) {         if (q1->data < q2->data) {             t->next = q1;             t = q1;             q1 = q1->next;         } else {             t->next = q2;             t = q2;             q2 = q2->next;         }     }     t->next = q1 ? q1 : q2;      p = head1->next;     while(p)     {         printf("%d ",p->data);         p = p->next;     }     /*     p = head2->next;     while(p)     {         k=p;         t=head1->next;         q=head1;         while(t)         {             if(k->data<t->data)             {                 k->next=t;                 q->next=k;                 break;             }             t=t->next;             q=q->next;         }         if(t==NULL)         {             k->next=NULL;             q->next=k;         }         p=p->next;     }     p=head1->next;     while(p)     {         if(p->next==NULL)             printf("%d\n",p->data);         else             printf("%d ",p->data);         p=p->next;     }     */     return 0; }   参考一下吧  合并和输出可以对比参考一下；我的那为啥不对


Question: uva332 Rational Numbers from Repeating Fractions尝试了十次一直WA，麻烦各位帮我看一下哪里遗漏，谢谢

引用 2 楼 cfjtaishan 的回复:需求描述的不明确，代码阅读起来不易懂。 有测试用例吗？贴出来

需求描述的不明确，代码阅读起来不易懂。

建议看下 提问的艺术

引用 6楼自信男孩 的回复:[quote=引用 5 楼 pan5690983 的回复:] Line15   scanf("%s", dec);  是不是少了一个取地址符号--->  scanf("%s", &dec); dec好像是数组名，数组名本身就是首地址。还需要加&？[/quote]啊啊 那应该是不用我的锅

引用 5 楼 pan5690983 的回复:Line15   scanf("%s", dec);  是不是少了一个取地址符号--->  scanf("%s", &dec); dec好像是数组名，数组名本身就是首地址。还需要加&？

百度搜相关关键字。


Question: 就几行程序而已，为什么输出不对！！！

经过最近的搜索，问题的本质还是存储变量的区域不同，p[]是存在栈里的（包括p[]里面的内容），用完就释放，所以打印一定出错，但是如果把p[]换成*P（p存在栈）那么p所指的内容存放在常量区，用完不释放存放在常量区的内容，所以在打印后不会出错，希望对后来者有帮助！！！！

如果定义为 char *p    则 hello wored 是常量字符串 它储存在常量储存区，指针p指向该区域的地址，但是如果定义为 char p[] 则是定义了一个数组变量，这个数组变量是局部变量，函数调用结束就会注销这部分占用内存，  return就出错了

char p[] 改为const char []

p是栈上的数组，函数结束后，栈释放，对于"hello world"来说. hello在栈顶，world是栈底，然后估计调用printf的时候，因为要传参压栈，把world这块给覆盖掉了，hello因为远而没有受到影响。 至于p如果是char*的话，那么此时p的值是指向数据区的一个指针，虽然说p本身被覆盖掉了，但是p的值是通过GetMemory返回的，因此str仍是指向数据区“hello world”的，所以肯定可以输出完整的 “hello world”

引用 7 楼 zhao4zhong1 的回复:其实电脑开机后物理内存的每个字节中都有值且都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。 C99已不支持void main

可以复习一下函数的副本机制，GetMemory函数最好传递一个地址进去，可以直接char *p=“helloworld”；

栈中的变量通常包括函数参数和函数里声明的临时变量。 栈中的基本变量退出其作用域时，没有谁执行一段代码去释放/销毁/析构它所占用的内存，仅仅是没人再去理会的留在当前栈顶上方的若干遗留下来可被后续压栈操作覆盖的无用数据而已。 而栈中的类变量退出其作用域时，会自动执行其析构函数，……

这是返回局部变量地址的问题，p数组是在函数getMemory栈上申请的，它的生命周期是函数调用开始，函数调用结束，则生命周期也随之结束。结束时，p的空间就会被释放，在Test函数里使用已经被释放的内存空间得到的结果是未定义的。  这是一类经典问题了。

一句话，传指针的指针

因为p是数组名，而不是指针

p是在栈上申请的内存，是一个局部变量，作用域在函数内。如果需要返回 ，可用malloc申请堆上的内存。堆上的内存需要手动释放。 内存中依然有数据，但是计算机已经认为是无效数据（内存没有被占用），可以随时被重新申请。乱码是最轻的，严重直接崩溃。 还有残留数据是因为C在释放内存时，只释放标志位，没必要把内存所有数据重新赋值。

引用 11 楼 jiht594 的回复:[quote=引用 6 楼 qq_26602805 的回复:] [quote=引用 1 楼 earbao 的回复:] 有的，局部变量返回后会给自动释放，指针不会。 您好，我还是不太明白，这里的释放是不是这个意思：本来是要返回p，但是在没有赋值给str前，由于p被释放了，所以str赋值的是未知的，如果是未知的那为什么还能打印出hell[/quote]  未知的意思就是打出什么都有可能。即便打出的和你想要的一样也不行，狗屎运而已。知道局部变量这样用不对就行了。[/quote]  那里的内存已经不是你的了，至于什么时候被清空或者被覆盖不是你能控制的。

printf(str);没有这个用法吧！  改为printf("%s\n",str);可以正常打印 char p[]与char *p没什么区别

引用 6 楼 qq_26602805 的回复:[quote=引用 1 楼 earbao 的回复:] 有的，局部变量返回后会给自动释放，指针不会。 您好，我还是不太明白，这里的释放是不是这个意思：本来是要返回p，但是在没有赋值给str前，由于p被释放了，所以str赋值的是未知的，如果是未知的那为什么还能打印出hell[/quote]  未知的意思就是打出什么都有可能。即便打出的和你想要的一样也不行，狗屎运而已。知道局部变量这样用不对就行了。

有的，局部变量返回后会给自动释放，指针不会。

引用 1 楼 earbao 的回复:有的，局部变量返回后会给自动释放，指针不会。[/quo  [quote=引用 3 楼 paschen 的回复:] 你GetMemory函数里的p是一个局部数组变量，该函数结束后就销毁了，所以出现未定义行为，你可以写成char*p=.....，因为这样p指向的是常量区的字符串，函数结束后，该内存仍然有效 请问，那出现未定义为什么还能打印出hell

引用 1 楼 earbao 的回复:有的，局部变量返回后会给自动释放，指针不会。 您好，我还是不太明白，这里的释放是不是这个意思：本来是要返回p，但是在没有赋值给str前，由于p被释放了，所以str赋值的是未知的，如果是未知的那为什么还能打印出hell

char p[] = "hello world";                 return p;   问题处在这两句话上， 第一句话里面的数组名p和“指向数组首元素地址的指针”不等效。 所以你声明并且初始化了一个平凡无奇的数组，只不过恰好数组元素是字符型的，可以用c-string来初始化。  第二句中数组名p和“指向数组首元素地址的指针”等效，可以互换。 于是乎，返回了一个栈变量的地址出去了。


Question: 想的脑阔痛，求大佬解决赋值问题！

引用 8 楼 AlbertS的回复:整理了一下你的代码：需要注意的就是整数和char之间不能使用strcpy来复制  #include<stdio.h> #include<string.h>  #define MAX_CHANGDU 5 #define MAX_MINGZI 64  int main() {  	int i,j; 	int ia,ib; 	char tempName[MAX_MINGZI] = {0}; 	char name[MAX_CHANGDU][MAX_MINGZI]={"张三","李四","王五","老大","老二"}; 	int score[MAX_CHANGDU]={75,85,55,65,95}; 	printf("排序前：\t"); 	for(i = 0; i < MAX_CHANGDU; i++) 	{ 		printf("%s,%d\t",name[i],score[i]); 	} 	printf("\n");   	for(i = 0; i < MAX_CHANGDU -1; i++) 	{ 		ia = score[i]; 		ib = i; 		for(j = i + 1; j < MAX_CHANGDU; j++) 		{ 			if(score[j] < ia) 			{ 				ia = score[j]; 				ib = j; 			} 		}  		// 将较小的分数和名字交换到前面 		if (i != ib) 		{ 			//先将需要交换的ib位置（也就是最小值位置）的内容放到临时变量里，其中分数已经做过了，不需要再赋值 			//ia = score[ib]; 			strcpy(tempName, name[ib]);  			//然后将i位置的内容更新到ib位置 			score[ib] = score[i]; 			strcpy(name[ib],name[i]);  			//再将临时变量中的内容更新会i位置 			score[i] = ia; 			strcpy(name[i], tempName);   			// 至此完成了i位置的分数、名字与ib位置的分数名字交换 		} 		//strcpy(name[i],ia); // 整数和char之间不能使用strcpy 	} 	printf("排序后：\t"); 	for(i = 0; i < MAX_CHANGDU; i++) 	{ 		printf("%s,%d\t",name[i],score[i]); 	} 	return 0; }   运行结果： 排序前：        张三,75 李四,85 王五,55 老大,65 老二,95 排序后：        王五,55 老大,65 张三,75 李四,85 老二,95 大佬，能简单讲讲思路吗，看不懂

memcpy可以拷贝连续内存的数据，这个应该可以

strcpy(name[i],ia);明显错了，int数据直接赋值好了

作为一个C程序员，对  scanf,sscanf,fscanf  printf,sprintf,fprintf 这类函数的用法，还是要做到“拳不离手，曲不离口”的。

#include<stdio.h> #include<string.h>  int main() { #define MAX_CHANGDU 5 #define MAX_MINGZI 64     int i,j;     int imin, tmp;     char str[MAX_MINGZI];     char name[MAX_CHANGDU][MAX_MINGZI]={"张三","李四","王五","老大","老二"};     int score[MAX_CHANGDU]={75,85,55,65,95};     printf("排序前：\t");     for(i=0;i<MAX_CHANGDU;i++)     {         printf("%s: %d\t",name[i],score[i]);     }     printf("\n");     for (i = 0; i < MAX_CHANGDU; i++) {         imin = i;         for (j = i + 1; j < MAX_CHANGDU; j++)             if (score[imin] > score[j])                 imin = j;         if (imin != i) {             tmp = score[imin];             score[imin] = score[i];             score[i] = tmp;             strcpy(str, name[imin]);             strcpy(name[imin], name[i]);             strcpy(name[i], str);         }     }  #if 0      for(i=0;i<MAX_CHANGDU;i++)     {         ia=score[i];         ib=i;         for(j=i+1;j<MAX_CHANGDU;j++)         {             if(score[j]<ia)             {                 ia=score[j];                 ib=j;             }         }         score[ib]=score[i];         score[i]=ia;          strcpy(name[ib],name[i]);         strcpy(name[i],ia);     } #endif     printf("排序后：\t");     for(i=0;i<MAX_CHANGDU;i++)     {         printf("%s: %d\t", name[i], score[i]);     }     putchar(10);     return 0; } 参考一下吧  楼主的问题在strcpy上，strcpy(name[i],ia);ia是int类型，不能用strcpy。

#include <windows.h> #include<string.h> #include<stdio.h>  #define MAX_NAME_NUM 5		// 最大名字数量 #define MAX_NAME_LEN 64		// 最大名字长度   void main() { 	char strName[MAX_NAME_NUM][MAX_NAME_LEN] = {"张三","李四","王五","老大","老二"};	// 名字 	int nIndex[MAX_NAME_NUM] = {0, 1, 2 , 3, 4};										// 分数所对应名字的位置 	int nScore[MAX_NAME_NUM] = {75,85,55,65,95};										// 分数 	int i,j, nTmp;             printf("排序前:\t"); 	for(i=0; i<MAX_NAME_NUM; i++) 	{ 		printf("%s,%d	", strName[i], nScore[i]); 	} 	printf("\n");     	// 冒泡排序 	for(i=0; i<MAX_NAME_NUM-1; i++) 	{ 		for(j=1; j<MAX_NAME_NUM-i; j++) 		{ 			if(nScore[j-1]>nScore[j]) 			{ 				nTmp=nScore[j]; 				nScore[j] = nScore[j-1]; 				nScore[j-1] = nTmp;  				nTmp=nIndex[j]; 				nIndex[j] = nIndex[j-1]; 				nIndex[j-1] = nTmp; 			} 		} 	} 	     printf("排序后:\t"); 	for(i=0; i<MAX_NAME_NUM; i++) 	{ 		printf("%s,%d	", strName[nIndex[i]], nScore[i]); 	} 	printf("\n"); 	system("pause"); }

但是没想到其他解决办法

strcpy(name[i],ia);不对，strcpy用于拷贝字符串


Question: C语言统计一个英文文本文件中26个英文字母出现次数并按英文字母序输出统计结果

#include "stdio.h" int main( void ) { 	FILE *p = fopen("1.txt","r"); 	int c=0,i=0; 	int ch[256]={0}; 	while( (c=fgetc(p)) != EOF) 		ch[c]++;				//256种字节值都记录下来  	fclose(p); 	 	for( i=0 ; i<256 ; i++ )	//遍历256种字节值的个数  		if( (i>='A'&&i<='Z') || (i>='a'&&i<='z') )	//是字母就输出  			printf("%c:%d\n", i, ch[i] ); 	return 0; }  没有运行验证，不过应该是没问题的

letter不知道吧，怎么if的呀

为什么我根本打不开文件

用hash映射就不会出现这个问题了吧

str[i+1]=str[i]+1; 这一句会越界吧

#include<stdio.h>  void hello(char one, FILE*fp ) {     char letter;     int num=0, ret;     while(!feof(fp)){         if(letter==one)             num++; #if 0         fscanf(fp, "%c", &letter); #else         ret = fscanf(fp, "%c", &letter);         if (ret == EOF)             break; #endif     }     printf("%c:%d  ", one, num);      return ; }  int main() {     FILE *fp;     if((fp=fopen("english.txt", "r"))==NULL){         printf("Cannot open the file!\n");         //exit(0);         return -1;     }      char str[26];     int i=0;     str[0]='a';      for (i=0; i<26; i++){         //str[i+1]=str[i]+1;         str[i] = 'a' + i;         // printf("str[%d]=%c ", i, str[i]);         hello(str[i], fp);         rewind(fp);     }     fclose(fp);      return 0; }  参考一下吧   str[i+1]=str[i]+1; 这条语句str越界，因为当i为25时，str[i+1]下表就是26，因为str[26]的下表是从0~25. 由于feof本身在判断文件末尾时会有一些小问题，建议从网上查一下feof，建议使用： ret = fscanf(fp, "%c", &letter);         if (ret == EOF)             break;

说一下个人使用DEVC++的经历，以前使用DEVC++调试，特别是打断点，走到断点处总是出现各种奇怪的问题，但是去掉断点一次行跑到system("pause")就没问题。DEVC++已经不更新了，建议使用Codeblocks，vc/vs

我用的是DEVC++

你用的什么编译器，我在VC6.0下正常，没有错误。


Question: 指针数组的请教

第一次： s[0]字符串"ABCD"的首地址 strlen(s[1])=2 所以是打印："ABCD"向右偏移1位后的整个字符串——BCD  第二次： s[2]字符串"EFGH"的首地址 strlen(s[1])=1（因为第一次里，向右偏移一位了） 所以是打印："EFGH"向右偏移0位后的整个字符串——EFGH

s[1]类型为char*，是地址++，而不是数字12+1，是s[1]++后是"2",strlen(s[1]) = 1

错了 因为s[1]++以后 strlen(s[1]) = 1

我的理解是 第一行输出 s[0]+2-1 即 s[0]+1   这得到BCD 然以后 s[1]++ 得到 s[1]=13?  i+=2 得到 i=2. 接着循环s[2]+2-1 即S[2]+1 不是也是FGH吗？ 我哪里理解错了吗

#include <stdio.h> #include <string.h> struct stud{    char name[10];    int  score[2];  } *p; main () {    char *s[4] = { "ABCD", "12", "EFGH", "34" };    int i = 0 ;    struct stud t[4]= {{"Lisa",98,97}，{"Tom",89,86}，                       {"John",68,79}，{"Lili",94,90}};     while( *s[1] != '\0' ){ 	        printf("%s\n", s[i]+strlen(s[1])-1); 	        s[1]++; 			i +=2;	 	}     p=t+2; 	printf("%s, %d\n ",t[0].name,t[0].name,t[0].score[0]+t[0].score[1]); 	printf("%s, %d\n ",p->name,p->score[0] + p->score[1]); } 被吞图了，看代码也可以，输出的第一行和第二行为什么是BCD 和 EFGH 啊

百度搜相关关键字。


Question: 可变参数的问题

好像c不支持这种特性,你需要自己解析 传递一个可变参数,然后用va list va_arg 来获得每个参数在进行下次传递.

va_arg, va_end, va_start Access variable-argument lists.  type va_arg( va_list arg_ptr, type );  void va_end( va_list arg_ptr );  void va_start( va_list arg_ptr );   (UNIX version)  void va_start( va_list arg_ptr, prev_param );   (ANSI version)  Routine Required Header Optional Headers Compatibility  va_arg <stdio.h> and <stdarg.h> <varargs.h>1 ANSI, Win 95, Win NT  va_end <stdio.h> and <stdarg.h> <varargs.h>1 ANSI, Win 95, Win NT  va_start <stdio.h> and <stdarg.h> <varargs.h>1 ANSI, Win 95, Win NT    1 Required for UNIX V compatibility.  For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  va_arg returns the current argument; va_start and va_end do not return values.  Parameters  type  Type of argument to be retrieved  arg_ptr  Pointer to list of arguments  prev_param  Parameter preceding first optional argument (ANSI only)  Remarks  The va_arg, va_end, and va_start macros provide a portable way to access the arguments to a function when the function takes a variable number of arguments. Two versions of the macros are available: The macros defined in STDARG.H conform to the ANSI C standard, and the macros defined in VARARGS.H are compatible with the UNIX System V definition. The macros are:  va_alist  Name of parameter to called function (UNIX version only)  va_arg  Macro to retrieve current argument  va_dcl  Declaration of va_alist (UNIX version only)  va_end  Macro to reset arg_ptr  va_list  typedef for pointer to list of arguments defined in STDIO.H  va_start  Macro to set arg_ptr to beginning of list of optional arguments (UNIX version only)  Both versions of the macros assume that the function takes a fixed number of required arguments, followed by a variable number of optional arguments. The required arguments are declared as ordinary parameters to the function and can be accessed through the parameter names. The optional arguments are accessed through the macros in STDARG.H or VARARGS.H, which set a pointer to the first optional argument in the argument list, retrieve arguments from the list, and reset the pointer when argument processing is completed.  The ANSI C standard macros, defined in STDARG.H, are used as follows:   All required arguments to the function are declared as parameters in the usual way. va_dcl is not used with the STDARG.H macros.   va_start sets arg_ptr to the first optional argument in the list of arguments passed to the function. The argument arg_ptr must have va_list type. The argument prev_param is the name of the required parameter immediately preceding the first optional argument in the argument list. If prev_param is declared with the register storage class, the macro’s behavior is undefined. va_start must be used before va_arg is used for the first time.   va_arg retrieves a value of type from the location given by arg_ptr and increments arg_ptr to point to the next argument in the list, using the size of type to determine where the next argument starts. va_arg can be used any number of times within the function to retrieve arguments from the list.   After all arguments have been retrieved, va_end resets the pointer to NULL.  The UNIX System V macros, defined in VARARGS.H, operate somewhat differently:   Any required arguments to the function can be declared as parameters in the usual way.   The last (or only) parameter to the function represents the list of optional arguments. This parameter must be named va_alist (not to be confused with va_list, which is defined as the type of va_alist).   va_dcl appears after the function definition and before the opening left brace of the function. This macro is defined as a complete declaration of the va_alist parameter, including the terminating semicolon; therefore, no semicolon should follow va_dcl.   Within the function, va_start sets arg_ptr to the beginning of the list of optional arguments passed to the function. va_start must be used before va_arg is used for the first time. The argument arg_ptr must have va_list type.   va_arg retrieves a value of type from the location given by arg_ptr and increments arg_ptr to point to the next argument in the list, using the size of type to determine where the next argument starts. va_arg can be used any number of times within the function to retrieve the arguments from the list.   After all arguments have been retrieved, va_end resets the pointer to NULL.  Example  /* VA.C: The program below illustrates passing a variable  * number of arguments using the following macros:  *      va_start            va_arg              va_end  *      va_list             va_dcl (UNIX only)  */  #include <stdio.h> #define ANSI            /* Comment out for UNIX version     */ #ifdef ANSI             /* ANSI compatible version          */ #include <stdarg.h> int average( int first, ... ); #else                   /* UNIX compatible version          */ #include <varargs.h> int average( va_list ); #endif  void main( void ) {    /* Call with 3 integers (-1 is used as terminator). */    printf( "Average is: %d\n", average( 2, 3, 4, -1 ) );     /* Call with 4 integers. */    printf( "Average is: %d\n", average( 5, 7, 9, 11, -1 ) );     /* Call with just -1 terminator. */    printf( "Average is: %d\n", average( -1 ) ); }  /* Returns the average of a variable list of integers. */ #ifdef ANSI             /* ANSI compatible version    */ int average( int first, ... ) {    int count = 0, sum = 0, i = first;    va_list marker;     va_start( marker, first );     /* Initialize variable arguments. */    while( i != -1 )    {       sum += i;       count++;       i = va_arg( marker, int);    }    va_end( marker );              /* Reset variable arguments.      */    return( sum ? (sum / count) : 0 ); } #else       /* UNIX compatible version must use old-style definition.  */ int average( va_alist ) va_dcl {    int i, count, sum;    va_list marker;     va_start( marker );            /* Initialize variable arguments. */    for( sum = count = 0; (i = va_arg( marker, int)) != -1; count++ )       sum += i;    va_end( marker );              /* Reset variable arguments.      */    return( sum ? (sum / count) : 0 ); } #endif   Output  Average is: 3 Average is: 8 Average is: 0   Argument Access Routines  See Also   vfprintf

这种情况下要用宏才行

所有的 int func(void const *param, ...); 函数都是最终函数，该函数调用 int vfunc(void const *param, va_list argptr); 函数。 不要在变参数函数中调用变参数函数，而是呼叫 va_list 参数的函数。

百度搜相关关键字。


Question: 指针问题，求大佬帮助！！~

百度搜 “C 指针传参”


Question: C语言链表问题

引用 4 楼 zhao4zhong1 的回复:[quote=引用 2 楼 hefashion0190 的回复:] 可以参考下wiki中链表的示例 https://zh.wikipedia.org/wiki/%E9%93%BE%E8%A1%A8 对比#1和#2，我觉得wiki上的图不如我的图讲得更清楚。[/quote]

函数参数应尽量少，看到楼主的传入参数并没有带入到函数内数值，而是把参数当做内部普通局部变量使用，这样倒不如去掉该参数，改成在函数内定义局部变量。 参数的增加会导致程序的运行效率降低，如果是初学者可以暂不考虑这个问题导致的效率降低。

#include<stdio.h> #include<stdlib.h> #include<malloc.h>  typedef struct LNode {     int data;     struct LNode *next; } LNode,*Linklist;  void Creatlist(Linklist head,int n); void Traverselist(Linklist head); void del(Linklist head,int j); void rev(Linklist head,int n); void search(Linklist head,int i); void Insert(Linklist head,int i,int e);  int main() {     int n,i,e,j;     Linklist head;     head=(Linklist)malloc(sizeof(LNode));     if(head==NULL)         exit(1);     Creatlist(head,n);     printf("遍历链表，输出链表:\n");     Traverselist(head);      search(head,i);     Insert(head,i,e);     printf("插入后的链表为:\n");     Traverselist(head);     del(head,j);     printf("删除后的链表为:\n");     Traverselist(head);     rev(head,n);     printf("逆序后的链表为:\n");     Traverselist(head);     getchar();     return 0; } void Creatlist(Linklist head,int n) {     int i;     head->next=NULL;     Linklist p,q;     q = head;     /*  多余的一个节点     p = (Linklist)malloc(sizeof(LNode));     if(p==NULL)         exit(1);     */     printf("请输入结点个数n的值:");     scanf("%d",&n);     printf("请输入各个结点的值:");     for(i=0;i<n;i++)     {         p=(Linklist)malloc(sizeof(LNode));         scanf("%d", &p->data);         p->next=NULL;         q->next = p;         q = p;     } } void Traverselist(Linklist head) {     Linklist p;     p=head->next;     while(p!=NULL)     {         printf("%3d",p->data);         p = p->next;     } } void search(Linklist head,int i) {     printf("\n请输入查找第i个结点的i的值:");     scanf("%d",&i);     Linklist p;     p = head;     int j=1;     while((p->next)&&(j<=i))     {         p=p->next;         j++;     }     if (!p->next) {         printf("Can't find it!\n");         return;     }     printf("%d",p->data); } void Insert(Linklist head,int i,int e) {     printf("\n在第i个结点前插入一个整数e,请分别输入i和e的值:");     scanf("%d%d", &i, &e);     Linklist p,q;     p = head;     int j = 1;     while((p->next)&&(j<i))     {         p = p->next;         j++;     }     if (!p->next && j < i) {         printf("插入位置错误");         return;     }      q = (Linklist)malloc(sizeof(LNode));     q->data = e;     q->next = p->next;     p->next = q; } void del(Linklist head,int j) {     Linklist p,q;     p=head;     int i=1;     printf("\n请输入要删除的第j个元素的值:");     scanf("%d", &j);     while((p->next)&&(i<j))     {         p = p->next;         i++;     }     if (!p->next && i < j) {         printf("删除位置不合理");         return;     }     q = p->next;     p->next = q->next;     free(q); } /*void del(Linklist head)   {   int j,i=0;   printf("\n输入j的值:\n");   scanf("%d",&j);   Linklist p,q;   p=head;   q=head;   for(i=1;i<=j;i++)   p=p->next;   if(p==NULL)   exit(0);   for(i=1;i<j;i++)   q=q->next;   q->next=p->next;   p->next=NULL;   free(p);   printf("当前序列为:\n");   q=head->next;   while(q)   {   printf("%d\t",q->data);   q=q->next;   }   printf("\n");   }*/ void rev(Linklist head,int n) {     Linklist p, q, r;      if(head==NULL)         return; #if 1     q = head;     p = head->next;     head->next = NULL;      while (p) {         r = p->next;         p->next = q->next;         q->next = p;         p = r;     } #else     p = head->next;     q = p->next; //q为p下一个节点     while(q)     {         r=q->next; //r为q下一个节点         q->next=p; //指针回指         p=q;         q=r;          //p, q后移    *关键是对指针间赋值的理解*     }     //head->next=p; #endif }  参考一下吧  多个功能有多处错误； 添加链表，搜索，插入和删除都有一些逻辑问题。 逆序存在死循环的问题。问题都一一修改了，建议对比一下代码找一下自己的原因。

引用 2 楼 hefashion0190 的回复:可以参考下wiki中链表的示例 https://zh.wikipedia.org/wiki/%E9%93%BE%E8%A1%A8 对比#1和#2，我觉得wiki上的图不如我的图讲得更清楚。

数据结构对单链表进行数据排序 http://bbs.csdn.net/topics/392201633


Question: oj上的光棍题，不知道怎么处理数据的问题，求指正啊！！

谢谢啊，ac了···

#include<stdio.h> #include <stdlib.h>  int main() {     int n,i;     char *bachelor;     while(scanf("%d", &n)!=EOF)     {         if(n == 0)             break;         bachelor = (char *)malloc(sizeof(char) * (n +1));         if (!bachelor)             exit(0);          for (i = 0; i < n; i++)             bachelor[i] = '1';         bachelor[i] = 0;    /* '\0' */         printf("%s\n", bachelor);         free(bachelor);     }      return 0; }   参考一下吧； 理论上输入n位10000都没问题。


Question: C程序运行后按Ctrl+z后再按Enter退不出循环是为什么

Linux：Ctrl+D Windows：Enter、Ctrl+Z、Enter

引用 1 楼 自信男孩的回复:Linux下输入ctrl+d，windows输入ctrl+z输入EOF  在Linux下测试，都能正常退出while循环； 第一个程序退出循环后打印100个数值。 我是在windows下输入了ctrl+z，然后按下回车    结果只出现换行，并没有输出任何其他内容啊，这是为什么啊


Question: 在一个固定长度的数组中对字符串进行增删改查

储存长度为变长，并且lz想要获取数组实际长度的话，首先建议用指针，malloc动态分配内存； 其次，统计每个出现次数，只能想到比较笨的遍历方法

百度搜相关关键字。


Question: 传递参数类型怎么传递

就是传递的类型....

#define create_buffer(...) _create_buffer(#__VA_ARGS__) void* _create_buffer(const char* s_typename) { 	return NULL; }

参数是值传递的，没听说过可以传类型进去的。你确定是funa可以传类型？还是类型代表的某个值


Question: c数据结构强制转换,这怎么转

转成什么？union？

直接就像你写这样就可以：(straa)st_ab    或者return  *(straa*)&st_ab;

straa func() {     strbb st_ab;     return (straa)st_ab; } 根据aa，bb的数据结构来看，可以直接强制类型转换。 转换之后就可以按照aa来用。

如果是c++ ，可以自定义转换函数， 纯C话，如果二者内存布局一致，可以用memcpy 或者自己一个一个字段赋值


Question: 嵌入式C语言程序运行效率？

贴点代码学习一下。

去看看指令的执行周期就可以了。 IO 的指令周期相对比较长。

无profiler不要谈效率！！尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！

这种情况，提高循环的执行效率就是不去做无用的工作，既然点评没有改变，则不去设置。 估计不是设置寄存器浪费时间，而是重复（大量的重复）做设置寄存器导致的耗时多。循环次数增加本身就会增加时间复杂度。


Question: c语言程序错误求大神改错

怎么没有初始化

for (;j>i-1;j--)         L->data[j+1]=L->data[j]; insert函数里，这儿应该是for，而不是if  void find(sequenlist *L,int n) 这儿是定义，但是声明时却是一个参数，定义时是2个参数；  for(;j<L->length;j++)          printf("%d",L->data[j]);  去掉for循环中第一个表达式j，这儿没有意义；


Question: 折半法查找为什么反回的总是-1,多谢

low=sz[0]; high=sz[n-1]; low和high应该都是下表而不是下表对应的值。因此，应改成：  low = 0; high = n-1;

没找到不就是-1嘛

low=sz[0]; high=sz[n-1];   这块代码写错了，low=0;high=n-1;  还有数组大小和查找的值最好作为参数传进来。


Question: 各位大神，帮我调试一下这段程序，出现错误，帮忙指正并改动一下代码，多谢了

都是一些基本的语法问题，建议楼主细心一些。 另外，函数名定义，不要用拼音。如果英语能力欠缺建议好好补一补，写这样的代码不但阅读起来会比较有难度，而且别人别人也不应定用，自己平时写代码时尽量克服拼音。  折半查找binary_search， 输出：print, show，输入input， enter等等仅供参考

if (mid=n)         {             return mid;         } 改成：  if (mid==n)         {             return mid;         } 注意是判断语句而不是赋值语句；  //sz[i]=term;                 term = sz[i];                 sz[i]=sz[j];                 sz[j]=term; 注意数据交换的顺序：现将sz[i]赋值给term，而不是term赋值给sz[i];再说term是随机值，把随机值赋值给sz[i]没意义。  int main() {     int sz[N];     shuruchengji(sz);     shuchushunxuchengji(sz);     zhebanfachazhao(sz); } 函数调用，参数的传入规则如上。

shuruchengji(sz[N]);需改为shuruchengji(sz); sz[N]表示一个int

总是出现这个错误 cannot convert parameter 1 from 'int' to 'int []'

关于自己是否适合编程的很简单的测试： 在报纸或杂志上随便找一段约1000字的文章，在Word中输入一遍。输完后再参考下面答案：  A里面有10处以上文字或标点错误 B里面没有文字或标点错误并敢为此跟人打赌 C里面没有文字或标点错误并且字体和排版完全与原稿一致 D打印在半透明的纸上和原稿重叠在一起检查一模一样，且自我感觉很有成就感  A不适合编程（理由：打字准确度偏低、粗心大意） B初级程序员（理由：打字准确度很高、认真细致、自信、理解全角半角概念） C高级程序员（理由：在B的基础上理解字体和排版也是电脑打印的重要因素、但相比D还不够偏执、精益求精、结果可验证） D软件项目经理（理由：能针对项目给出令人信服的细致到极点的需求说明和典型测试用例。用户几乎挑不出毛病。专业！）  如果想从A变成B的话，到我的资源http://download.csdn.net/detail/zhao4zhong1/4084259里面下载“适合程序员的键盘练习”


Question: 求助，使用OLE剪切板时IDataObject的问题

百度搜相关关键字。

顶一下，求指导


Question: 如何实现一元稀疏多项式乘法

真的写得好。

仅供参考：//链表实现一元多项式的加法减法乘法 #include <stdio.h> #include <stdlib.h> typedef struct node {     float coef;   //系数     int expn;     //指数     struct node *next; } PolyNode;      //多项式节点 polynomial node typedef PolyNode* Polynomial; Polynomial createPolynomial() {  //创建多项式     PolyNode *p, *q, *head = (PolyNode *)malloc(sizeof(PolyNode));   //头节点     head->next = NULL;     float coef;     int expn;     printf("输入该多项式每一项的系数和指数，每项一行，输入0 0结束！\n");     while (scanf("%f %d", &coef, &expn) && coef) {   // 默认，按指数递减排列         if (head->next) {             p = head;             while (p->next && expn < p->next->expn)                 p = p->next;             if (p->next) {                 if (expn == p->next->expn) { //有相同指数的直接把系数加到原多项式                     p->next->coef += coef;                     if (p->next->coef > -0.000001 && p->next->coef < 0.000001) { //若是相加后系数为0，则舍弃该节点                         q = p->next;                         p->next = q->next;                         free(q);                     }                 } else {                     q = (PolyNode*)malloc(sizeof(PolyNode));                     q->coef = coef;                     q->expn = expn;                     q->next = p->next;                     p->next = q;                 }             } else {                 p->next = (PolyNode*)malloc(sizeof(PolyNode));                 p = p->next;                 p->coef = coef;                 p->expn = expn;                 p->next = NULL;             }         } else {             head->next = (PolyNode*)malloc(sizeof(PolyNode));             head->next->coef = coef;             head->next->expn = expn;             head->next->next = NULL;         }     }     return head; } Polynomial multiply(Polynomial poly, float coef, int expn) {  //多项式与指定单项式相乘，该单项式为 coefx^expn     PolyNode *p, *q, *Poly = (PolyNode*)malloc(sizeof(PolyNode));     p = Poly;     q = poly->next;     while (q) {         p->next = (PolyNode*)malloc(sizeof(PolyNode));         p = p->next;         p->coef = (q->coef*coef);         p->expn = (q->expn + expn);         q = q->next;     }     p->next = NULL;     return Poly; } void add(Polynomial poly1, Polynomial poly2) {  //把 poly2 加到 poly1 上     PolyNode *p, *q, *r;     r = poly1;     p = poly1->next;  //指向第一个节点     q = poly2->next;     poly2->next = NULL;     while (p && q) {         if (p->expn > q->expn) {             r->next = p;             p = p->next;             r = r->next;         } else if (p->expn < q->expn) {             r->next = q;             q = q->next;             r = r->next;         } else {             PolyNode *t;             p->coef += q->coef;             if (!(p->coef > -0.000001 && p->coef < 0.000001)) //系数不为0             {                 r->next = p;                 r = r->next;                 p = p->next;             } else {                 t = p;                 p = p->next;                 free(t);             }             t = q;             q = q->next;             free(t);         }     }     if (p)         r->next = p;     if (q)         r->next = q; } Polynomial polySubtract(Polynomial poly1, Polynomial poly2) {  //多项式减法 poly1-poly2形成一个新的多项式     //把poly2的系数取相反数，形成一个新的多项式     Polynomial poly = (PolyNode*)malloc(sizeof(PolyNode)); //构造头节点     PolyNode *p, *q;     p = poly;     q = poly2->next;     while (q) {         p->next = (PolyNode*)malloc(sizeof(PolyNode));         p = p->next;         p->coef = -(q->coef);  //系数取反         p->expn = q->expn;         q = q->next;     }     p->next = NULL;     add(poly, poly1);  //利用加法     return poly; } Polynomial polyAdd(Polynomial poly1, Polynomial poly2) { //多项式相加 poly1+poly2形成一个新的多项式     Polynomial poly = (PolyNode*)malloc(sizeof(PolyNode));  //和多项式的头节点     poly->next = NULL;     PolyNode *p, *q, *r;     r = poly;     p = poly1->next;     q = poly2->next;     while (p&&q) {         if (p->expn > q->expn) {             r->next = (PolyNode*)malloc(sizeof(PolyNode));             r = r->next;             r->coef = p->coef;             r->expn = p->expn;             p = p->next;         } else if (p->expn < q->expn) {             r->next = (PolyNode*)malloc(sizeof(PolyNode));             r = r->next;             r->coef = q->coef;             r->expn = q->expn;             q = q->next;         } else {             float m = p->coef + q->coef;             if (!(m > -0.000001 && m < 0.000001)) {                 r->next = (PolyNode*)malloc(sizeof(PolyNode));                 r = r->next;                 r->coef = m;                 r->expn = p->expn;             }             q = q->next;             p = p->next;         }     }     while (p) {         r->next = (PolyNode*)malloc(sizeof(PolyNode));         r = r->next;         r->coef = p->coef;         r->expn = p->expn;         p = p->next;     }     while (q) {         r->next = (PolyNode*)malloc(sizeof(PolyNode));         r = r->next;         r->coef = q->coef;         r->expn = q->expn;         q = q->next;     }     r->next = NULL;     return poly; } Polynomial polyMultiply(Polynomial poly1, Polynomial poly2) {  //多项式相乘     Polynomial poly = (PolyNode*)malloc(sizeof(PolyNode));  //创建多项式和的头节点     poly->next = NULL;     PolyNode *p;     p = poly2->next;     while (p) {         add(poly, multiply(poly1, p->coef, p->expn));         p = p->next;     }     return poly; } void printPoly(Polynomial poly) {  //打印多项式     if (poly && poly->next) {         PolyNode *p = poly->next;  //p指向第一个节点         while (p->next) {             printf("%gx^%d", p->coef, p->expn);             p = p->next;             if (p && (p->coef > 0))                 printf("+");         }         if (p->expn == 0)             printf("%g", p->coef);   //打印常数项         else             printf("%gx^%d", p->coef, p->expn);         printf("\n");     } } void freePoly(Polynomial poly) {  //释放内存     if (poly && poly->next) {         PolyNode *p, *q;         p = poly;         while (p) {             q = p->next;             free(p);             p = q;         }     }     poly = NULL; } int main() {     printf("用链表实现多项式的加减法\n");     Polynomial poly1, poly2, poly3;     printf("创建多项式一\n");     poly1 = createPolynomial();     printf("多项式一：\n");     printPoly(poly1);     printf("创建多项式二\n");     poly2 = createPolynomial();     printf("多项式二：\n");     printPoly(poly2);     printf("两多项式相加，和为：\n");     poly3 = polyAdd(poly1, poly2);     printPoly(poly3);     freePoly(poly3);     printf("两个多项式相乘，积为：\n");     poly3 = polyMultiply(poly1, poly2);     printPoly(poly3);     freePoly(poly3);     printf("两多项式相减，差为：\n");     poly3 = polySubtract(poly1, poly2);     printPoly(poly3);     freePoly(poly1);     freePoly(poly2);     freePoly(poly3);     system("pause");     return 0; }

1：双重循环做“系数相乘指数相加”，结果保存到第三个列表中 2：对结果列表按指数排序 3：遍历结果列表，合并同类项


Question: oj上的一道题输入几个字符串然后将重复的输出用的散列，我的问题是当字符串散列值相同算法就直接输出了，而不是完全相同时输出

我也知道啊，这个问题困扰好久了。就是我新调用一次函数里面有一个给指针申请空间的语句，然后再给指针结构体的内容赋值，而下一次再执行这个函数的时候这个指针的值就被覆盖了一样。他不应该是从新申请了一个空间吗？

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。


Question: c语言数组

void fun(char p1[], char p2[]) {      int i=0, j;     for (i=0;p1[i]!='\0';i++)         ;      for (j=0;p2[j]!='\0';j++)         p1[i++]=p2[j];     p1[i] = 0;   /*'\0'*/ }  参考一下吧

*p1=*p?这个怎么看起来不对劲啊

#include <stdio.h> void fun(char p1[], char p2[]) {  	int i=0,j; 	char p[120]; for (i=0;p1[i]!='\0';i++)     p[i]=p1[i]; for (j=0;p2[j]!='\0';j++) 	p[i++]=p2[j];  *p1=*p;   }  main() {    char s1[80], s2[40] ;void NONO ();       printf("Enter s1 and s2:\n") ;      scanf("%s%s", s1, s2) ;      printf("s1=%s\n", s1) ;      printf("s2=%s\n", s2) ;      printf("Invoke fun(s1,s2):\n") ;      fun(s1, s2) ;      printf("After invoking:\n") ;      printf("%s\n", s1) ;      NONO() ; } 这个是整个程序，你看看

if(p1[i]!='\0') p[i++]=p1[i]; 这儿的if是不是应该用while呢？ 改成这样 (p1[i]!='\0') p[i++]=p1[i]; 这是其一。 第二个问题，p1若是字符数组，那么p1 = p；是无法赋值的；那么即使p1是指向数组的字符指针，那么p1 = p;这儿调用fun之后p会被自动释放，因为p数组是局部变量。除非把p定义成static属性的变量。否则返回局部数组没有意义。  建议将你的函数原型贴出来，没有形参和实参，以及fun的调用规则，不好确定如何去修改。


Question: C语言函数问题

函数还能在main中声明啊？

引用 2 楼 paschen 的回复:Research函数中，把InsertSort(int *arr, int n);改成：void InsertSort(int *arr, int n);  要有返回类型，这才算一个函数声明 回答到点子上了，改了之后就编译成功了，是我太粗心了，谢谢

#include<stdio.h> #include<stdlib.h> #include<string.h>  struct Number { 	int a; 	struct Number *next; };  /*    函数声明，Insert（）是插入函数，Delete（）是删除函数，Research（）是查询函数    InsertSort（）是插入排序函数  */ void Insert(struct Number *first,int x); void Delete(struct Number *first,int x); void Research(int *arr,int n,int x,struct Number *first); void InsertSort(int *arr,int n);  int main() { 	int n,x; 	char ch; 	int i; 	struct Number *first=(struct Number *)malloc(sizeof(struct Number));//头结点，初始化头结点 	first->a=0; 	first->next=NULL; 	while(scanf("%d",&n)!=EOF) 	{ 		int *arr=(int *)malloc(sizeof(int)*(n+1));//用一个数组来放与x异或的值，初始化 		memset(arr,0,sizeof(int)*(n+1)); 		for(i=0;i<n;i++) 		{ 			scanf(" %c %d",&ch,&x); 			switch(ch) 			{ 				case '+': Insert(first,x);break; 				case '-': Delete(first,x);break; 				case '?': Research(arr,n,x,first);break; 			} 		} 		printf("%d\n",arr[1]); 	} } void Insert(struct Number *first,int x) { 	struct Number *p=first; 	while(p!=NULL) 	{ 		p=p->next; 	} 	struct Number *s=(struct Number *)malloc(sizeof(struct Number)); 	s->a=x; 	p=s; 	s->next=NULL; } void Delete(struct Number *first,int x) { 	struct Number *q=first; 	struct Number *p=q->next; 	while(p!=NULL) 	{ 		if(p->a==x) 		{ 			q->next=p->next; 			free(p); 			return; 		} 		q=q->next; 		p=p->next; 	} } void Research(int *arr,int n,int x,struct Number *first) { 	//InsertSort(int *arr,int n); 	int i=1; 	struct Number *p=first; 	while(p!=NULL) 	{ 		arr[i]=p->a^x;//与链表中的每个数异或求最大值 		p=p->next; 		i++; 	} 	InsertSort(arr,n);//排序，是数组第一个数为最大值 }  void InsertSort(int *arr, int n) { 	int i,j; 	for(i=2;i<=n;i++) 	{ 		arr[0]=arr[i]; 		for(j=i-1;arr[j]<arr[0];j--) 			arr[j+1]=arr[j]; 		arr[j+1]=arr[0]; 	} } 参考一下吧  函数声明建议放在函数外，不建议放在main函数内，这样只会让main函数逻辑更乱。 若被调用函数在调用函数之下，建议在调用函数外，前面提前声明一下即可。


Question: 关于结构体和共用体的数组成员初始化问题

char *t1="str";//编译器支持：将t1的值初始化为常量字符串"str"的起始地址 char t2[5]="str";//编译器不支持：将常量字符串"str"的内容复制一份到&t2[0]开始处  我猜。

引用 15 楼 zhao4zhong1 的回复:对结构体某一成员初始化是语法糖。 语法糖越甜，编译调试查错越苦！ 把有限的生命浪费在品尝/品鉴无穷多种的语法糖中，我认为不值当。 这不是什么语法糖为了找方便捷径什么的事情。这是我认为我对这个知识点有问题，我想要解决它，才来问问题，难道我心里明明对这个地方不懂。要装着没这个问题一样过了它吗？ 或者，老师，这个问题能不能帮助我一下，我问了很多人，还是无法解决

引用 13 楼 xcv163169 的回复:[quote=引用 12 楼 weixin_39587157 的回复:] 打错了      a.t  代表的是字符数组t 的首地址  首地址这个问题。我也不知道具体的。但是初始化的时候应该可以吧。毕竟共用体里是可以这样初始化的。你说的第二点是我觉得是赋值吧，赋值跟初始化不一样吧。。[/quote]  我看的教材上有这样的话 C99标准允许对某一成员初始化，如： struct Student b={.name="xxxxxx"}；前面声明的时候struct Student{  long int num; char name[20] };

引用 12 楼 weixin_39587157 的回复:打错了      a.t  代表的是字符数组t 的首地址  首地址这个问题。我也不知道具体的。但是初始化的时候应该可以吧。毕竟共用体里是可以这样初始化的。你说的第二点是我觉得是赋值吧，赋值跟初始化不一样吧。。

打错了      a.t  代表的是字符数组t 的首地址

struct Stu a={.t="sss"};  这样初始化是不行的，因为a.t  代表的是字符数组a的首地址，相当于常量，怎么可以给 a.t 赋值呢？  1.如果你想初始化,最好整体初始化 struct Stu ={5,"sss" }; 2.如果你想单个成员初始化的话；加头文件#include<string.h> struct Stu *a,t; a=&t; a->s=5; strcpy(a->t,"sss");

调试，或者依次输出共用体里那个数组的元素看看，不用字符串输出，(我一般这么查问题)

引用 8 楼 no_emotion 的回复:楼主，你试试把.t改为.t[ ]  .t表示的是a中的成员a.t，t已经定义好了[5]个长度，我也试了这样是不行的

楼主，你试试把.t改为.t[ ]

引用 5 楼 xcv163169 的回复:引用 3 楼 no_emotion 的回复:初始化字符数组，如果输出用%s，初始化最后必须主动加\0，结构体和共用体应该都这样，但是你用四个字符初始化5数量的数组，为什么能成功就不知道了(新手，水平有限).对字符数组初始化的时候不是会在最后加上\0算一个元素吗 '\0'和数值0是相等的。即'\0'字符的ASCII值对应的十进制是0，即0 == ‘\0'， 你在判断字符串结束标记时，可以直接判断是否等于0 比如下面就是计算字符串的长度的逻辑代码，  char src[] = "hello"; int i = 0; while (src[i] != 0)    /*也可以直接while (src[i])*/     i++;

引用 4 楼 cfjtaishan 的回复:估计你的编译器不是支持C99的， C99标准支持这样的结构体的初始化。如果不支持，建议你一个个的赋值，或者先这样初始化 struct Stu a = { 0 }; 可是对共用体指定第二项数组成员初始化的时候那里不是c99才支持的么。额。我用的是DEV-CPP 5.4.0

引用 1 楼 FOR_SEEK的回复:结构体可以对某个变量赋值，用{.变量名=值...}就行，共用体是共用一个地址，只需要初始化一个即可， 刚没加载出来，没看完，不懂


Question: 杭电OJ出现Runtime Error (ACCESS_VIOLATION)，麻烦各位前辈帮我看下原因~

#include <stdio.h> #include <stdlib.h>  int main(int argc, char* argv[]) {     int i,j,n,m;     int num = 0;     float sum = 0, aver = 0;     float **stu, *course_avr_list;      while(scanf("%d %d", &m, &n) == 2)     {         course_avr_list = (float *)malloc(sizeof(float) * n);         if (!course_avr_list)             exit(0);         stu = (float **)malloc(sizeof(float *) * m);         if (!stu)             exit(0);         for(i = 0; i < n; i++) {             stu[i] = (float *)malloc(sizeof(float)*(n + 1));             if (!stu[i])                 exit(0);             course_avr_list[i] = 0;         }         for(i = 0; i < m; i++)         {             for(j = 0; j < n; j++) {                 scanf("%f", &stu[i][j]);                 sum += stu[i][j];                 course_avr_list[j] += stu[i][j];             }             aver = sum / m;             stu[i][n] = aver;             sum = 0;         }         for (i = 0; i < m; i++)             printf("%.2f\t", stu[i][n]);         printf("\n");          for (j = 0; j < n; j++) {             course_avr_list[j] /= n;             printf("%.2f\t", course_avr_list[j]);         }         printf("\n");          for (i = 0; i < m; i++) {             for (j = 0; j < n; j++)                 if (stu[i][j] < course_avr_list[j])                     break;             if (j >= n)                 num++;         }         printf("\n%d\n",num);         num = 0;         for (i = 0; i < n; i++)             free(stu[i]);         free(stu);         free(course_avr_list);      }     return 0; }  参考一下吧 对于学生成绩，不建议是用double类型，因为float类型完全能够表示，double比float多占内存空间； 建议减少循环次数，能将循环次数合并的则合并，循环次数增加会导致时间复杂度高，也一定原因上会加剧running time。 malloc需要多少就申请多少，没必要都要多申请一个。 malloc申请的空间需要手动释放，因此使用完之后要记着释放。如果有多次测试数据，那么若不释放会导致内存泄露。

a=(double **)malloc(sizeof(double *)*(i+1)); for(n=0;n<j;n++)  a[n] = 上面分配了  i+1个指针单元， 下面0～j, 当j大于i+1时，下面就越界了  输入的参数应先做判断是否合法， 比如上面输入负数会出什么问题？ 分配的缓冲区应及时清理 变量最好是起个比较知意的名字， 这样不容易出错  后面的自己慢慢分析吧  还有

对了，分配内存那里，一开始写的分配的大小都是i个和j个，后来实在找不出问题乱改就试了试多分配一个...


Question: char *src = "Hello";是合法的语句吗？

char* src = "hello"; VS2017实测不合法。 如果需要内容可修改，可用数组，如果用指针的话我真想不出来编译器怎么分配内存，如果访问越界怎么办 如果不需要修改，为什么不加const，你这样编码风格就不对

char *src = "Hello";是合法的语句吗？ 是合法的； Hello是常量字符串，存储在常量区，常量字符串是不能修改的。  加上赵4老师：#pragma comment(linker,"/SECTION:.rdata,RW")以后，确实能修改了。但//加这句可以让常量区可写，后果自负！

单纯看这一点，完全合法。

不要纠结各种常量了，这个世界上唯一不变的就是变化。用API WriteProcessMemory还能修改正运行的其它进程的内存里面的所谓常量呢！

引用 9 楼 shihengzhen101 的回复:[quote=引用 8 楼 zhao4zhong1 的回复:] [quote=引用 6 楼 shihengzhen101 的回复:] [quote=引用 4 楼 zhao4zhong1 的回复:] #pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！  你这句话可是分发了大半个论坛[/quote] 我哪句话不是分发了大半个论坛？[/quote] 说的也对啊，我竟无言以对！[/quote]

引用 8 楼 zhao4zhong1 的回复:[quote=引用 6 楼 shihengzhen101 的回复:] [quote=引用 4 楼 zhao4zhong1 的回复:] #pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！  你这句话可是分发了大半个论坛[/quote] 我哪句话不是分发了大半个论坛？[/quote] 说的也对啊，我竟无言以对！

引用 6 楼 shihengzhen101 的回复:[quote=引用 4 楼 zhao4zhong1 的回复:] #pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！  你这句话可是分发了大半个论坛[/quote] 我哪句话不是分发了大半个论坛？

引用 1 楼 cfjtaishan 的回复:是。在有些编译器里可能会报错，加上const就不会报错。 因此写成这样是最完备的： const char *src = "Hello"; +1

引用 4 楼 zhao4zhong1 的回复:#pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！  你这句话可是分发了大半个论坛

最好别这样写。一般写成 char src[] = "Hello";

字符串最好还是加上const

地址指向常量区 指向的内容不可修改 最好还是定义成数组

是的.  char *src = "Hello";  // Hello存放在文字常量区，指针src指向H这个字节的地址

合法，变量src指向字符串Hello的首地址。

本来不合法，但由于历史原因以前的编译器可以通过编译，VS2017默认是不支持，要把符合模式设置为否才行


Question: 关于指针操作的问题

引用 1 楼 qq_36751214 的回复:计算机存储数据时安装16进制，或者2进制不是10进制，所以应该是int a=0x123456;  char *p=&a; *p=0x20; cout<<hex<<a<<endl;  仅供参考  明白啦，谢谢

引用 2 楼 yxwsbobo 的回复:楼上的是对的，十进制的123456 中的56，并非是一个字节，你改变第一个字节是不会把56替换的  十进制 123456 的 十六进制是 0x1E240  第一个字节清零变成 0X1E200 也就是十进制的 123392 ，所以你给第一个字节赋值多少， 就相当于用10禁止的 123392加多少  明白啦明白啦，茅塞顿开呀...谢谢啦


Question: 关于二级指针的问题

崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。

理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后，就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。

void test(int *p){        *p = 20;  } 可以简单地考虑一下上述这种情况，你  int  a;  然后调用test(&a)不会有问题，而int *p_a,test(p_a)就会错误，因为你的p_a现在指向的是一个不确定的内存位置，就会非法访问。 所以说你先定义 void *haha，再void **result = &haha，再调用pthread_join(t,result)也是不会报错的。    具体pthread_join函数里怎么用了result你可以看源码

解引指针前要先想一下指针有没指向有效的内存，否则类型是一致了，解引了无效的指针自然可能导致你程序崩溃

引用 2 楼 yxwsbobo 的回复:并非是类型一样就可以了，这个函数调用会修改 result  本身的值，内部使用的时候会进行 *result = ... 而你直接定义二级指针，那么天知道解引用会解到哪里，所以出错了。 你可以试试  pthread_t t; void **result; *result = new (void*); if((pthread_join(t,result))==0) {     printf("thread terminated,result is: %s\n",((char*)*result)); }  并非是类型一样就可以了，这个函数调用会修改 result  本身的值，内部使用的时候会进行 *result = ... 而你直接定义二级指针，那么天知道解引用会解到哪里，所以出错了。 你可以试试  pthread_t t; void **result = new (void*); if((pthread_join(t,result))==0) {     printf("thread terminated,result is: %s\n",((char*)*result)); }  应该是这样

pthread_join第二个参数是作为传出参数用的，如果要想得到完整的解释就需要查看pthread_join是如何实现的。 但是，我们可以通过第一种定义一重指针，传递一重指针的地址进去可以推测： int pthread_join(pthread_t thread, void **retval); pthread_join函数对于第二个参数的运用，是*result指向一个全局错误号变量。即将错误号的地址带出来，就可以当出现错误时（执行pthread_join失败）打出错误码从而得到错误原因。因此在pthread_join里的实现，应该是 *retval = &errno_code;即result = &errno_code; 若定义的result是二重指针，并且result是野指针，那么在pthread_join中，*result也是野指针（一重），所以会导致段错误；


Question: 将h264视频封装到mxf文件中，播放不出来？

引用 1 楼 zhao4zhong1 的回复:百度搜相关关键字。 但是我查百度并没有关于h264,打包成mxf格式的，我一个学生初次接触这个视频解析打包，有点难，有好多地方都不是特别懂

百度搜相关关键字。


Question: oc中关于如何调用已经输入的数据

引用 1 楼 cfjtaishan 的回复:一个是将addMark函数中需要在show中打印的数据以返回值的形式给show（对于show来讲是传入参数）； 一个是定义全局的数据，这样show方法来讲，全局的数据也是可见的。关于这两个回答。1不是很明白如何把多个参数做为返回值传入show中，2我是通过运行程序后输入的数据去传递给addmark，保存在其中，在通过这个数据在show中执行一个运算过程。怎样定义全局数据呢


Question: 不知道哪错了 关于链表的题

谢谢 大佬 受教

#include<stdio.h> #include<stdlib.h>  struct node {     int data;     struct node *next; };  struct node *create_link(int num); void merge_link(struct node *phead_a, struct node *phead_b); static void visit_link(struct node *phead); void destroy_link(struct node *phead);   int main() {  #if 1     int m, n;     struct node *phead_a, *phead_b;      scanf("%d %d", &m, &n);      phead_a = create_link(m);     phead_b = create_link(n);      //visit_link(phead_a);     //visit_link(phead_b);      merge_link(phead_a, phead_b);      visit_link(phead_a);      destroy_link(phead_a); #else     int m,n,i,j,x,y;     scanf("%d %d",&m,&n);     struct aaa *head1,*head2,*p,*q,*t,*p1,*p2,*q1,*q2,*k;     head1=(struct aaa*)malloc(sizeof(struct aaa));     head1->next=NULL;     q1=head1;     for(i=0; i<m; i++)     {         p1=(struct aaa*)malloc(sizeof(struct aaa));         scanf("%d",&p1->data);         p1->next=NULL;         q1->next=p1;         q1=p1;     }     head2=(struct aaa*)malloc(sizeof(struct aaa));     head2->next=NULL;     q2=head2;     for(i=0; i<n; i++)     {         p2=(struct aaa*)malloc(sizeof(struct aaa));         scanf("%d",&p2->data);         p2->next=NULL;         q2->next=p2;         q2=p2;     }     p=head2->next;     while(p)     {         x=0;         t=head1->next;         q=head1;         while(t)         {             if(p->data<t->data)             {                 for(i=0; i<x; i++)                 {                     q=q->next;                 }                 p->next=q->next;                 q->next=p;                 break;             }             else             {                 x++;             }             t=t->next;         }         if(t==NULL)         {             while(q->next)             {                 q=q->next;             }             p->next=q->next;             q->next=p;         }         p=p->next;     }     p=head1->next;     while(p)     {         if(p->next==NULL)             printf("%d\n",p->data);         else             printf("%d ",p->data);         p=p->next;     } #endif     return 0; }  struct node *create_link(int num) {     struct node *phead, *pnew, *plast;     int i;      phead = (struct node *)malloc(sizeof(struct node));     if (!phead)         exit(0);     phead->next = NULL;     plast = phead;      for (i = 0; i < num; i++) {         pnew = (struct node *)malloc(sizeof(struct node));         if (!pnew)             exit(0);         scanf("%d", &pnew->data);         plast->next = pnew;         plast = pnew;     }     plast->next = NULL;      return phead; }  void merge_link(struct node *phead_a, struct node *phead_b) {     struct node *pa, *pb, *pc;      pa = phead_a->next;     pb = phead_b->next;     pc = phead_a;      while (pa && pb) {         if (pa->data > pb->data) {             pc->next = pb;             pc = pb;             pb = pb->next;         } else {             pc->next = pa;             pc = pa;             pa = pa->next;         }     }      pc->next = pa ? pa : pb; }  void destroy_link(struct node *phead) {     struct node *ptmp, *pcur;      pcur = phead->next;     while (pcur) {         ptmp = pcur->next;         free(pcur);         pcur = ptmp;     } }  static void visit_link(struct node *phead) {     struct node *pcur = phead->next;      while (pcur) {         printf("%d\t", pcur->data);         pcur = pcur->next;     }     putchar(10); } 参考一下吧  不建议将所有功能都写到main函数内，那样代码读起来会比较混乱。建议使用自定义函数，每个函数实现一个功能。


Question: C程序分段错误

//C++ Operators //  Operators specify an evaluation to be performed on one of the following: //    One operand (unary operator) //    Two operands (binary operator) //    Three operands (ternary operator) //  The C++ language includes all C operators and adds several new operators. //  Table 1.1 lists the operators available in Microsoft C++. //  Operators follow a strict precedence which defines the evaluation order of //expressions containing these operators.  Operators associate with either the //expression on their left or the expression on their right;    this is called //“associativity.” Operators in the same group have equal precedence and are //evaluated left to right in an expression unless explicitly forced by a pair of //parentheses, ( ). //  Table 1.1 shows the precedence and associativity of C++ operators //  (from highest to lowest precedence). // //Table 1.1   C++ Operator Precedence and Associativity // The highest precedence level is at the top of the table. //+------------------+-----------------------------------------+---------------+ //| Operator         | Name or Meaning                         | Associativity | //+------------------+-----------------------------------------+---------------+ //| ::               | Scope resolution                        | None          | //| ::               | Global                                  | None          | //| [ ]              | Array subscript                         | Left to right | //| ( )              | Function call                           | Left to right | //| ( )              | Conversion                              | None          | //| .                | Member selection (object)               | Left to right | //| ->               | Member selection (pointer)              | Left to right | //| ++               | Postfix increment                       | None          | //| --               | Postfix decrement                       | None          | //| new              | Allocate object                         | None          | //| delete           | Deallocate object                       | None          | //| delete[ ]        | Deallocate object                       | None          | //| ++               | Prefix increment                        | None          | //| --               | Prefix decrement                        | None          | //| *                | Dereference                             | None          | //| &                | Address-of                              | None          | //| +                | Unary plus                              | None          | //| -                | Arithmetic negation (unary)             | None          | //| !                | Logical NOT                             | None          | //| ~                | Bitwise complement                      | None          | //| sizeof           | Size of object                          | None          | //| sizeof ( )       | Size of type                            | None          | //| typeid( )        | type name                               | None          | //| (type)           | Type cast (conversion)                  | Right to left | //| const_cast       | Type cast (conversion)                  | None          | //| dynamic_cast     | Type cast (conversion)                  | None          | //| reinterpret_cast | Type cast (conversion)                  | None          | //| static_cast      | Type cast (conversion)                  | None          | //| .*               | Apply pointer to class member (objects) | Left to right | //| ->*              | Dereference pointer to class member     | Left to right | //| *                | Multiplication                          | Left to right | //| /                | Division                                | Left to right | //| %                | Remainder (modulus)                     | Left to right | //| +                | Addition                                | Left to right | //| -                | Subtraction                             | Left to right | //| <<               | Left shift                              | Left to right | //| >>               | Right shift                             | Left to right | //| <                | Less than                               | Left to right | //| >                | Greater than                            | Left to right | //| <=               | Less than or equal to                   | Left to right | //| >=               | Greater than or equal to                | Left to right | //| ==               | Equality                                | Left to right | //| !=               | Inequality                              | Left to right | //| &                | Bitwise AND                             | Left to right | //| ^                | Bitwise exclusive OR                    | Left to right | //| |                | Bitwise OR                              | Left to right | //| &&               | Logical AND                             | Left to right | //| ||               | Logical OR                              | Left to right | //| e1?e2:e3         | Conditional                             | Right to left | //| =                | Assignment                              | Right to left | //| *=               | Multiplication assignment               | Right to left | //| /=               | Division assignment                     | Right to left | //| %=               | Modulus assignment                      | Right to left | //| +=               | Addition assignment                     | Right to left | //| -=               | Subtraction assignment                  | Right to left | //| <<=              | Left-shift assignment                   | Right to left | //| >>=              | Right-shift assignment                  | Right to left | //| &=               | Bitwise AND assignment                  | Right to left | //| |=               | Bitwise inclusive OR assignment         | Right to left | //| ^=               | Bitwise exclusive OR assignment         | Right to left | //| ,                | Comma                                   | Left to right | //+------------------+-----------------------------------------+---------------+

for(i=0; i<NUM; i++)         {                 *p[i] = arry[--num];         } 将上面的一句代码改成：   (*p)[i] = arry[--num];


Question: C程序分段错误

#include<stdio.h> #include<stdlib.h> #include<string.h>  #define MAXSIZE 1000  void Trans(const int *arry, int NUM, int **p) {     int i, num = NUM;     *p = (int *)malloc(sizeof(int)*NUM);     if(!(*p))     {         perror("malloc fail");         return;     }     for(i=0; i<NUM; i++)     {         (*p)[i] = arry[--num];   /*注意改成(*p)[i]， *p是一个整体，需要加括号，否则会p和[]先结合*/     } }  int main() {     int NUM, i;     int *p = NULL;     int arry[MAXSIZE];      bzero(&arry, sizeof(arry));      printf("please input NUM(1·1000):\n");     scanf("%d", &NUM);     printf("please input all:\n");     for(i=0; i<NUM; i++)     {         scanf("%d", &arry[i]);     }      Trans(arry, NUM, &p);     for(i=0; i<NUM; i++)     {         printf("arry[%d] = %d\n", i, p[i]);     }     printf("\n");     free(p);     p = NULL;     return 0; }  参考一下吧 给(*p)赋值时需要注意下


Question: C语言怎么实现鼠标事件啊，就是响应鼠标的操作，在VC6.0里面

https://zhidao.baidu.com/question/181505908.html https://www.cnblogs.com/lxl0928/p/3807262.html http://www.bianceng.cn/Programming/C/201501/47580.htm 只要肯努力还是能找到相关资料的。如果说找不到，说明还不够努力。  如果想要找到完全符合你的要求的，那就是搜集资料自己做～


Question: 求助

dest-1，在初始时，dest指向第一个指针，而dest-1则不可预测

dest-1得出的是一个值，即右值（C++里面的说法），然后进行自增操作，而自增自减操作是对一个变量才可以的。  PS：此处错误跟1楼内存的的说法没有必然联系，这是编译错误不涉及运行时错误

是的，这两个表达式的区别是很容易看出来的。 *dest++ = *src++ 这个表达式是现将src指向的字符赋值给dest指向的内存，然后src++, dest++; 但是*(dest-1)++ = *src++就不一样了。这个表达式是将src指向的字符赋值给dest-1指向的内存，如果dest指向的是以0x11223344开始的内存，那么dest-1就是指向0x11223343.很明显越界了（左越界）；越界的写入是未定义了，如果这个一字节的内存单元不可写，那么就会出现这样的错误。


Question: 关于strtok函数的问题

引用 3 楼 weixin_39587157 的回复:这要理解的话 ，涉及strtok函数的实现原理代码，你可以 理解p = strtok(NULL, ".");  为继续分割 第一次分割时在p后面追加，NULL 等到最后一次分割时while（）遇到NULL后，结束循环  通俗易懂

引用 2 楼 jianwen0529 的回复:strtok实现中，是会对即将要截取的字符串修改的，通常做法是对分割字符用\0替代，并记录某些状态 strtok(NULL, ".");会根据上一次的状态，再对剩余的子串分割  你可以看看你的编译器下对这个函数实现的源码  依据楼上的说法，这个函数不是线程安全的，因为一个线程可能对另一个线程的状态进行改写，也可能造成数据竞争或冲突  明白啦，谢谢啦

引用 1 楼 cfjtaishan 的回复:当第一个参数传递NULL时，则表示从剩余的字符串里找到子串，并将子串前的返回；strtok函数里会保存第一次调用之后（使用静态变量static保存）剩余的字符串的地址（或称为位置）。 个人建议使用strtok_r代替strtok，因为strtok_r函数是strtok函数的可重入版本，strtok_r是linux平台下的strtok函数的线程安全版。  char *strtok_r(char *str, const char *delim, char **saveptr); 这个是strtok_r的原型，第三个参数saveptr就是上次调用之后剩余的字符串首地址。使用strtok_r可应该会更好理解字符串分割。  明白啦，谢谢啦


Question: 有序链表的合并问题

引用 4 楼 Lraxer 的回复:谢谢大家，我已经找到问题了。二楼讲的第一个问题就是主要的问题，第二个问题我的程序62行写了。 看来你没有很好理解第二个问题。你有没有考虑到两个链表不一样长，或者说两个链表的长度相差多个节点，比如5个，10个节点， 如果你用下面的测试用例试试你的代码能否正常合并： 链表1:3个节点，分别1， 2， 3，链表2：5个节点，分别：2， 3， 4， 5， 6， 正确的结果合并之后应该是：1， 2， 3， 4， 5， 6 我估计用你的逻辑不是完全输出。不信的话可以试一下

else {             p3->next = p1;             p3 = p1;             p1 = p1->next;      //这里少了一句，p1未指向下一节点             Num* temp = p2->next;             free(p2);             p2 = temp;         }

去掉getchar();这儿加getchar()没有意义。你可能考虑到，输入一个整型数时会将'\n'残留在输入缓冲里，但是'\n'是字符，不会与%d匹配的。因此不用担心这个。

#include <stdio.h> #include <stdlib.h>  #define len sizeof(Num)  typedef struct Number {     int value;     struct Number* next; }Num;  Num* CreatList() {     int m;     Num* head, *p, *p1;     head = (Num*) malloc(len);     if (!head)         exit(0);     head->next = NULL;     p = head;      printf("how many items would you like to input?\n");     scanf("%d", &m);      for (int i=0;i<m;i++) {         p1 = (Num*) malloc(len);         if (!p1)             exit(0);         printf("Input the value:\n");         scanf("%d", &p1->value);         p->next = p1;         p = p1;     }     p->next = NULL;      return head; }  void MergeLists(Num* head1, Num* head2) {     Num *p1 = head1->next, *p2 = head2->next, *p3;     p3 = head1;      while (p1 && p2) {         if(p1->value > p2->value) {             p3->next = p2;             p3 = p2;             p2 = p2->next;         }         else if (p1->value < p2->value) {             p3->next = p1;             p3 = p1;             p1 = p1->next;         }         else {             p3->next = p1;             p3 = p1;             //不要忘了让p1也只想下一个节点             p1 = p1->next;             Num *tmp = p2->next;             free(p2);             p2 = tmp;         }     }      while (p1) {         p3->next = p1;         p3 = p1;         p1 = p1->next;     }     while (p2) {         p3->next = p2;         p3 = p2;         p2 = p2->next;     } }  void PrintList(Num* head) {     Num* p = head->next;     while (p) {         printf("%d\t", p->value);         p = p->next;     }     putchar(10); }  int main() {     Num* head1, * head2;     printf("写入两个有序表\n");     head1 = CreatList();     PrintList(head1);     head2 = CreatList();     PrintList(head2);      MergeLists(head1, head2);     printf("After merge: \n");     PrintList(head1);     return 0; } 参考一下吧 两个问题： 问题1：当p1的value和p2的value相等时，将p1的节点给了p3->next，但是p1没有指向下一个节点，既没有操作p1 = p1->next；p2删除了相等的节点，指向了下一个节点； 问题2：当p1或p2为NULL时，即其中一个链表先结束时，第二个链表还没有结束，应该将剩余的节点直接链到p3上，即新的链表上。


Question: C语言指针

理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！

当一个函数的参数列表里有多个参数的时候，C语言没有规定实参的进栈顺序和计算顺序，而是由编译器自行决定的。#include <stdio.h> int a() { 	printf("a\n"); 	return 1; }  int b() { 	printf("b\n"); 	return 2; }  int main(void) { 	printf("%d, %d\n", a(), b()); 	return 0; }  //MSVC 下编译结果 b a 1, 2  // Ubuntu GCC 下编译结果 b a 1, 2  // LLVM Clang 下编译结果 a b 1, 2

这个和入栈顺序没有关系，根据调用约定肯定是从右向左入栈，但这解释不了为什么3个地址都一样  事实上问题出在了函数调用中求值顺序，对于每一个参数的求值顺序C++标准中并没有规定，也就是这个行为是未定义的，任何情况都有可能发生  printf("%p,%p,%p,",p++,p++,p++); 这个在不同编译器下表现的结果都不一样的

看结果来说应该是从右向左入栈了，但这个好像不是硬性规定，不同的编译器可能实现不同，写程序时不要依赖这样的副作用！

int 无意义的操作 = 0; int 无意义的问题 = 0; printf("%d, %d, %d\n", 无聊的操作, 无聊的操作++, (无聊的问题++) + 无聊的问题);

由于ptr_num++或++ptr_num有副作用，因此不建议这么写: printf("%p\t %d \t %p\n", ptr_num, *(ptr_num++), ptr_num); 不同的编译器入栈的顺序可能不一样，因此在传参数时去掉后增++

首先不是数字加1了，而是ptr_num指向了第二个元素的地址，即2所在的位置首地址，因此第二个输出的是2； 因为ptr_num的指向的第一个元素的地址，即nums的首地址是：0x0041FB84，少4个字节（若是64位系统应该是0x0041FB80,少8个字节）； 在两个printf之前加一句： printf("%p\n", ptr_num); 就可以知道nums的首地址是多少了。

就如一楼所说，楼主心里默认为函数参数的求值顺序是从左到右，但其实标准并没有对这个顺序有什么规定。每个编译器都可能做出适合自己的与别家编译器不一样的选择。 换个编译器，说不定楼主看到的输出又不一样了

第一个printf执行时，编译器实际先计算了*ptr_num++，执行后ptr_num已经自增，此后三个参数才依次入栈，所以两个printf实际显示的都是已经自增了之后的ptr_num


Question: 请教一个c语言链表问题，请懂的人回答一下下

这是由于函数的副本机制，函数的传递都是值传递，实参的值是拷贝给形参的，修改形参不能改变实参，只能传递地址

数据结构对单链表进行数据排序 http://bbs.csdn.net/topics/392201633

因为传入函数里的是指向结构体的指针，存储的是结构体的地址;你说的那种情况要传入该指针的地址（指针的指针）才行。

在调用函数的时候，这里的node就从传入的变量拷贝了一份。只是用来暂时存放结点的地址。 除非你加引用。

原因是node是List Length函数里的局部变量，参数传递，就是值传递，即实参的值赋值给形参（形参是函数内的局部变量），那么若是指针给指针传值，就是传的地址值。node是指针，它用于存放地址，而内存空间（节点的存放位置）是在堆上，不在函数栈上。而node只是用于存放堆上节点的地址。所以，node = node->next修改的是node指向的位置，而没有修改堆上节点的next指向节点。

C语言中，函数的传递都是值传递，也就是说，实参的值是拷贝给形参的，所以修改形参的值，改变不了实参的值。


Question: 用c语言求真值表以及主析取式，请大神指点

int L=sprintf(x+z,"|(!%c&!%c&%c)",c[0],c[1],c[2]);z+=L;

引用 2 楼 自信男孩的回复:x[z++]='|';x[z++]='(';x[z++]='!';x[z++]=c[0];x[z++]='&';x[z++]='!';x[z++]=c[1];x[z++]='&';x[z++]=c[2];x[z++]=')'; 这么写代码不感觉看着都费劲吗？ 累啊，但是小白刚入门，想不到什么更好的方法。。


Question: 链表排序时只有第一个是乱码，有的信息串位。

void creat(st1* head) {     int i;     int n;     st1 *p,*q;     printf("输入书籍数目:\n");     scanf("%d",&n);     for(i=0;i<n;i++)     {         printf("输入第%d个借阅信息:\n",i+1);         p = (st1*)malloc(sizeof(st1));         printf("输入编号:\n");         scanf("%d",&p->num);         printf("输入书名:\n");         scanf("%s", p->book);         printf("输入读者姓名:\n");         scanf("%s", p->name);         printf("输入借阅时间:\n");         scanf("%d",&p->time);         printf("输入第%d个借阅信息完成\n",i+1);         printf("\n");         if(0 == i)         {             head->next = p;         }         else         {             q->next = p;         }         q = p;     }     p->next = NULL; } 第一个问题：scanf输入p->name和p->book去掉前面的&。因为数组名本身就是地址值，就是数组的首地址。 同理insert,change函数里的scanf对于name和book的输入一样需要去掉&; 第二个问题：insert函数，对newst指针分配空间，为啥要给p->num, p->book等输入赋值呢？是不是应该给newst赋值呢？ 下面是我的修改： st1* insert(st1* head) {     st1 *pnew, *prev, *pcur;     int i = 1;     int index;     printf("要插入的位置:");     scanf("%d",&index);     pnew = (st1*)malloc(sizeof(st1));     if (!pnew)         exit(0);     printf("输入编号:\n");     scanf("%d",&pnew->num);     printf("输入书名:\n");     scanf("%s", pnew->book);     printf("输入读者姓名：");     scanf("%s", pnew->name);     printf("输入借阅时间:\n");     scanf("%d",&pnew->time);     printf("输入借阅信息完成\n");      prev = head;     pcur = head->next;      while (pcur) {         if (i == index) {             pnew->next = prev->next;             prev->next = pnew;             return head;         }         prev = prev->next;         pcur = pcur->next;         i++;     }     if (!pcur) {         prev->next = pnew;         pnew->next = NULL;     }     return head; #if 0     if(1 == index)     {         newst->next = head->next;         head->next = newst;          return head;     }     while( p ) {         if(i == (index-1))         {             st1 *q = p->next ;             p->next = newst;             newst->next = q;         }         p = p->next ;         i++;     }     return p; #endif } 第三个问题，sort排序，按照编号排序还有按照借阅时间排序，但是程序里只支持按照编号排序，因为按照借阅时间排序的部分，也是判断p->num > q->num； 还有，排序时，对于哨兵节点是不参与排序的，即链表的头结点。所以，循环变量初始化时，应该是p = head->next； void sort(st1 *head) {     st1 *p,*q;     int m ;     int temp;     int temp1;     char temp2[10];      printf("选择1)按编号,2)按时间排序\n");     scanf("%d",&m);     switch(m)     {         case 1:             for(p = head->next;p != NULL; p = p-> next)             {                 for (q = p->next;q != NULL; q = q-> next )                 {                     if(p->num>q->num)                     {                         temp = q->num;                         q->num = p->num;                         p->num =temp;                         temp1 = q->time;                         q->time = p->time;                         p->time =temp1;                         strcpy(temp2,q->book);                         strcpy(q->book,p->book);                         strcpy(p->book,temp2);                     }                 }             }             break;         case 2:             for(p = head->next;p != NULL; p = p-> next)             {                 for (q = p->next;q != NULL; q = q-> next )                 {                     if(p->time > q->time)                     {                         temp = q->time;                         q->time = p->time;                         p->time =temp;                         temp1 = q->num;                         q->num = p->num;                         p->num =temp1;                         strcpy(temp2,q->book);                         strcpy(q->book,p->book);                         strcpy(p->book,temp2);                      }                 }             }             break;     } } 以上参考一下吧

谢谢大家了，问题解决了。


Question: winfrom  对象转xml

自己再写一段代码，读取xml文件，将其中的<?xml version="1.0"?>改为<? Xml version="1.0" encoding="UTF-8"?>  所谓修改删除文件a某位置的内容，其实是读打开文件a，再将‘a中修改删除位置之前的内容＋修改删除的内容＋a中修改删除位置之后的内容’保存到文件b，关闭文件a，删除文件a，将文件b改名为与之前文件a相同的名字，仅此而已。http://bbs.csdn.net/topics/391975224


Question: 动态结构体数组的问题

引用 1 楼 cfjtaishan 的回复:tu=(student*)malloc(M*sizeof(student*)); 改一下这句，改成这样：去掉sizeof括号内的* stu=(student*)malloc(M*sizeof(student)); 因为加上*则是申请了M * sizeof(int)个字节的空间，因为加上*就是申请M个指针，指针变量的大小和int类型占用内存的大小一样。 从你的接下来的代码来看，你要申请的不是M个指针，而是申请M个student类型的变量，即M * sizeof(student)  欸没问题了，谢谢老师！

如果申请的是sizeof(student *)，根据长度计算，很明显会越界。注意 sizeof(student *)的长度和sizeof(student)的长度不一样，差距很大，如果结构体成员越多，差距会越大； sizeof(student *)若是在32位系统里，该值为4；sizeof(student)在精简版源文件定义结构体里，为12


Question: c语言数据结构线性表

引用 1 楼 自信男孩的回复:建议把代码贴出来，对于代码的问题不要贴图片。 好的，我弄到下面去。。。。

再供参考： 数据结构对单链表进行数据排序 http://bbs.csdn.net/topics/392201633

仅供参考：#include <algorithm> #include <iostream> #include <functional> #include <cstring> using namespace std; int main() {     char *Alphabet = "abcdefghijklmnopqrstuvwxyz" ;     char *Vowels   = "aeiou" ;     char *AlphaNum = "0123456789abcdef" ;     char result[45] ;     char *last ;      int lenA  = strlen(Alphabet) ;     int lenV  = strlen(Vowels  ) ;     int lenAN = strlen(AlphaNum) ;      cout << "Alphabet = " << Alphabet << endl ;     cout << "Vowels   = " << Vowels   << endl ;     cout << "AlphaNum = " << AlphaNum << endl ;      cout << "\nusing non-predicate versions" << endl ;      //non-predicate set_difference     last = set_difference(Alphabet, Alphabet+lenA,                           AlphaNum, AlphaNum+lenAN,                           result) ;     *last = 0 ;     cout << "set_difference(Alphabet, AlphaNum) =  " << result << endl ;      //non-predicate set_intersection     last = set_intersection(Alphabet, Alphabet+lenA,                             AlphaNum, AlphaNum+lenAN,                             result) ;     *last = 0 ;     cout << "set_intersection(Alphabet, AlphaNum) =  " << result << endl ;      //non-predicate set_symmetric_difference     last = set_symmetric_difference(Alphabet, Alphabet+lenA,                                     Vowels  , Vowels  +lenV,                                     result) ;     *last = 0 ;     cout << "set_symmetric_difference(Alphabet, Vowels) =  " << result << endl ;      //non-predicate set_union     last = set_union(Alphabet, Alphabet+lenA,                      AlphaNum, AlphaNum+lenAN,                      result) ;     *last = 0 ;     cout << "set_union(Alphabet, AlphaNum) =  " << result << endl ;      cout << "\nusing predicate versions" << endl ;      //predicate set_difference     last = set_difference(Alphabet, Alphabet+lenA,                           AlphaNum, AlphaNum+lenAN,                           result  , less<char>()) ;     *last = 0 ;     cout << "set_difference(Alphabet, AlphaNum) =  " << result << endl ;      //predicate set_intersection     last = set_intersection(Alphabet, Alphabet+lenA,                             AlphaNum, AlphaNum+lenAN,                             result  , less<char>()) ;     *last = 0 ;     cout << "set_intersection(Alphabet, AlphaNum) =  " << result << endl ;      //predicate set_symmetric_difference     last = set_symmetric_difference(Alphabet, Alphabet+lenA,                                     Vowels  , Vowels  +lenV,                                     result  , less<char>()) ;     *last = 0 ;     cout << "set_symmetric_difference(Alphabet, Vowels) =  " << result << endl ;      //predicate set_union     last = set_union(Alphabet, Alphabet+lenA,                      AlphaNum, AlphaNum+lenAN,                      result  , less<char>()) ;     *last = 0 ;     cout << "set_union(Alphabet, AlphaNum) =  " << result << endl ;      return 0 ; }

哥们看不清楚啊。

建议把代码贴出来，对于代码的问题不要贴图片。


Question: 求高效率随机算法

建议楼主搜索“洗牌算法”或者shuffle算法，这是符合你要求的一类做法

长度为10000的数组src_data，初始化为0到9999 整数src_len初始化为10000 重复6000次： 	生成从0到src_len-1的随机数index 	src_data[index]放入目标数组中 	src_data[index]=src_data[src_len-1] 	src_len=src_len-1

随机必然有重复，所谓“不重复的随机”实际上是洗牌。洗牌算法参考下面： #include <stdio.h> #include <stdlib.h> #include <time.h> int d[6]; int i,n,a,b,t; int c,j; void main() {     srand(time(NULL));     printf("shuffle 0..n-1 demo\n");     for (n=1;n<=5;n++) {/* 测试1～5个元素 */         printf("_____n=%d_____\n",n);         j=1;         for (c=1;c<=n;c++) j=j*c;/* j为n! */         j*=n*2;         for (c=1;c<=j;c++) {/* 测试n*2*n!次 */             for (i=0;i<n;i++) d[i]=i;/* 填写0～n-1 */             for (i=n;i>0;i--) {/* 打乱0～n-1 */                 a=i-1;b=rand()%i;                 if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}             }             printf("%04d:",c);             for (i=0;i<n;i++) printf("%d",d[i]);             printf("\n");         }     }     printf("shuffle 1..n demo\n");     for (n=1;n<=5;n++) {/* 测试1～5个元素 */         printf("_____n=%d_____\n",n);         j=1;         for (c=1;c<=n;c++) j=j*c;/* j为n! */         j*=n*2;         for (c=1;c<=j;c++) {/* 测试n*2*n!次 */             for (i=1;i<=n;i++) d[i]=i;/* 填写1～n */             for (i=n;i>1;i--) {/* 打乱1～n */                 a=i;b=rand()%i+1;                 if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}             }             printf("%04d:",c);             for (i=1;i<=n;i++) printf("%d",d[i]);             printf("\n");         }     } }


Question: showmotion这个模块或者函数在MATLAB/simulation 中有人见过吗？

百度搜相关关键字。


Question: 怎么两次输出都一样啊。。。。。

楼主需要了解goto正确使用方法，但是这只限于学习，在实际工作中，一份代码的优劣与goto的使用比例是成反比的。

引用 3 楼 cfjtaishan 的回复:个人建议最好不要轻易使用goto语句，goto语句使用多了对于代码的可读性不好。所以，能不用则不用，尽量避免。goto语句可以用其他方式替换估计这是初学的时候的作业吧，课程都会先学goto，在继续学while和for

#include <stdio.h> #include <stdlib.h> #include <string.h>  int main() { 	char St[20] = "asdasd"; 	goto ASD; aaa:  	printf("%s\n",St); 	goto end; ASD: 	{ 		printf("%s\n",St); 		goto asd; 	} asd: 	{ 		//St[20]="dfg"; 		strcpy(St, "dfg"); 		goto aaa; 	} end: 	system("pause"); 	return 0; } 参考一下吧  字符串赋值，不能用St[20] = "dfg"；再说数组St下表是从0~19，St[20]很明显越界了。 总的来讲，字符串赋值，不能以这种形式（除非是定义时赋值），需要借助字符串拷贝函数。

把        St[20]="dfg";改成strcpy("St","dfg0");试试


Question: 算是服了vs2015了，这段程序为什么不打印？

#include <stdio.h> int main(void) {     int i, j, k;     char letter;     printf("shuru:");     scanf_s("%c", &letter, 1);     k = letter - 'A' + 1;      for (i = 0; i < k; i++)     {         for (j = 0; j < k - i; j++)             printf(" ");         for (j = 0; j <= i; j++)             printf("%c", 'A' + j);         for (j = i - 1; j >= 0; j--)             printf("%c", 'A' + j);         printf("\n");     }     return 0; } 参考一下吧   for (j = i - 1; j >= 0; j--)             printf("%c", 'A' + j); 注意j--，你写成j++,会导致死循环和溢出；

引用 2 楼 qq_30519247 的回复:[quote=引用 1 楼 user-3 的回复:] scanf_s("%c", &letter);  改成：  scanf_s("%c", &letter, 1);  for (j = i - 1; j >= 0; j++)  改成：  for (j = i - 1; j >= 0; j--) 我是不是该放弃vs2015，为什么scanf_s("%c", &letter, 1);还要加1啊。[/quote] 这是因为scanf_s和scanf是不一样的，scanf_s比scanf更安全，更安全体现在它比scanf多一个输入字符数的要求上。因此对于%c需要确定其字符数。

引用 2 楼 qq_30519247 的回复:[quote=引用 1 楼 user-3 的回复:] scanf_s("%c", &letter);  改成：  scanf_s("%c", &letter, 1);  for (j = i - 1; j >= 0; j++)  改成：  for (j = i - 1; j >= 0; j--) 我是不是该放弃vs2015，为什么scanf_s("%c", &letter, 1);还要加1啊。[/quote] 你可以在vs2015里继续用scanf，套路参考http://blog.csdn.net/fantasydreams/article/details/45250627

#include <stdio.h> #include <stdlib.h> int main(void) {     int i, j, k;     char letter;     printf("shuru:");     scanf_s("%c", &letter,1);     k = letter - 'A' + 1;     for (i = 0; i < k; i++)     {         for (j = 0; j < k - i; j++)printf(" ");         for (j = 0; j <= i; j++)printf("%c", 'A' + j);         for (j = i - 1; j >= 0; j--)printf("%c", 'A' + j);         printf("\n");     }     system("pause");     return 0; } 建议楼主参考下面的链接，学学scanf_s和scanf的区别 https://msdn.microsoft.com/en-us/library/w40768et.aspx

引用 1 楼 user-3 的回复:scanf_s("%c", &letter);  改成：  scanf_s("%c", &letter, 1);  for (j = i - 1; j >= 0; j++)  改成：  for (j = i - 1; j >= 0; j--) 我是不是该放弃vs2015，为什么scanf_s("%c", &letter, 1);还要加1啊。