Question: 链表赋值出错

NODE *insert_table(NODE *p,int index)						//添加元素 { 	NODE *pnew=(NODE *)malloc(sizeof(NODE)); 	if (NULL==pnew) 	{ 		printf("Out of space!\n"); 		return 0; 	} 	int n = 0; 	char buffer[64]={0}; 	while (scanf("%s",buffer)!= EOF) 	{ 		//int l1 = strlen(buffer); 		//pnew->arr[n] = (char *)malloc(sizeof(char)*(l1 + 1)); 		pnew->arr[n] = (char *)malloc(strlen(buffer) + 1); 		strcpy(pnew->arr[n],buffer); 		for (int i = 0; i <=n; i++) 		{ 			printf("arr[n]的值为%s",pnew->arr[i]); 		} 	 		if (n==index){ 			break; 		}else{ 			n++; 		} 	} 	pnew->next=p->next;		//新的节点的后继取代前节点的后继 	p->next=pnew;			//前节点指向自己 	return pnew; } 我在中间检测了赋值的问题，好像没错，那么是不是后面指针指向错了。。看了下感觉也没什么问题 pnew->next=p->next;		//新的节点的后继取代前节点的后继 	p->next=pnew;			//前节点指向自己 	return pnew;

引用 2 楼 qq423399099 的回复:楼主贴一下NODE的结构体，那个arr是个啥类型的 #include <stdlib.h> #include <stdio.h> #include <string.h> #include<conio.h> #define NULL 0    #define amount1 100            //结构体中*arr[]数组长度，用来定义扩充成员个数  struct NODE { 	char *arr[amount1]; 	NODE *next;            //指向后继 };

楼主贴一下NODE的结构体，那个arr是个啥类型的

检查指针是否有效，数组是否越界

错误补充_(:зゝ∠)_  0x010F32CB 处的第一机会异常(在 mysqltext.exe 中): 0xC0000005: 读取位置 0x00000190 时发生访问冲突。 线程 0x1938 已退出，返回值为 -1073741510 (0xc000013a)。 程序“[1680] mysqltext.exe”已退出，返回值为 -1073741510 (0xc000013a)。

引用 10 楼 qq423399099 的回复:楼主你的create_table函数里 head头结点的next指针你没有赋值也没有赋成NULL（不知道指向哪了） 之后insert_table函数里while循环之后： pnew->next=p->next;   //报错，p->next指向的是一个未知区域 好的。。谢谢都懂了_(:зゝ∠)_

引用 6 楼 jyxuan94 的回复:所有相关带买都贴下吧 头文件#include <stdlib.h> #include <stdio.h> #include <string.h> #include<conio.h> #define NULL 0    #define amount1 100            //结构体中*arr[]数组长度，用来定义扩充成员个数  struct NODE { 	char *arr[amount1]; 	NODE *next;            //指向后继 };  void help_list();																			//显示帮助文档  int create_table(NODE* head);																//建表，添加类名 NODE *insert_table(NODE *p,int n);												//添加元素  table.cpp文件 #include"table.h" int create_table(NODE* head) { 	head = (NODE *)malloc(sizeof(NODE)); 	int index = 0; 	char buffer[64] = {0}; 	while (scanf("%s",buffer)!= EOF)  	{ 		head->arr[index] = (char *)malloc(strlen(buffer) + 1); 		strcpy(head->arr[index],buffer); 		if(getchar() == '\n')break;//读到输入的字符串的末尾了，结束循环 		else index++; 	} 	return index; }  NODE *insert_table(NODE *p,int index)						//添加元素 { 	NODE *pnew=(NODE *)malloc(sizeof(NODE)); 	if (NULL==pnew) 	{ 		printf("Out of space!\n"); 		return 0; 	} 	int n = 0; 	char buffer[64]={0}; 	while (scanf("%s",buffer)!= EOF) 	{ 		pnew->arr[n] = (char *)malloc(sizeof(strlen(buffer) + 1)); 		strcpy(pnew->arr[n],buffer); 		for (int i = 0; i <=n; i++) 		{ 			printf("arr[n]的值为%s",pnew->arr[i]); 		}  		if (n==index){ 			break; 		}else{ 			n++; 		} 	} 	pnew->next=p->next;		//新的节点的后继取代前节点的后继 	p->next=pnew;			//前节点指向自己 	return pnew; } void insert_member(NODE* head,int add_n,int index)					//添加成员 { 	NODE *pnew =(NODE *)malloc(sizeof(NODE)); 	char buffer[64] = {0}; 	scanf("%s",buffer); 	head->arr[index] = (char *)malloc(strlen(buffer) + 1); 	strcpy(head->arr[index], buffer); 	pnew=head->next; 	for (int i = 0; i <= add_n; i++) 	{ 		scanf("%s",buffer); 		pnew->arr[index] = (char *)malloc(strlen(buffer) + 1); 		pnew=pnew->next; 	}	 } 主函数的cpp文件 #include"table.h" #define amount 100			//数组长度  NODE *head;  //判断开始命令是否正确 void right_wrong(char *p1) { 	char *p2,arr[amount]; 	p2=arr; 	while (1) 	{ 		gets(p2); 		if (strcmp(p1,p2)==0){ 			printf("how to use mysql?	please enter<help>\n>>mysql order>>"); 			break; 		} 		else { 			printf(">>error!\n Please enter<start mysql>\n"); 		} 	} } void main() { 	int index,add_n=1;						//index成员个数,add_n计数 	char *p0,arr[amount]; 	char create_name[300];					//文件保存名字 	NODE *p;								//用来标注链表的最后一个节点地址 	p=head; 	p0=arr;									//p0为输入的字符串，arr数组用来初始化*p0 	char p1[]="start mysql",p2[]="help",p3[]="create table",p4[]="table insert",			//功能命令 	printf(">>my sql!\n"); 	right_wrong(p1);  	//主程序运行过程，输入指令对应到相符的条件下调用函数实现功能 	while (1) 	{ 		gets(p0); 		if (strcmp(p2,p0)==0){											//显示帮助文档		 			printf(">>mysql order>>"); 		} 		else if (strcmp(p3,p0)==0){										//建表和结构体 			printf(">>Please enter the name of the table\n>>");			//保存文件名 			gets(create_name);													 			printf(">>Please enter the member of the table\n>>"); 			index=create_table(head); 			printf(">>success!enter %d memers!\n>>mysql order>>",index+1); 		} 		else if (strcmp(p4,p0)==0){										//元素添加 			printf(">>Please enter the element\n>>"); 			p=insert_table(p,index);									//p的地址变成新的节点 			printf(">>success!\n>>mysql order>>"); 		} 		else { 			printf(">>error!\n Please read the help file\n>>mysql order>>"); 		} 	} } #include <stdlib.h> #include <stdio.h> #include <string.h> #include<conio.h> #define NULL 0    #define amount1 100            //结构体中*arr[]数组长度，用来定义扩充成员个数 #define  amount 100    struct NODE { 	char *arr[amount1]; 	NODE *next;            //指向后继 };  NODE *head;  int create_table(NODE* head) { 	head = (NODE *)malloc(sizeof(NODE)); 	int index = 0; 	char buffer[64] = {0}; 	while (scanf("%s",buffer)!= EOF)  	{ 		head->arr[index] = (char *)malloc(strlen(buffer) + 1); 		strcpy(head->arr[index],buffer); 		if(getchar() == '\n')break;//读到输入的字符串的末尾了，结束循环 		else index++; 	} 	return index; }  NODE *insert_table(NODE *p,int index)						//添加元素 { 	NODE *pnew=(NODE *)malloc(sizeof(NODE)); 	if (NULL==pnew) 	{ 		printf("Out of space!\n"); 		return 0; 	} 	int n = 0; 	char buffer[64]={0}; 	while (scanf("%s",buffer)!= EOF) 	{ 		pnew->arr[n] = (char *)malloc(sizeof(strlen(buffer) + 1)); 		strcpy(pnew->arr[n],buffer); 		if (n==index){ 			break; 		}else{ 			n++; 		} 	} 	pnew->next=p->next;		//新的节点的后继取代前节点的后继 	p->next=pnew;			//前节点指向自己 	return pnew; } void main() {  	int index,add_n=1;						//index成员个数,add_n计数 	char create_name[300];					//文件保存名字 	NODE *p;								//用来标注链表的最后一个节点地址 	p=head; 	 										//建表和结构体												 	printf(">>Please enter the member of the table\n>>"); 	index=create_table(head); 	printf(">>success!enter %d memers!\n>>mysql order>>",index+1);  	printf(">>Please enter the element\n>>"); 	p=insert_table(p,index);									//p的地址变成新的节点 	printf(">>success!\n>>mysql order>>");		 	 } 大大上面的整理的有点乱。我现在把代码相关的部分拿出来放在一个源文件了

引用 7 楼 qq423399099 的回复:[quote=引用 4 楼 jyxuan94 的回复:] [quote=引用 2 楼 qq423399099 的回复:] 楼主贴一下NODE的结构体，那个arr是个啥类型的 #include <stdlib.h> #include <stdio.h> #include <string.h> #include<conio.h> #define NULL 0    #define amount1 100            //结构体中*arr[]数组长度，用来定义扩充成员个数  struct NODE { 	char *arr[amount1]; 	NODE *next;            //指向后继 };[/quote] strcpy那里应该是对的[/quote] pnew->next=p->next;        //新的节点的后继取代前节点的后继     p->next=pnew;            //前节点指向自己     return pnew; 这个应该也没问题吧

引用 4 楼 jyxuan94 的回复:[quote=引用 2 楼 qq423399099 的回复:] 楼主贴一下NODE的结构体，那个arr是个啥类型的 #include <stdlib.h> #include <stdio.h> #include <string.h> #include<conio.h> #define NULL 0    #define amount1 100            //结构体中*arr[]数组长度，用来定义扩充成员个数  struct NODE { 	char *arr[amount1]; 	NODE *next;            //指向后继 };[/quote] strcpy那里应该是对的


Question: 填字游戏

循环遍历就行，如果乘数与被乘数都变就两重循环，否则就一重

穷举法吧。但好象无解：//      12345 //         *1 //----------- //     555555 #include <stdio.h> int main() {     int a,i;      a=555555/12345+1;     for (i=1;i<a;i+=10) {         if (i*12345==555555) {             printf("12345*%d==555555\n",i);             break;         }     }     return 0; }

谁会？？？？？


Question: 初学者long double 在win10上输出的问题

我跟楼主一样的问题，输出也一样。用的编译器是gcc 4.9.2，后来升级成gcc 5.3.0都还是一样，至今没找到原因。

编译器位数不同吧 32和64输出不一样

编译器是C-free5.0 书上是VC7.1 显示的

不说什么编译器别人基本上也帮不了你。


Question: 如何将c语言中的程序输出值按照每行一个数据输出

谢谢！明白啦

<<endl 不可以吗


Question: 帮我看看程序哪儿写得不行

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  有时不将“调用函数名字＋各参数值，进入函数后各参数值，中间变量值，退出函数前准备返回的值，返回函数到调用处后函数名字＋各参数值＋返回值”这些信息写日志到文件中是无论如何也发现不了问题在哪里的，包括捕获各种异常、写日志到屏幕、单步或设断点或生成core文件、……这些方法都不行！ 写日志到文件参考下面： #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <io.h> #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  _vsnprintf         vsnprintf #endif //Log{ #define MAXLOGSIZE 20000000 #define MAXLINSIZE 16000 #include <time.h> #include <sys/timeb.h> #include <stdarg.h> char logfilename1[]="MyLog1.log"; char logfilename2[]="MyLog2.log"; static char logstr[MAXLINSIZE+1]; char datestr[16]; char timestr[16]; char mss[4]; CRITICAL_SECTION cs_log; FILE *flog; #ifdef WIN32 void Lock(CRITICAL_SECTION *l) {     EnterCriticalSection(l); } void Unlock(CRITICAL_SECTION *l) {     LeaveCriticalSection(l); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } #endif void LogV(const char *pszFmt,va_list argp) {     struct tm *now;     struct timeb tb;      if (NULL==pszFmt||0==pszFmt[0]) return;     _vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);     ftime(&tb);     now=localtime(&tb.time);     sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);     sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );     sprintf(mss,"%03d",tb.millitm);     printf("%s %s.%s %s",datestr,timestr,mss,logstr);     flog=fopen(logfilename1,"a");     if (NULL!=flog) {         fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);         if (ftell(flog)>MAXLOGSIZE) {             fclose(flog);             if (rename(logfilename1,logfilename2)) {                 remove(logfilename2);                 rename(logfilename1,logfilename2);             }         } else {             fclose(flog);         }     } } void Log(const char *pszFmt,...) {     va_list argp;      Lock(&cs_log);     va_start(argp,pszFmt);     LogV(pszFmt,argp);     va_end(argp);     Unlock(&cs_log); } //Log} int main(int argc,char * argv[]) {     int i; #ifdef WIN32     InitializeCriticalSection(&cs_log); #else     pthread_mutex_init(&cs_log,NULL); #endif     for (i=0;i<10000;i++) {         Log("This is a Log %04d from FILE:%s LINE:%d\n",i, __FILE__, __LINE__);     } #ifdef WIN32     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_log); #endif     return 0; } //1-78行添加到你带main的.c或.cpp的那个文件的最前面 //81-85行添加到你的main函数开头 //89-93行添加到你的main函数结束前 //在要写LOG的地方仿照第87行的写法写LOG到文件MyLog1.log中

对啊，这只是对应的执行积分操作的程序，还有控制系统和控制端口的程序，太多了这里就没写。 这儿直说控制积分的部分出现了什么问题。

代码不全啊，运行不了


Question: 控制台窗口显示图片

#pragma comment(lib,"user32") #pragma comment(lib,"gdi32") #include <stdlib.h> #include <conio.h> #include <windows.h> HWND WINAPI GetConsoleWindow(); void HideTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if (GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = FALSE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } void ShowTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if (GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = TRUE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } int main() {     HWND  hwnd;     HDC   hdc;     HFONT hfont;     HBITMAP hbm;     HDC hdcBits;     BITMAP bm;      system("color F0");     system("cls");     HideTheCursor();     hwnd  = GetConsoleWindow();     hdc   = GetDC(hwnd);     hbm=LoadImage(0,"C:\\Windows\\Soap Bubbles.bmp",IMAGE_BITMAP,0,0,LR_DEFAULTSIZE|LR_LOADFROMFILE);     if (hbm) {         hdcBits = CreateCompatibleDC(hdc);         GetObject (hbm, sizeof(BITMAP), &bm);         SelectObject(hdcBits,hbm);         BitBlt(hdc,200,10,bm.bmWidth, bm.bmHeight,hdcBits,0,0,SRCCOPY);         DeleteDC(hdcBits);         DeleteObject(hbm);     }     hfont = CreateFont(24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "华文楷体");     SelectObject(hdc,hfont);     SetTextColor(hdc,RGB(255,255,255));     SetBkMode(hdc,TRANSPARENT);     TextOut(hdc,210,30,"这个背景是泡泡",14);     DeleteObject(hfont);     ReleaseDC(hwnd,hdc);     getch();     system("color 07");     system("cls");     ShowTheCursor();     return 0; }

>>>完善一下，只可惜覆盖后不会自画  EasyX好

完善一下，只可惜覆盖后不会自画 #define _WIN32_WINNT 0x0500 #include <Windows.h> #include <stdio.h>  #pragma comment(lib, "kernel32")  int main(void) {        HWND hWnd = GetConsoleWindow();    HDC hdc = GetDC(hWnd);    HDC memhDc = CreateCompatibleDC(hdc);    HBITMAP hBitmap = (HBITMAP)LoadImage(NULL, "1.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);    SelectObject(memhDc, hBitmap);    {       BITMAP bmp;       int i;       GetObject(hBitmap, sizeof(BITMAP), &bmp);       for (i = 0; i < bmp.bmHeight / 15; ++i)       {          putchar('\n');       }       BitBlt(hdc, 0, 0, bmp.bmWidth, bmp.bmHeight, memhDc, 0, 0, SRCCOPY);    }    DeleteObject(hBitmap);    DeleteDC(memhDc);    ReleaseDC(hWnd, hdc);    return 0; }


Question: 求教！如何上界面。

引用 5 楼 zhao4zhong1 的回复:VB6 VB6可视化程序设计(无锡职业技术学院)http://download.csdn.net/detail/zhao4zhong1/6824713

关于上界面，仅供参考： 从C语言的菜单界面管理系统到C++ Builder的图形用户界面，一个简单的电话簿Demo例子 http://blog.163.com/tab_98/blog/static/1192409720158673337998/

推荐个很老的游戏库，SDL，很多之前的游戏就是用这做的，像象棋，仙剑，坦克大战等，完全要用c语言写，界面都是代码实现的。

据说c++可以编写上位机，用VC的MFC

vc写点小程序蛮好的


Question: 有人做一维图像信号处理的吗c实现

百度搜一搜总会搜到的。


Question: 菜鸟求助一个关于C语言循环输入字符串的问题，我相信大神们肯定也被问过好多次！

EOF 文件结束

引用 2 楼 xusongge 的回复:引用 1 楼 user-5 的回复:放在while循环里面不行吗，跳出的条件是 输入结束 ，至于其中输入的字符串保存起来不就行了吗，循环结束输出不知道循环次数啊兄弟，而且题目也没说什么时候结束，可能输入3行结束，可能4行，可能5行...  放在while(1)循环里，循环中生成一个随机数，当这个数满足某种条件时退出循环

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

引用 2 楼 xusongge 的回复:引用 1 楼 user-5 的回复:放在while循环里面不行吗，跳出的条件是 输入结束 ，至于其中输入的字符串保存起来不就行了吗，循环结束输出不知道循环次数啊兄弟，而且题目也没说什么时候结束，可能输入3行结束，可能4行，可能5行... 不用考虑循环次数啊，不等于EOF不就行了。(c = getchar() != EOF)


Question: C语言socket编程的问题

引用 5 楼 Rewen 的回复:不是数据问题，是recv 端的问题。 没有配置listening socket吧  服务端   #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <errno.h>  int main(int age, char *args[]) { 	struct sockaddr_in addr; 	struct sockaddr_in client_addr;  	int sockfd = 0;  //套接字 	int port = 0;    //端口 	int on = 1; 	int choice = 0; 	socklen_t client_addrlen = 0;  	char buff[1024*10]; 	char pathname[1024];  	FILE *fpjpg = NULL;  	memset(&addr, 0 , sizeof(addr)); 	memset(&client_addr, 0 , sizeof(client_addr)); 	memset(buff, 0 , sizeof(buff)); 	memset(pathname, 0 , sizeof(pathname));  	if ( age < 2 ) 	{ 		printf("port not bei null\n"); 		return -1; 	}  	port = atoi(args[1]); 	if ( port == 0 ) 	{ 		printf("atoi fail\n"); 		return -1; 	}  	sockfd = socket(AF_INET, SOCK_STREAM , 0);  	if ( sockfd == 0 ) 	{ 		printf("socket fail\n"); 		return -1; 	}  	if ( setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on , sizeof(on)) == -1 ) 	{ 		printf("setsockope fail\n"); 		return -1; 	}  	addr.sin_family = AF_INET; 	addr.sin_port = htons(port); 	addr.sin_addr.s_addr = htonl(INADDR_ANY);  	if (bind(sockfd, (struct sockaddr *)&addr , sizeof(addr)) == -1 ) 	{ 		printf("bind fail\n"); 		return -1; 	}  	if ( listen(sockfd , 20) == -1 ) 	{ 		printf("listen fail\n"); 		return -1; 	}  	client_addrlen = sizeof(client_addrlen); 	if ( accept(sockfd, (struct sockaddr *)&client_addr, &client_addrlen) == -1 ) 	{ 		printf("accept fail\n"); 		return -1; 	}  	while (1) 	{ 		printf("[1] is jpg [2] is text :");  		scanf("%d",&choice);  		switch(choice) 		{ 		case 1:  	//		printf("input jpg pathname:"); 	//		while (getchar() != '\n');  	//		fgets(pathname, sizeof(pathname), stdin);  			fpjpg = fopen("/home/x/code/1.jpg", "rb");  	//		if (pathname[strlen(pathname) - 1] == '\n') 	//		{ 	//			pathname[strlen(pathname) - 1] = 0; 	//		}   			if ( fpjpg == NULL ) 			{ 				printf("jpg open fail : %s\n",strerror(errno)); 				continue; 			}  			while ( !(feof(fpjpg)) ) 			{  				memset(buff, 0 , sizeof(buff));  				if (fread(buff, 1 , sizeof(buff), fpjpg) == 0) 				{ 					printf("jpg open fail : %s\n",strerror(errno)); 				}  				if (send(sockfd, buff, sizeof(buff), 0) == -1) 				{ 					printf("send fail\n"); 					break; 				}  			} 			break; 		} 		fclose(fpjpg); 		close(sockfd); 	}  	return EXIT_SUCCESS; }   客户端  #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>  int main(int age, char *args[]) { 	struct sockaddr_in addr;  	int sockfd = 0;   //套接字 	int port = 0;	  //端口 	int ret = 0;  	char buff[1024*10];    //数据buff 	char pathname[1024];   //创建新文件的路径 	char ipbuf[128];       //ip 地址  	FILE *fpjpg = NULL;  	memset(&addr, 0 , sizeof(addr)); 	memset(buff, 0 , sizeof(buff)); 	memset(ipbuf, 0 , sizeof(ipbuf));  	if ( age < 3 ) 	{ 		printf("ip and port not bei null\n"); 		return -1; 	}  	port = atoi(args[2]); 	if ( port == 0 ) 	{ 		printf("atoi fail\n"); 		return -1; 	}  	if (strlen(args[1]) > 16) 	{ 		printf("Invalid IP address\n"); 	} 	strncpy(ipbuf, args[1], strlen(args[1]));   	sockfd = socket(AF_INET, SOCK_STREAM , 0);  	if ( sockfd == 0 ) 	{ 		printf("socket fail\n"); 		return -1; 	}   	addr.sin_family = AF_INET; 	addr.sin_port = htons(port); 	addr.sin_addr.s_addr = inet_addr(ipbuf);   	if (connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) 	{ 		printf("connect fail\n"); 		return -1; 	}  	fpjpg = fopen("/home/x/code/project/sock/2.jpg","wb");  	while (1) 	{ 		memset(buff, 0 , sizeof(buff)); 		ret = recv(sockfd, buff, sizeof(buff), 0);  // 接收数据  每次到这里直接就返回0了  		if (ret == 0) 		{ 			printf("recv is ok\n"); 			break; 		} 		fwrite(buff, 1 , sizeof(buff), fpjpg);  	} 	fclose(fpjpg); 	close(sockfd);   	return EXIT_SUCCESS; }

不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊！ http://bbs.csdn.net/topics/380167545

我是以 二进制 就是wb 打开一个图片文件 然后调用fread 写到buff里 再把这个buff用send发出去     客户端 调用recv 接收到buff里  再用fwrite写到另一个图片文件里   但是服务端一发送   客户端的recv函数就直接返回0  客户端就退出了，我在想是不是recv 接收到了什么数据导致返回0

那是你客户端写错了， send/recv就是操作二进制的。

不行 send 发出去  客户端收到直接就退出了  二进制数据

create a tcp socket//socket_fd = socket(AF_INET, SOCK_STREAM, 0); connect to server open the file  while (1) { 	size = fread(); 	if (size < 0)	 	{ 		break; 	} 	send(socket_fd, buf, size, 0); }  close socket


引用 2 楼 aiur233 的回复:[quote=引用 1 楼 lianshaohua 的回复:] 1、怀疑是他的lib库编译的工具不是vs2010导致的 2、有可能是你工程编码与他的编码不一致 我重新下了一遍winpcap开发者包，从头配置了一下，现在好了，我还是不知道为什么[/quote] 有可能是包的问题

引用 1 楼 lianshaohua 的回复:1、怀疑是他的lib库编译的工具不是vs2010导致的 2、有可能是你工程编码与他的编码不一致 我重新下了一遍winpcap开发者包，从头配置了一下，现在好了，我还是不知道为什么


Question: 求一个解决思路：加密和解密分别用了一个秘钥后保存压缩

仅将文件名或链接保存到数据库中。

压缩可以减短文本的长度，但是对于加密过后的内容来说，压缩比应该不高。  信息总是要占内存的，这跟有没有加密，有没有压缩，没有关系。

引用 2 楼 chehw_1 的回复:如果所需加密的明文过长，那么不要直接用非对称加密的方法直接加密，否则会严重影响性能。  可以考虑用非对称加密算法（RSA、ECC等）的公钥来加密一个对称式加密（比如AES_CBC_256）密钥K，并用密钥K通过对称加密算法进行加密； 解密时，先用私钥解密来获取密钥K，然后再用对应的对称加密算法进行解密。 恩，只用它来存续用户信息应该没有问题

引用 1 楼 yuelengdihai 的回复:[/code]有没有长度限制

仅供参考 #include <iostream.h> #include <math.h> #include <stdio.h>  typedef int Elemtype; Elemtype p,q,e; Elemtype fn; Elemtype m,c; int flag = 0; typedef void (*Msghandler) (void); struct MsgMap {  char ch;  Msghandler handler; }; /* 公钥 */ struct PU {  Elemtype e;  Elemtype n; } pu; /* 私钥 */ struct PR {  Elemtype d;  Elemtype n; } pr; /* 判定一个数是否为素数 */ bool test_prime(Elemtype m) {  if (m <= 1) {   return false;  }  else if (m == 2) {   return true;  }  else {   for(int i=2; i<=sqrt(m); i++) {    if((m % i) == 0) {     return false;     break;    }   }   return true;  } } /* 将十进制数据转化为二进制数组 */ void switch_to_bit(Elemtype b, Elemtype bin[32]) {  int n = 0;  while( b > 0) {   bin[n] = b % 2;   n++;   b /= 2;  }  } /* 候选菜单，主界面 */ void Init() {  cout<<"*********************************************"<<endl;  cout<<"***       Welcome to use RSA encoder      ***"<<endl;  cout<<"***               a.about                 ***"<<endl;  cout<<"***               e.encrypt               ***"<<endl;  cout<<"***               d.decrypt               ***"<<endl;  cout<<"***               s.setkey                ***"<<endl;  cout<<"***               q.quit                  ***"<<endl;  cout<<"**********************************by*Terry***"<<endl;  cout<<"press a key:"<<endl; } /* 将两个数排序，大的在前面*/ void order(Elemtype &in1, Elemtype &in2) {  Elemtype a = ( in1 > in2 ? in1 : in2);  Elemtype b = ( in1 < in2 ? in1 : in2);  in1 = a;  in2 = b; } /* 求最大公约数 */ Elemtype gcd(Elemtype a, Elemtype b) {  order(a,b);  int r;  if(b == 0) {  return a;  }  else {   while(true) {    r = a % b;    a = b;    b = r;    if (b == 0) {    return a;    break;    }   }  }  } /* 用扩展的欧几里得算法求乘法逆元 */ Elemtype extend_euclid(Elemtype m, Elemtype bin) {  order(m,bin);  Elemtype a[3],b[3],t[3];  a[0] = 1, a[1] = 0, a[2] = m;  b[0] = 0, b[1] = 1, b[2] = bin;  if (b[2] == 0) {    return a[2] = gcd(m, bin);   }  if (b[2] ==1) {    return b[2] = gcd(m, bin);  }  while(true) {   if (b[2] ==1) {    return b[1];    break;   }   int q = a[2] / b[2];   for(int i=0; i<3; i++) {    t[i] = a[i] - q * b[i];    a[i] = b[i];    b[i] = t[i];   }  } } /* 快速模幂算法 */ Elemtype modular_multiplication(Elemtype a, Elemtype b, Elemtype n) {  Elemtype f = 1;  Elemtype bin[32];  switch_to_bit(b,bin);  for(int i=31; i>=0; i--) {   f = (f * f) % n;   if(bin[i] == 1) {    f = (f * a) % n;   }  }  return f; } /* 产生密钥 */ void produce_key() {  cout<<"input two primes p and q:";  cin>>p>>q;    while (!(test_prime(p)&&test_prime(q))){   cout<<"wrong input,please make sure two number are both primes!"<<endl;   cout<<"input two primes p and q:";   cin>>p>>q;  };  pr.n = p * q;  pu.n = p * q;  fn = (p - 1) * (q - 1);  cout<<"fn = "<<fn<<endl;  cout<<"input e :";  cin>>e;  while((gcd(fn,e)!=1)) {   cout<<"e is error,try again!";   cout<<"input e :";   cin>>e;  }  pr.d = (extend_euclid(fn,e) + fn) % fn;  pu.e = e;  flag = 1;  cout<<"PR.d: "<<pr.d<<"   PR.n: "<<pr.n<<endl;  cout<<"PU.e: "<<pu.e<<"   PU.n: "<<pu.n<<endl; } /* 加密 */ void encrypt() {  if(flag == 0) {   cout<<"setkey first:"<<endl;   produce_key();  }  cout<<"input m:";  cin>>m;  c = modular_multiplication(m,pu.e,pu.n);  cout<<"c is:"<<c<<endl; } /* 解密 */ void decrypt() {  if(flag == 0) {   cout<<"setkey first:"<<endl;   produce_key();  }  cout<<"input c:";  cin>>c;  m = modular_multiplication(c,pr.d,pr.n);  cout<<"m is:"<<m<<endl; } /* 版权信息 */ void about() {  cout<<"*********************************************"<<endl;  cout<<"***               by Terry                ***"<<endl;  cout<<"*** copyright 2010,All rights reserved by ***"<<endl;  cout<<"*** Terry,technology supported by weizuo !***"<<endl;  cout<<"*** If you have any question, please mail ***"<<endl;  cout<<"*** to 18679376@qq.com   !                ***"<<endl;  cout<<"*** Computer of science and engineering   ***"<<endl;  cout<<"*** XiDian University    2010-4-29        ***"<<endl;  cout<<"*********************************************"<<endl;  cout<<endl<<endl;  Init(); } /* 消息映射 */ MsgMap Messagemap[] = {  ,  ,  ,  ,   }; /* 主函数，提供循环 */ void main() {  Init();  char d;  while((d = getchar())!='q') {   int i = 0;   while(Messagemap[i].ch) {    if(Messagemap[i].ch == d) {     Messagemap[i].handler();     break;    }    i++;   }  } }


Question: c语言中删除字符串中的特定字符的问题

%c int c？？？

层主 这个问题我也不明白啊 你解释的我也没明白 能再给我详细讲讲吗

有点不踏实感，刚梳理一下，现在清晰了。谢楼上

引用 6 楼 qq_28840093 的回复:再回三楼。dev c++对于字符的类型没有特别要求，用int 和char一样。c-free里更改成char，就可以了。都是试验，不敢相信，需要权威哎--。 所以是OK了么？

引用 4 楼 qq_28840093 的回复:弄不来调试。手写步骤，明白楼上这句话【str1的下标不应该变，否则str1这个位置也同样跳过了】的意思了。那第三个应该是对的呀。比如：are you all right? 输入r。第一步：str[0]->str1[0] = a ,j++为1,i++为1. 第二步：str[1]=r,跳过，i++为2，j仍然为1.第三步。这样试数，好像没什么地方不对。在dev c++中确实实现了。可是在c-free中没有变动。还是迷糊.. 楼主的你的int c改为char c没，如果是int c的话我这里VS也得不到正确结果

楼主的第一和第二个是一样的效果，i和j的值在每次循环里都是一样的值。。。。换汤不换药啊。。。 第三个可以是因为，你应该跳过str里等于c的字符，而此时str1的下标不应该变，否则str1这个位置也同样跳过了（之前存着什么就是什么，如果没有清零那么将会是垃圾值） 楼主这里第三个运行是正确的么？我这里VC编译器是不行的 应该要将int c;改成char c; 而且char str1[100];改为char str1[100] = {0};否则数组没有\0结尾会输出很多个垃圾字符来

.................dev c++单步调试用不了，在下其他编译器。等下试试吧

建议单步跟踪程序运行，每一步观察各变量怎么变化的


Question: C语言中遇到了一个小的疑问

谢谢大家的回复，受益匪浅

引用 5 楼 u014472726 的回复:[quote=引用 2 楼 qq423399099 的回复:] 数组名是个常量，指针才是变量。 char str[] ="helloworld"; 这是编译器事先界定了的，它是一个常量指针变量，初始化后，无法再变更。  str++，机器侦测到你有意图变更它，立刻报警，机器天生明白。谢谢你的回答，我只是有点疑问 不是数组名就是指向数组的指针，所以我有点晕[/quote] 哈哈，刚学是有点晕的，楼主加油

引用 2 楼 qq423399099 的回复:数组名是个常量，指针才是变量。 char str[] ="helloworld"; 这是编译器事先界定了的，它是一个常量指针变量，初始化后，无法再变更。  str++，机器侦测到你有意图变更它，立刻报警，机器天生明白。谢谢你的回答，我只是有点疑问 不是数组名就是指向数组的指针，所以我有点晕

你定义的是str，下面用的又是src  假设你是打错了，但src是字符数组，而不是指针，不能进行++运算

修改如下：  #include<stdio.h> #include<string.h> int main() { 	char str[] = "helloworld"; 	//这里的赋值，不就是为了日后的使用吗！ 	char *p = str; 	int i; 	for (i = 0; i <= 10; i++) 	{ 		//if (strncmp(src, "l", 1) == 0) 		if (strncmp(p, "l", 1) == 0) 		{ 			printf("p =%s\n", p); 		} 		p++; 	} 	return 0; }

src是数组类型, 不可以++


Question: c字符串求助

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include <stdbool.h>  static const char _blank[] = " \t\n";  static inline bool  is_blank(char c) { 	int i; 	for(i = 0; i < (sizeof(_blank) - 1); ++i) 	{ 		if(c == _blank[i]) return true; 	} 	return false; }  static inline char * trim_left(char * begin, char * end) {	 	while(begin < end) 	{ 		if(!is_blank(*begin)) break; 		++begin;	 	} 	return begin; }  static inline char * trim_right(char * begin, char * end) {	 	if(begin == end) return end; 	 	while(end > begin) 	{ 		--end; 		if(!is_blank(*end)) break; 	} 	*(end + 1) = '\0'; 	return end + 1; }  static inline void swap_bytes(char * begin, char * end) { 	char c; 	while(begin < end) { 		c = *begin; 		*begin++ = *(--end); 		*end = c; 	} }    int main(int argc, char **argv) { #define MAX_LINE (100) 	int c, i; 	int n = -1; 	 	printf("n = "); 	while(1) 	{		 		c = scanf("%d", &n); 		if(c == 0)  		{ 			while((c = getchar()) != '\n' && c != EOF); // skip tailing charactors 			printf("invalid value. please reinput: \nn = "); 			continue; 		} 		break; 	} 	while((c = getchar()) != '\n' && c != EOF);  	if(-1 == n) exit(1); 	 	char (* input)[MAX_LINE]; // 声明一个二维数组的行指针(每行最多允许输入MAX_LINE个char） 	// 动态分配二维数组的内存 	input = (char (*)[MAX_LINE])malloc(sizeof(char [MAX_LINE]) * n);  	assert(NULL != input); 	 	for(i = 0; i < n; ++i) 	{ 		printf("%d:\t", i + 1); 		fgets(input[i], MAX_LINE, stdin); 	} 	 	char * p, * p_end; 	char * p_sep; 	char * begin; 	for(i = 0; i < n; ++i) 	{ 		p = input[i]; 		p_end = p + strlen(input[i]); 			 		p = trim_left(p, p_end); 		p_end = trim_right(p, p_end); 		printf("str_%d = [%s]  ==> ", i + 1, p); 		 		if(p == p_end) // no content 		{ 			printf("\n"); 			continue; 		} 				 		begin = p; 		while(1) 		{ 			p_sep = strchr(p, '_'); 			if(p_sep)  			{ 				swap_bytes(p, p_sep); 				p = p_sep + 1; 				continue; 			} 			swap_bytes(p, p_end); 			break; 		} 		printf("[%s]\n", begin); 	} 	 	free(input); 	 #undef MAX_LINE 	 	return 0; }

我知道错误了，求大神们教我 就是输入的末尾如果有多个空格的话，输出就会错误 求助该如何删除输入完字符串之后多出来的空格 比如说输入12_12      的话，就会输出21_     21

这个不是同一道题吧

仅供参考：//有字符串 //1_22_333,,4444__55555,_666666 //需要解析为 //1 //22 //333 //_ //4444 //55555 //666666 #include <stdio.h> char s[]="1_22_333,,4444__55555,_666666"; char c,*p,*p1; int st; void main() {     st=0;     p=s;     while (1) {         c=*p;         if (0==c) {             switch (st) {             case 1:printf("_\n");    break;             case 2:printf("%s\n",p1);break;             }             break;//         }         switch (st) {         case 0:                  if ('_'==c) {                            st=0;}             else if (','==c) {                            st=1;}             else             {p1=p;                       st=2;}         break;         case 1:                  if ('_'==c) {                            st=1;}             else if (','==c) {printf("_\n");              st=1;}             else             {p1=p;                       st=2;}         break;         case 2:                  if ('_'==c) {*p=0;printf("%s\n",p1);*p=c;st=0;}             else if (','==c) {*p=0;printf("%s\n",p1);*p=c;st=1;}             else             {                            st=2;}         break;         }         p++;     } } //1 //22 //333 //_ //4444 //55555 //666666

求大神们援助

还是答案错误，明明输出时一样的，但是告诉我答案错误，不知道是哪里出错了 这是我同学用c++写的，给通过了，有什么不一样的地方吗？ #include<iostream> #include<string> #include<memory.h> using namespace std; int main() { string s[101], s1[101]; string strset = "_"; int n; cin>>n; for(int a = 0; a < n; a++){ for(int b = 0; b < 101; b++){ s[b].clear() ; s1[b].clear(); } string in; cin>>in; int first = 0, last = 0, b = 0; if(in[0] != '_'){ first = 0; last = 0; b = 0; }  else { while(in[b] == '_') b++; first = last = b; } int begin = b; while(last < in.length()) { first = last; last = in.find_first_of(strset,first + 1); if(b == begin) s[b] = in.substr(first, last-first); else s[b] = in.substr(first + 1, last - first-1); b++; } for(int c = 0; c < b; c++){ for(int d = s[c].length() - 1; d >= 0; d--){ s1[c] += s[c][d]; } } if(b != 0) cout<<s1[0]; for(int c = 1; c < b; c++){ cout<<"_"<<s1[c]; } cout<<endl; } }

改了几个地方已经标注在里面了，楼主直接复制过去试试  #include<stdio.h> int main() { 	int n; 	scanf("%d",&n);//输入测试的次数n  	fflush(stdin);//清除换行符  	char arr[100]; 	char*p=arr; 	for(int d=0;d<n;d++) 	{ 		/*for(int e=0;e<101;e++)//初始化arr数组为0  		{ 			arr[e]=0; 		} */ 		char arr[100] = {0};//111111111111111111111 		gets(arr);//获取第d个字符串  		char*p=arr;//22222222222222222,每次循环都需要重置指针p的位置 		int ji=0;//ji表示在_之间有ji个字符  		if(*p=='_')//若第一个字符为_的话直接输出_并且将指针移到下一位  		{ 			printf("_");//3333333333333333333333 			p++; 		} 		else//若第一个字符不为_，ji+1并且将指针移到下一位  		{ 			ji++; 			p++; 		} 		while(*p!='\0')//当还没有读到该字符串的结尾时继续循环  		{ 			if(*p!='_')//若对应指针指向的字符不为_，ji+并且指针指向下一位  			{ 				ji++; 				p++; 			} 			else//若对应指针指向的字符为_，输出ji位的 *（p+i）  			{ 				int b=ji;//44444444444444444444 				for(int i=-1;b>0;b--) 				{ 					printf("%c",*(p+i)); 					i--; 				} 				printf("%c",*p);//输出_  				p++;//指针指向下一个字符  				ji=0;//将ji初始化为0  			} 			if(*p=='\0')//若读到结尾的符号  			{ 				int l=ji; 				for(int k=-1;l>0;l--)//输出ji位的*(p+k)  				{ 					printf("%c",*(p+k)); 					k--; 				} 				printf("\n");//换行  				break; //跳出循环  			}  		} 	} }

for(int d=0;d<n;d++)这一句写错了，不是2是n

这次加上了注释，但是还是只能做一次，之后再输入第二个字符串的时候就没有输出了，为什么呢？ #include<stdio.h> int main() { 	int n; 	scanf("%d",&n);//输入测试的次数n  	fflush(stdin);//清除换行符  	char arr[100]; 	char*p=arr; 	for(int d=0;d<2;d++) 	{ 	for(int e=0;e<101;e++)//初始化arr数组为0  	{ 		arr[e]=0; 	 }  	gets(arr);//获取第d个字符串  	int ji=0;//ji表示在_之间有ji个字符  	if(*p=='_')//若第一个字符为_的话直接输出_并且将指针移到下一位  	{ 	printf("'_'"); 	p++; } 	else//若第一个字符不为_，ji+1并且将指针移到下一位  	{ 		ji++; 		p++; 	} 	while(*p!='\0')//当还没有读到该字符串的结尾时继续循环  	{ 		if(*p!='_')//若对应指针指向的字符不为_，ji+并且指针指向下一位  		{ 			ji++; 			p++; 		}         else//若对应指针指向的字符为_，输出ji位的 *（p+i）          {         	int b=ji+1;         	for(int i=-1;b>0;b--)         	{         		printf("%c",*(p+i));         		i--; 			} 			printf("%c",*p);//输出_  			p++;//指针指向下一个字符  			ji=0;//将ji初始化为0  		} 		if(*p=='\0')//若读到结尾的符号  		{ 			int l=ji; 			for(int k=-1;l>0;l--)//输出ji位的*(p+k)  			{ 				printf("%c",*(p+k)); 				k--; 			} 			printf("\n");//换行  			break; //跳出循环  		 }  	} 	} }

楼主你的scanf("%d",&n);你输入一个数以后数字被读走了，但输入缓冲区里还遗留着\n 所以第一次进for循环的时候gets(arr);中的arr读到的是回车符，然后进行if判断，不管true还是false,p都会++ 然后第二次循环的时候，指针已经指向第二个字符了，就算输入进来的是_45_,但if(*p=='_')也会为false  解决方法： scanf("%d",&n);后面加一句  fflush(stdin);//加上这一行，就清空换行符了   PS：楼主貌似下面的逻辑还是有问题的。。楼主可以稍微想下或者加点注释再发一下


Question: 一个dbx小问题

引用 3 楼 lovebelobe 的回复:[quote=引用 1 楼 qq423399099 的回复:] 应该是if(no == 1) 少了个=吧 请大神看看下面这样写是否正确~ stop if(no == 1)[/quote] 可以这样用的，还有stop in和stop at

if(no = =1){ return; }

引用 1 楼 qq423399099 的回复:应该是if(no == 1) 少了个=吧 请大神看看下面这样写是否正确~ stop if(no == 1)

引用 楼主 lovebelobe 的回复:关于下面的代码，调试的时候只想要在no=1的时候停下来，应该用when命令吗？ if(no = 1){ var = ok; } 请大神看看下面这样写是否正确~ stop if(no = 1)

应该是if(no == 1) 少了个=吧


Question: 链表节点排序

仅供参考：//不带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> #include <locale.h> struct NODE {     int          data;     struct NODE *next; } *head,*p,*q,*s,*p1,*p2,*q1,**ta; int i,k,n,t,m,v,N=10; int main() {     setlocale(LC_ALL,"chs");     srand(time(NULL));      head=NULL;      printf("创建%d个节点的单链表:",N);//创建N个节点的单链表     p=head;     for (i=0;i<N;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) exit(1);         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         if (NULL==p) {             head=q;             p=head;         } else {             p->next=q;             p=q;         }     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=3;     v=5;     printf("将值为%d的结点插入到单链表的第%d个结点前:",v,k);//将值为v的结点插入到单链表的第k个结点前     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) exit(1);             q->data=5;             q->next=head;             head=q;             break;         } else {             if (k-1==n) {                 q=(struct NODE *)malloc(sizeof(struct NODE));                 if (NULL==q) exit(1);                 q->data=5;                 q->next=p->next;                 p->next=q;                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=5;     printf("删除第%d个节点:",k);//删除第k个节点     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=head;             head=head->next;             free(q);             break;         } else {             if (k-1==n) {                 q=p->next;                 if (q) {                     p->next=q->next;                     free(q);                 }                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      printf("从小到大排序:");//从小到大排序     for (p=head,p1=NULL;p!=NULL;p1=p,p=p->next) {         for (q=p->next,q1=p;q!=NULL;q1=q,q=q->next) {             if (p->data > q->data) {                  //交换data //              printf("swap %02d %02d\n",p->data,q->data); //              t=p->data;p->data=q->data;q->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->data,q->data);                 if (p==head) {//p是头                     if (p->next==q) {//pq挨着                         head=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=head;                     } else {//pq不挨着                         head=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=head;                     }                 } else {//p不是头                     if (p->next==q) {//pq挨着                         p1->next=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=p1->next;                     } else {//pq不挨着                         p1->next=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=p1->next;                     }                 }                  //输出整个单链表 //              s=head; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表并计算链表长度n     n=0;     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         n++;         s=s->next;     }      printf("将整个链表逆序:");//将整个链表逆序     if (n>=2) {         p=head;         q=p->next;         p->next=NULL;         while (1) {             q1=q->next;             q->next=p;             p=q;             q=q1;             if (NULL==q) break;         }         head=p;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      m=4;     n=6;     printf("将单链表中前%d个结点和后%d个结点进行互换:",m,n);//将单链表中前m个结点和后n个结点进行互换,m+n为链表总长     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m==k) {             q=p;         }         s=p;         p=p->next;     }     q1=head;     head=q->next;     s->next=q1;     q->next=NULL;      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //创建10个节点的单链表:08->74->07->23->03->99->31->56->88->16-> //将值为5的结点插入到单链表的第3个结点前:08->74->05->07->23->03->99->31->56->88->16-> //删除第5个节点:08->74->05->07->03->99->31->56->88->16-> //从小到大排序:03->05->07->08->16->31->56->74->88->99-> //将整个链表逆序:99->88->74->56->31->16->08->07->05->03-> //将单链表中前4个结点和后6个结点进行互换:31->16->08->07->05->03->99->88->74->56-> //

void Sort(ID *h) {     ID *p1,*p2,*p3,*m,*p1prev;     char answer;     p2=NULL;     while(h->next!=p2)     {         p1=h;         p1prev=NULL; //p1前驱指针，头节点无前驱         while(p1->next!=p2 )         {             p3=p1->next;             if(strcmp(p1->style,p3->style)>0)             {                 if(p1prev)  //不是头节点，（是头节点时，交换前两个（边界情况））                     p1prev->next=p3;//删除p1                 p1->next=p3->next;                 p3->next=p1;                 m=p1;   p1=p3;   p3=m;             }             p1prev=p1;             p1=p1->next;             if(p1 == p2) break;//交换了最后两个（边界情况）         }         p2=p1;     }     printf("是否保存（Y(是)/N(否)--注意大小写）：");     scanf("%s",&answer);     if(answer=='Y')         Save(h);     return; }  若交换，则把p1，p3互换一下，应该可以解决这个问题  m=p1;   p1=p3;   p3=m;

还是有点问题啊0.0，这种排序应该类似冒泡吧，不是应该头比1,1比2,2比3的比较么？如果照这样来，假设节点1大于节点2，那么是交换了没错，那p1=p1->next;后p1不就是节点三了么？节点2节点3就没有比较。特意试了一下后发现并没有完全排好序哦。

malloc申请的空间中的内容不经过初始化之后是不确定的，strcpy函数进行是以‘\0’作为字符串结尾处理的，你的结构体中的字符数组没有初始化就使用，会出现越界，比如mail[20]中，原来所有20字节都不为0，则写入“33”时，只有前两个被写了“33”，后面还保持不变，这样strcpy的时候就会越界拷贝到next甚至更后面的数据，这样程序就出错了。 你的程序出现死循环，经调试看到了h->next=h->next->next,就是说h->next这个数据的next还是自身，无限循环了。  交换节点就是在链表中进行先删除后插入操作，加一个前驱指针就可以了。要注意边界情况处理 void Sort(ID *h) {     ID *p1,*p2,*p3,*m,*p1prev;     char answer;     p2=NULL;     while(h->next!=p2)     {         p1=h;         p1prev=NULL; //p1前驱指针，头节点无前驱         while(p1->next!=p2 )         {             p3=p1->next;             if(strcmp(p1->style,p3->style)>0)             {                 if(p1prev)  //不是头节点，（是头节点时，交换前两个（边界情况））                     p1prev->next=p3;//删除p1                 p1->next=p3->next;                 p3->next=p1;             }             p1prev=p1;             p1=p1->next;             if(p1 == p2) break;//交换了最后两个（边界情况）         }         p2=p1;     }     printf("是否保存（Y(是)/N(否)--注意大小写）：");     scanf("%s",&answer);     if(answer=='Y')         Save(h);     return; }

666，十分感谢，这个问题纠结了我几天了0.0，还有这是啥原理啊，为什么每次malloc后都要初始？为何不初始就会导致无限循环？如果把Sort中的交换换成交换节点又要怎么写？我试了好多也是错的，毕竟用strcpy数据多就不合适了。大神求教！

运行效果 为了截屏去掉了一些打印

我尝试了下，就是我开始说的，加 memset(p,0,(sizeof(ID)); 是所有malloc的地方都要加的，这样就OK了

前面的六个功能都可以用，就是排序有问题，无法排序，我加了几个输出语句来看运行到哪里，发现是while死循环了，没有出来0.0

程序哪一行报错，具体是什么错误？

试了，木有用啊0.0

可能跟你在Add和Create函数中malloc申请的空间没有清0有关 加个 memset(p,0,(sizeof(ID)); 试试


Question: 初学者关于数据结构中指针的疑问。

先来看个图（主要有两步）：  第一步： p->next = (*L)->next; 先看等号右边，取出L的next指针，这个next指针里存着一个地址（这个地址是第一个结点的地址） 将它赋值给p的next指针，那么此时L的next指针和p的next指针都指向了第一个结点 第二步：  (*L)->next = p; 这句将L的next指针存着的地址换成了p的地址，使得L的next指针指向了p 这样就完成了头部插入一个结点的操作  下面的CreateListTail原理也是一样的

指针变量相当于一个可以写字的纸条，指针p=xxx 相当于给纸条写了一个东西的地址（通过纸条里的地址可以访问到对应地址的东西），这个纸条可以擦了重写(p = yyy)，就是这样。慢慢想吧

把自己当计算机，严格按照程序，边画图边执行一遍，你就明白怎么回事儿。


Question: 如何将文本数据中的内容以二级制格式保存

问题解决了~res = (c1-'0')*16+c2-'0'本意应该是将读取的字符ASCII码表示形式恢复成数字表示。这对于不大于9的数字而言是可行的，但大于9的数字，如c，其ASCII值与数值并不是减48的关系。因此最后我才用了这种形式： switch(c1)           {             case 'a': tmp1=10;break;             case 'b': tmp1=11;break;             case 'c': tmp1=12;break;             case 'd': tmp1=13;break;             case 'e': tmp1=14;break;             case 'f': tmp1=15;break;           } 用tmp1来代替（c1-'0'），c2同理。最后问题完满解决。无论如何还是要感谢@Bealing  给支招！

引用 3 楼 bealing 的回复:[quote=引用 2 楼 bammo 的回复:] [quote=引用 1 楼 bealing 的回复:]  # Windows平台测试通过，linux下道理应该一样 #include<stdio.h>  int main() { 	char c1,c2,res; 	FILE *filer = fopen("C:/r.txt","r"); 	FILE *filew = fopen("C:/w.bin","wb"); 	 	if(filer == NULL || filew == NULL){ 		printf("打开失败");  		return 0; 	} 	//循环读取并转换  	while((c1 = fgetc(filer),c2 = fgetc(filer))!= EOF){ 		res = (c1-'0')*16+c2-'0'; //读取的数据是16进制的  		fprintf(filew,"%c",res); 	} 		 	fclose(filer); 	fclose(filew); 	 	return 0;  }    谢谢~ 测试后发现还有一点问题：如果读出的字符对应的十六进制小于等于9，如'5'，则按照你给出的方法可成功转换。但如果某字符对应的十六进制大于9，如'c'，其对应的ASCII值为0x63，减0x30，得到0x33，对应的是'3'。那么转换结果就错了。请问这种情况怎么处理呢？？[/quote] 文本文件中是以字符的ASCII码形式保存的，如下“353538396535”,如果你存在文本文档中的数据如你所说，那么你理解错了，'c'，其对应的ASCII值为0x63，存到文本文档中的值是字符串“63"，而不是数字，所以不是0x63减0x30，而是‘6’-‘0’=6，‘3’-‘0’=3，然后转换成6*16+3 = 0x63 = ’c‘[/quote] 下面是我利用十六进制编辑工具打开文本文档显示的内容：  如果按你所说，'c'存到文件中的值是字符串"63"，那么利用fgetc()一次读出的字符应该是'6'，然而实际情况却是'c'。ASCII码是一种编码形式，数据保存到文件中最终都是以二进制形式，也就是数字，而不是字符串吧？

引用 2 楼 bammo 的回复:[quote=引用 1 楼 bealing 的回复:]  # Windows平台测试通过，linux下道理应该一样 #include<stdio.h>  int main() { 	char c1,c2,res; 	FILE *filer = fopen("C:/r.txt","r"); 	FILE *filew = fopen("C:/w.bin","wb"); 	 	if(filer == NULL || filew == NULL){ 		printf("打开失败");  		return 0; 	} 	//循环读取并转换  	while((c1 = fgetc(filer),c2 = fgetc(filer))!= EOF){ 		res = (c1-'0')*16+c2-'0'; //读取的数据是16进制的  		fprintf(filew,"%c",res); 	} 		 	fclose(filer); 	fclose(filew); 	 	return 0;  }    谢谢~ 测试后发现还有一点问题：如果读出的字符对应的十六进制小于等于9，如'5'，则按照你给出的方法可成功转换。但如果某字符对应的十六进制大于9，如'c'，其对应的ASCII值为0x63，减0x30，得到0x33，对应的是'3'。那么转换结果就错了。请问这种情况怎么处理呢？？[/quote] 文本文件中是以字符的ASCII码形式保存的，如下“353538396535”,如果你存在文本文档中的数据如你所说，那么你理解错了，'c'，其对应的ASCII值为0x63，存到文本文档中的值是字符串“63"，而不是数字，所以不是0x63减0x30，而是‘6’-‘0’=6，‘3’-‘0’=3，然后转换成6*16+3 = 0x63 = ’c‘

引用 1 楼 bealing 的回复: # Windows平台测试通过，linux下道理应该一样 #include<stdio.h>  int main() { 	char c1,c2,res; 	FILE *filer = fopen("C:/r.txt","r"); 	FILE *filew = fopen("C:/w.bin","wb"); 	 	if(filer == NULL || filew == NULL){ 		printf("打开失败");  		return 0; 	} 	//循环读取并转换  	while((c1 = fgetc(filer),c2 = fgetc(filer))!= EOF){ 		res = (c1-'0')*16+c2-'0'; //读取的数据是16进制的  		fprintf(filew,"%c",res); 	} 		 	fclose(filer); 	fclose(filew); 	 	return 0;  }    谢谢~ 测试后发现还有一点问题：如果读出的字符对应的十六进制小于等于9，如'5'，则按照你给出的方法可成功转换。但如果某字符对应的十六进制大于9，如'c'，其对应的ASCII值为0x63，减0x30，得到0x33，对应的是'3'。那么转换结果就错了。请问这种情况怎么处理呢？？


Question: 给无参函数传参，没有return的函数返回值

1) int func(); 与 int func(void); 在 C 语言里得含义是不同的。 前者指声明 func 是一个函数，对参数未做任何约定。后者则表示该函数不接受任何参数。 [ 不适用于 C++ ] [ 这里说的是函数声明，不是定义 ]  2) 有返回值的函数，没有使用 return xxx; 返回一个值就结束运行，调用者又使用了这个返回值，那么这是一个未定义行为。 未定义行为可能产生任何结果，包括但不限于：产生期望的结果，产生未期望的结果，产生随机的结果，产生无法解释的结果，运行错误，随机的运行时错误，编译错误，等等

这种行为是未定义的，如果你想知道具体的可以看生成的汇编代码，通常是返回EAX的值，看当时EAX的值是多少函数很可能就返回多少

楼主一定要研究就看下汇编呗（这样没有返回值的VS都编译不过，楼主也不必太纠结结果） 第一个图标注的三行是调用int a = func(3);这句的  func函数：

特别强调下楼上的答案。不要写这种代码 Flowing off the end of a function is equivalent to a return with no value; this results in undefined behavior in a value-returning function

未定义行为，别这么干。费半天劲折腾明白了，换个编译器可能结果又不一样了。

在于func里面的printf的返回值引起的。里面的printf的返回值 被当成了func的返回值了。如果一个函数没有返回值，那么狠可能就直接用eax里面的值作为返回值，而eax存放的是func里面printf的返回值

至于printf的返回值是写入多少个字符，注意是多少个字符，所以你可以算下你写入的整数是多少个字符 加上换行符就答案了


Question: typedef     #ifdef    定义结构体成员变量

谢谢您的回答，目前已经解决了，按照您给我讲的最后一种方法。

这应该根据不同情况（硬件平台或者软件环境）， 做的不同处理  有些编译器，会根据平台选择，编译选项的选择，自动定义一些宏 这时候，TVREG_USEZ 就自动有了定义了，不需要手动定义 TVREG_USEZ 如果编译器本身，没有这个功能，可以在写makefile 的时候，定义宏  也可以把一些需要的宏定义写在单独的头文件中，需要的时候,#include 包含进去

////大约可以这么处理，前提是TVREG_USEZ的定义，有机会用到，不然代码写了，不编译，很难说这段代码是可用的 #ifdef TVREG_USEZ //定义了的处理代码     num *z = S->z;     num *ztilde = S->ztilde; .......................... #else  //没定义如何处理 ....................... #endif

想要 访问z， ztilde，结构体中要有定义，那就要定义TVREG_USEZ这个宏： #define TVREG_USEZ 在头文件开头加上这条宏

#ifdef TVREG_USEZ     num *z;                     /**< Current solution of z              */     num *ztilde;                /**< Bregman variable for z constraint  */ #endif  这样用意味着如果定义了TVREG_USEZ，那么有以下两个变量，显然没有定义过TVREG_USEZ 一般用都是 #ifndef #define #endif

#ifdef TVREG_USEZ     num *z;                     /**< Current solution of z              */     num *ztilde;                /**< Bregman variable for z constraint  */ #endif 看一下这个宏哪里定义的，定义了这个宏才会包含这两个成员变量，报错是说该成员变量未定义

根据这个.h和.c文件判断，我估计写出这个结构体（含有#if)的程序员很可能是打算实现一种C方式的模板。  要想使用该模板，可能项目中会有其他.c文件（或是需要你自己写出一个.c文件），其中的内容只有几行，大致为：  /* reg_usez_f1.c   */ #define TVREG_USEZ #define _FIDELITY 1    #include reg_resolver.c  // （假设模板文件是这个名字）注意是".c"的代码实现文件 #undef _FIDLITY  #undef TVREG_USEZ  注意不要编译作为模板的那个reg_resolver.c文件（IDE环境下，需要在工程设置中把该文件在编译选项中排除）


Question: 函数的局部变量释放问题

引用 楼主 s609727454 的回复:有如下代码: 1. int A(int a,int b)                       2. void A(int a,int b)                       3. int A(int &a,int &b)                       4. void A(int &a,int &b) 调用函数  A(c,d)后,上面四个函数的形参哪些会释放,哪些不会?(上面的1,3调用后不赋值给变量) 1,2会，34不会

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

你不觉得程序读写的是虚地址么... _(:3」∠)_

不要考虑那么多，只要了解参数传递方式，和引用 的含义就可以了 函数形参在函数结束，总是会解除内存占用的 然而引用 参数是所谓别名，他只是一个对象的替身。 对他执行的操作，都作用在那个对象上。 因此，引用参数解除内存占用，不影响对象的生命周期，以及操作结果。

理解和讨论之前请先学会如何观察！  计算机组成原理→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执行停在该断点处的时候。  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！

你这个释放的概念太模糊了， 怎么样叫释放？   如果是把释放定义为：把内存还给系统 那么，参数由于都是栈上的变量，函数调用完之后就是恢复现场，那都会释放  如果是把释放定义为：参数所对应的内存数据不再可用 那么对于1和2，由于是值传递，函数内对参数的修改不影响c，d的值，参数是释放掉了，不再可用 对于3和4，是引用传递，函数内对参数的修改是会影响c，d的值，参数是释放掉了，但是值是保留下来的

对于自动储存变量，并不会“释放”内存。 C++引入了对象概念后，自动储存变量“生命结束”后，会调用其析构函数


Question: 双基回文数问题

return 0;             break; ///这个是多余的，return 和 break 只需要一个即可 别的，没看出来有何问题，你是说别人都错了么？ 别人的代码 也贴过来看看才知道

a[i]!=a[n-i-1]; i=0时 a[n]就没了


Question: 指针运用问题，不知错误在哪里？

void findm(int *prow,int *qcol,int brray[][9],int *arrmax,int m,int n) { 	for (m=0; m<5; m++) 	{ 		for (n=0; n<9; n++) 		{ if(*arrmax<brray[m][n]) 		{ 			*arrmax=brray[m][n]; 			*prow=m; 			*qcol=n; 		}  		} 	} 	return; }

#include <stdio.h>  /* userCode(<80字符): 自定义函数之原型声明 */ void findm(int *prow,int *qcol,int brray[][9],int *arrmax,int i,int j);  int main(void) { 	int array[5][9], i, j, max, maxRow, maxCol;  	printf("Input matrix:\n"); 	for (i=0; i<5; i++) 	{ 		for (j=0; j<9; j++) 		{ 			scanf("%d", &array[i][j]); 		} 	}  	/* userCode(<80字符): 调用函数查找数组中最大元素及其所在位置的行下标、列下标 */ 	 findm(&i,&j,array,&array[0][0],i=0,j=0); 	printf("\nThe max is %d, row-sub is %d, col-sub is %d\n", max, maxRow, maxCol);  	return 0; }  /* User Code Begin：考生在此后完成自定义函数的设计，行数不限 */ void findm(int *prow,int *qcol,int brray[][9],int *arrmax,int i,int j) { 	for (i=0; i<5; i++) 	{ 		for (j=0; j<9; j++) 		{ if(*arrmax<*(arrmax+1)) 			{ 				*arrmax=*(arrmax+1); 				*prow=i; 				*qcol=j; 			}			 		} 	} 	return; }


Question: 新人求教

因为n=3时，由于是后++所以while(n++<=3)满足这个判断，之后执行循环体（此时n=4了，循环体为空） 然后此时再判断n++<=3（此时不满足），结束while循环（判断的时候又++了一次，n=5了，想必楼主是这里忽略了）

n++ 先用再加 n=3时，条件为true，此时n为4 n=4时，条件为false，此时n为5了，跳出while

++n 和 n++ 的区别


Question: 指针与局部变量生命周期的问题

内存释放并不会对内存清零。它只是说该段内存可以被其它地方使用了。如果该段内存被其它使用并改写，你打印的值就变了。（野指针也是指针，只是说他指向的内容有可能被其它地方改变）

楼主要验证应该改为(楼主之前这种i的作用域并不仅仅限于for循环)  int *a = NULL; for (int i=1; i<2; i++) {     int j = i;     a=&j; } printf("%d",*a);  说明： 指针指着一个生命周期结束的变量不仅可以访问，还可以修改，只不过这种访问是不确定的 局部变量的地址都是在程序自己的堆栈中，当局部变量结束后，只要没有将该局部变量的内存地址给别的变量，其值仍然存在。但如果修改的话，是比较危险的，因为这个内存地址可能给了程序的其它变量，通过指针强行修改的话，可能会引起程序崩溃


Question: 求助！为什么用double类型会出现这种问题，而用float就不会？

首先，你声明的是double型的变量a用来存放浮点类型的数据（也就是带有小数点的数据）。 但是呢，标准规定带小数点的字面值数据（就是你输入的数据）在缺省状况下都是double型的。 所以，你用%f的类型去存储你输入的double型数据就会出错误！(在这里，声明的变量类型和scanf里面的存储类型还有输入的数据类型三者要保持一致性)，应该把scanf里面的%f改为%lf，但是printf里面的%f就不用改也可以，也是行的。

输出的时候用%lf试试！！！


Question: c语言判断上三角矩阵和下三角矩阵

可以编写出来不？拜托

设行为i列为j判断i=j时是否都为0，然后判断i<j时有没有不是0的,有的话则为上三角，反之为下三角，只要2种情况都有的跳出，判断不是三角


Question: 纯C结构体问题

使用 DWORD 赋值，或者直接对这四个字节复制。

动态的 uchar  modulus[4];  要改成uchar*  modulus;


Question: 新人求问，在做例题，不懂为什么答案好像有点问题

还是不行，答案还是那样子

scnaf不要有其他东西   只要scanf("%f%f=%f",&a,&b,&c);就行了输入的时候一个一个回车就行或者空格

可以了，谢谢

#include <stdio.h> #include <math.h> void main() { 	double a, b, c, x1, x2, p, q, disc; 	scanf("%lf%lf%lf",&a, &b,&c); 	disc = b*b - 4 * a*c; 	q = sqrt(disc) / (2 * a); 	p = -b / (2 * a); 	x1 = p + q; 	x2 = p - q; 	printf("\nx1=%5.2f\nx2=%5.2f\n", x1, x2);  }

首先别加逗号输入的时候


Question: 数据结构，二进制转换到十进制，求高手帮看，谢谢

非常感谢你。

main函数的while循环后面多了一个分号，去掉就对了  while(c!='#'); //这里多了一个分号！！！！！！！！！！！！！！ { Push(&s,c); scanf("%c",&c); }


Question: C语言运算大量循环和MATLAB混合编程，编译通过，结果前面对，后面的错。单步调试，有指向，但是无执行。，若解决，有报酬

有大神可以帮我解决问题吗？


Question: 麻烦帮我分析下，我创建的链表不完整还是输出的问题

谢谢，知道了

h->next=p 改为 p=h。 不过我感觉你这样循环给链表加元素有点奇怪，我一般是创建个临时p指针移动到链表末尾，再创建新元素，添加到p指针的next域。

应当把s=(lnode*)malloc(sizeof(lnode));放到for循环里去

我知道是没有申请空间的缘故，但是现在我想问一下，输出时为什么总会输出头节点的数据


Question: PAT c语言简单编程错误求助

不同的oj不同，一般来说和你在控制台又输入又输出不同，一些oj平台，stdin和stdout是分开的。 可能题目想让你这样输入和输出： 4 1 2 3 Case #1: false 2 3 4 Case #2: true 2147483647 0 2147483646 Case #3: true 0 -2147483648 -2147483647 Case #4: false

for里面的i换成j试试


Question: C语言中的switch问题

引用 10楼我是你的主体 的回复:[quote=引用 9 楼 qq423399099 的回复:] 楼主要清理输入缓冲区 scanf("%c",&k);前面加一句fflush(stdin); 问题解决了。多谢了。 对了，这个应该不需要在后面的程序再加一次了吧[/quote]用%c读取要注意之前输入缓冲区遗留下来的字符，特别是之前输入遗留下的回车符

引用 9 楼 qq423399099 的回复:楼主要清理输入缓冲区 scanf("%c",&k);前面加一句fflush(stdin); 问题解决了。多谢了。 对了，这个应该不需要在后面的程序再加一次了吧

引用 6 楼 qq423399099 的回复:[quote=引用 5 楼 ai977313677 的回复:] [quote=引用 2 楼 user-2 的回复:] case 0: 改成 case ‘0’:   其他的case同样改了  数值与数字字符是不同的 改正之后他还是会跳过这一段程序，直接到下一段程序了[/quote] 建议楼主再贴一下代码[/quote] 这个有办法解决吗？

这是整个完整的程序 #include <stdio.h> #include <string.h> #include <stdlib.h> #define LEN 20 #define length sizeof(struct drugs)  enum tuse {for_extern_use,take_orally}; //枚举药品的用法  enum ttype {pill_for_cold,stomachace_medicine,antiphlogistic_drug,eyedrop}; //枚举药品类型  struct Usage {     char dosage[LEN];  //一次用量 }; //药品的使用方法  struct Drugs {     char name[LEN];     int num[LEN];     char date_PD[LEN];     char date_VD[LEN];     char date_Exp[LEN];     enum ttype type;     enum tuse use;     char usage[LEN];     struct Drugs *next; }; //药品的主要信息  /*引导录入药品相关信息*/   struct Drugs  inputdrug(void) {     char choose[5];     struct Drugs medicine;     char r,k;     printf("***新的药品***\n");     printf("请输入药品名:");     scanf("%s",medicine.name);                                      //药品名     printf("\n请输入药品编号(12位):");     scanf("%12d",medicine.num);                                     //药品编号     printf("\n该药品是否具有生产日期信息(yes or no):");     scanf("%s",&choose);     if(strcmp(choose,"yes")==0)     {         printf("\n请输入生产日期:");         scanf("%s",medicine.date_PD);     }         else if((strcmp(choose,"no"))==0)         {             printf("该药品的生产日期信息暂缺\n");             strcpy(medicine.date_PD,"lost");         }                                    //生产日期     printf("\n该药品是都否具有有效期信息(yes or no):");     scanf("%s",&choose);     if(strcmp(choose,"yes")==0)     {         printf("\n请输入有效期:");         scanf("%s",medicine.date_VD);     }         else if((strcmp(choose,"no"))==0)             {                 printf("该药品的有效期信息暂缺\n");                 strcpy(medicine.date_VD,"lost");             }                                   //有效期     printf("\n该药品是否具有失效日期信息(yes or no):");     scanf("%s",&choose);     if(strcmp(choose,"yes")==0)     {         printf("\n请输入失效日期:");         scanf("%s",medicine.date_Exp);     }          else if((strcmp(choose,"no"))==0)         {              printf("该药品的失效日期信息暂缺\n");              strcpy(medicine.date_Exp,"lost");         }                                  //失效日期     printf("\n请选择药品类型(0:感冒药，1:胃药，2:消炎药，3:眼药水):");     scanf("%c",&k);     switch (k)     {         case '0': medicine.type=pill_for_cold;break;         case '1': medicine.type=stomachace_medicine;break;         case '2': medicine.type=antiphlogistic_drug;break;         case '3': medicine.type=eyedrop;     }                                                  //药品种类     printf("\n请选择使用方法(0:口服,1:外用):");     scanf("%c",&r);     switch (r)     {         case '0': medicine.use=take_orally;break;         case '1': medicine.use=for_extern_use;     }                                                 //用法     printf("\n请输入用量(一次):");     scanf("%s",medicine.usage);                                                 //用量 };   /*输出某个药品信息*/  void print_out(struct Drugs * drug0) {     printf("****药品信息如下****");     printf("\n药品名:%s",drug0->name);     printf("\n药品编号:%d",drug0->num);     printf("\n生产日期:%d",drug0->date_PD);     printf("\n失效日期:%d",drug0->date_Exp);     printf("\n有效期:%D",drug0->date_VD);     printf("\ntype:");     switch (drug0->type)     {         case pill_for_cold : printf("感冒药\n");break;         case stomachace_medicine : printf("胃药\n");break;         case antiphlogistic_drug : printf("消炎药\n");break;         case eyedrop : printf("眼药水\n");     }     printf("\n用法:");     switch (drug0->use)     {         case for_extern_use : printf("外用\n");break;         case take_orally : printf("口服\n");     }     printf("用量:",drug0->usage); }  int main () {     inputdrug();     search();     return 0; }  然后出问题的程序是 printf("\n请选择药品类型(0:感冒药，1:胃药，2:消炎药，3:眼药水):");     scanf("%c",&k);     switch (k)     {         case '0': medicine.type=pill_for_cold;break;         case '1': medicine.type=stomachace_medicine;break;         case '2': medicine.type=antiphlogistic_drug;break;         case '3': medicine.type=eyedrop;     } 这一段

引用 5 楼 ai977313677 的回复:[quote=引用 2 楼 user-2 的回复:] case 0: 改成 case ‘0’:   其他的case同样改了  数值与数字字符是不同的 改正之后他还是会跳过这一段程序，直接到下一段程序了[/quote] 建议楼主再贴一下代码

引用 2 楼 user-2 的回复:case 0: 改成 case ‘0’:   其他的case同样改了  数值与数字字符是不同的 改正之后他还是会跳过这一段程序，直接到下一段程序了

楼上正解，还要保证你的k是char类型的 或者就要%d来读，k也变成int k

刚才按你说的改了一下，但是这个就算是改成字符型的，他还是会直接跳过这段代码直接运行下一段

然后运行的时候这段程序只会出现这个信息，也就是说运行会跳过这段程序，这是什么原因


Question: 语法错误

引用 1 楼 merry_zsp 的回复:原来是一个宏定义错了o(╯□╰)o 哈哈，怪不得在楼主的代码里找不到>也找不到<

原来是一个宏定义错了o(╯□╰)o


Question: scanf的值作为循环条件,while语句造成死循环

不要使用 while (条件) 更不要使用 while (组合条件) 要使用 while (1) {  if (条件1) break;  //...  if (条件2) continue;  //...  if (条件3) return;  //... } 因为前两种写法在语言表达意思的层面上有二义性，只有第三种才忠实反映了程序流的实际情况。 典型如： 下面两段的语义都是当文件未结束时读字符 while (!feof(f)) {  a=fgetc(f);  //...  b=fgetc(f);//可能此时已经feof了！  //... } 而这样写就没有问题： while (1) {  a=fgetc(f);  if (feof(f)) break;  //...  b=fgetc(f);  if (feof(f)) break;  //... } 类似的例子还可以举很多。

如果输入整数 + - 是数的一部分 ，而字符不是  如果输入浮点数 e 也可能会读走

因为你要读取的是数字，输入一个字符时， scanf函数会失败，但是这个字符还在流里面没有被读出来，所以就死循环动不了了；而getchar（）函数是读字符的，scanf函数失败，但是字符会被getchar（）函数从流里面读出来 scanf它要跳过所有非数字的字符专接收数字。那么输入了字符它就一直留在输入缓冲区；只要缓冲区有字符，scanf就要去读，一读不是数字，它就跳过，试图等到输入缓冲区没有字符了才等待你输入……如此反复，当然就“死循环”了。 至于输入+-号，我试了下，哈哈真的被读走了，但是并没有被读到a,b,c变量里，但确实真的从输入缓冲区里消失了 当使用scanf函数时，如果遇到一些匪夷所思的问题，在scanf函数后正确使用fflush(stdin);，清空输入缓冲区，可以解决很多问题。


Question: 递归和回溯有什么区别

没人回答新人吗？


Question: 一个关于简单实验数据处理的程序，求助！

楼主创建一个数组保存每个输入的数字就好了，我这里是用malloc加上int *指针来保存的  #include<stdio.h> #include<iostream> using namespace std;  void main(int argc, char *argv[]) { 	double a,sum,average; 	int i,n,*m; 	printf("个数："); 	scanf("%d", &n); 	m = (int *)malloc(sizeof(int)*n); 	for(i=1,sum=0; i <=n; i++) 	{ 		printf("请输入第%d个数据:", i); 		scanf("%lf", &a); 		sum=sum+a; 		*(m+i-1) = a; 	} 	average=sum/(i-1); 	printf("Sum:=%.3f\n",sum); 	printf("Average=%.3f\n",average); 	for(i=0;i<n;i++) 		printf("第%d个数与平均数的差值为:%lf\n", i+1, *(m+i)-average); }


Question: 求大神！！！！！！！！！！！！！！新人

楼主最后面printf("% c\n",b);改为printf("%c\n",b[0]);就能输出i了 不要用%c去输出一个字符数组

#include<stdio.h> void main() {     int i=0,a[12],m=0,n,j=0;     char b[100];     printf("请你输入12个整数：\n");//提示信息     for(i=0;i<12;i++)//循环输入     {         scanf("%d",&a[i]);     }     for(i=0;i<12;i++)     {         if(a[i]>a[m])         {              m=i;         }     }     printf("最大的数为%d\n",a[m]);     for(i=0;i<12;i++)     {         if(a[i]==a[m])         {             for(j=0;j<100;j++)             {                b[j]='i';                break;             }         }     }     printf("其下标为:");     printf("% c\n",b); }


Question: 指针问题

如果a是int*类型，b要指向他，那么b需要是int**，a如果要指向b，a应该是int***，除非强制类型转换

类型错误, int *a,*b. &b类型是int**, 不能赋予a,换成void*即可, 但是void*类型不能使用*单目运算符


Question: 出队列函数

谢谢，可能dequeue函数在其他地方已经定义了，且在函数里面w被赋值为队头元素

因为队列结构中一般有以下两个变量 int head, tail;  //队列的头和尾下标 head的数值表示当前队首元素的编号，自然能够通过w带出来啊。。。。

参数是指针，可以修改函数外的变量，所以结果能带出来。 话说这接口设计的真费劲啊，直接 return int 更方便。


Question: const void* 赋值给void*的问题

没人给答案，算了，自己摸索把。

刚才网页特别卡，写的也不太明确。 类似char* 我对const char×的处理是： int len = strlen(str); char* newstr = (char*)malloc(sizeof(char) * len); strcpy(newstr,str); 这是我对常量字符串的赋值做的复制赋值， 但是对const void×如何做类似处理不太知道。 我知道对常量是不能改变的，但复制出来后，就是可变的了。 void*如何做呢？

引用 4 楼 tommir3 的回复:[quote=引用 3 楼 adusuccessfully 的回复:] [quote=引用 2 楼 tommir3 的回复:] 其实可以转换一下， void* value = (void*)val; 可以使用的，但是如果向修改值是不可以的？  我还向问的是，如果向改变成可修改的，如何把val复制出一份给value  如果想修改就将int myFunction(const void* val)声明为int myFunction(void* val)   [/quote]   改动函数传入参数和Node结构的前提下，如何修改/？[/quote]  楼主问得是不改动函数传入参数和Node结构的前提下，如何修改把？  const int * p表示const修饰*p，指针p指向的内容（既*p）不能改变； int * const p表示const修饰p， 指针p的地址不能改变，但指向的内容可以改变；

引用 3 楼 adusuccessfully 的回复:[quote=引用 2 楼 tommir3 的回复:] 其实可以转换一下， void* value = (void*)val; 可以使用的，但是如果向修改值是不可以的？  我还向问的是，如果向改变成可修改的，如何把val复制出一份给value  如果想修改就将int myFunction(const void* val)声明为int myFunction(void* val)   [/quote]   改动函数传入参数和Node结构的前提下，如何修改/？

引用 2 楼 tommir3 的回复:其实可以转换一下， void* value = (void*)val; 可以使用的，但是如果向修改值是不可以的？  我还向问的是，如果向改变成可修改的，如何把val复制出一份给value  如果想修改就将int myFunction(const void* val)声明为int myFunction(void* val)

看void* value;会不会修改它所指向的内存，如果不会就声明为const void* value; 如果会，就把int myFunction(const void* val)声明为int myFunction(void* val)


Question: 关于随机产生10道运算的题目，大家帮我看下哪里出错了行吗？

default,,,break

引用 5 楼 qq423399099 的回复:楼上正解，下面来解释下为什么scanf("%d\n\n",&c);这样的是不行的 空白字符会使scanf()函数在读操作中略去输入中的一个或多个空白字符，空白符可以是space,tab,newline等等，直到第一个非空白符出现为止。（换句话来说就是\n在scanf中不表示等待换行符，而是读取并放弃连续的空白字符,直到下一个非空白符出现为止） 试了下果然可以，谢谢拉

引用 2 楼 adusuccessfully 的回复:看了一会儿，还单步跟调试了下，好像第一次遇到scanf要输入两次，才进入下一句。可能与scanf接收参数有关吧，具体说不清是为啥……  我将scanf换了C++中的cin没有输入两次的问题：  #include<stdio.h> #include<stdlib.h> #include<time.h> #include<iostream> using namespace std; void main() { 	int k,i,a,b,c,sum;//声明变量k,i,a,b,c,sum  	i = 1; 	c = 0; 	sum = 0;  	while(i<=10) 	{ 		srand(time(0)); 		k = rand()%(4-1+1)+1;	//从1到4中取一个随机数k  		a = rand()%(10-1+1)+1;	//从1到10中取一个随机数a  		b = rand()%(10-1+1)+1;	//从1到10中取一个随机数b   		switch (k) 		{ 		case 1: printf("问题%d: %d + %d 等于多少?\n",i,a,b);//随机数a+随机数b的和是多少  			cin>>c;	 //输入答案  			break; 		case 2: printf("问题%d: %d - %d 等于多少?\n",i,a,b);//随机数a+随机数b的差是多少 			cin>>c;//输入答案  			break; 		case 3: printf("问题%d: %d * %d 等于多少?\n",i,a,b);//随机数a+随机数b的积是多少 			cin>>c;//输入答案  			break; 		default:printf("问题%d: %d / %d 等于多少?\n",i,a,b);//随机数a+随机数b的商是多少 			cin>>c;//输入答案  		} 		printf("你的输入的答案为:%d\n",c);//打印每次输入的答案   		if(c == a + b||c == a - b||c == a * b||c == a / b)  		{ 			printf("答对了，你真聪明！\n"); 			sum = sum+10;	 //每答对一题加10分  		} 		else 			printf("答错了，请继续努力\n");  		i++;	 	} 	printf("你的总成绩为%d",sum); //答题总分  }  另 楼主定义的变量，最好都初始化下。 变量初始化，怎讲？ 初始化了怎么产生随机数？

去掉scanf里的所有\n

1 #include<stdio.h>   2 #include<stdlib.h>   3 #include<time.h>   4                 5                 6 int main(void)   7 {               8                 9     int k,i,a,b,c,sum;//声明变量k,i,a,b,c,sum  10     i = 1;     11     sum = 0;   12                13                14     while(i<=10) {  15     |   srand(time(0));  16     |   k = rand()%(4-1+1)+1; //从1到4中取一个随机数k  17     |   a = rand()%(10-1+1)+1; //从1到10中取一个随机数a  18     |   b = rand()%(10-1+1)+1; //从1到10中取一个随机数b  19                20     |   switch (k)  21     |   {      22     |   |   case 1: printf("问题%d: %d + %d 等于多少?\n", i, a, b);//随机数a+随机数b的和是多少  23     |   |   scanf("%d",&c);    //输入答案     24     |   |   break;  25     |   |   case 2: printf("问题%d: %d - %d 等于多少?\n",i,a,b);//随机数a+随机数b的差是多少  26     |   |   scanf("%d",&c);      //输入答案   27     |   |   break;  28     |   |   case 3: printf("问题%d: %d * %d 等于多少?\n",i,a,b);//随机数a+随机数b的积是多少  29     |   |   scanf("%d",&c);      //输入答案   30     |   |   break;  31     |   |   default:printf("问题%d: %d / %d 等于多少?\n",i,a,b);//随机数a+随机数b的商是多少  32     |   |   scanf("%d",&c);        //输入答案  33     |   |   break;                                                                                34     |   }      35     |   printf("你的输入的答案为:%d\n",c);//打印每次输入的答案  36                37                38                39     |   if(c == a + b||c == a - b||c == a * b||c == a / b)  40     |   {      41     |   |   printf("答对了，你真聪明！\n");   42     |   |   sum = sum+10; //每答对一题加10分  43     |   }       |   else  45     |   |   printf("答错了，请继续努力\n");  46       47     |   i++;  48     }  49              50     printf("你的总成绩为%d",sum); //答题总分  51     return 0;  52 }

看了一会儿，还单步跟调试了下，好像第一次遇到scanf要输入两次，才进入下一句。可能与scanf接收参数有关吧，具体说不清是为啥……  我将scanf换了C++中的cin没有输入两次的问题：  #include<stdio.h> #include<stdlib.h> #include<time.h> #include<iostream> using namespace std; void main() { 	int k,i,a,b,c,sum;//声明变量k,i,a,b,c,sum  	i = 1; 	c = 0; 	sum = 0;  	while(i<=10) 	{ 		srand(time(0)); 		k = rand()%(4-1+1)+1;	//从1到4中取一个随机数k  		a = rand()%(10-1+1)+1;	//从1到10中取一个随机数a  		b = rand()%(10-1+1)+1;	//从1到10中取一个随机数b   		switch (k) 		{ 		case 1: printf("问题%d: %d + %d 等于多少?\n",i,a,b);//随机数a+随机数b的和是多少  			cin>>c;	 //输入答案  			break; 		case 2: printf("问题%d: %d - %d 等于多少?\n",i,a,b);//随机数a+随机数b的差是多少 			cin>>c;//输入答案  			break; 		case 3: printf("问题%d: %d * %d 等于多少?\n",i,a,b);//随机数a+随机数b的积是多少 			cin>>c;//输入答案  			break; 		default:printf("问题%d: %d / %d 等于多少?\n",i,a,b);//随机数a+随机数b的商是多少 			cin>>c;//输入答案  		} 		printf("你的输入的答案为:%d\n",c);//打印每次输入的答案   		if(c == a + b||c == a - b||c == a * b||c == a / b)  		{ 			printf("答对了，你真聪明！\n"); 			sum = sum+10;	 //每答对一题加10分  		} 		else 			printf("答错了，请继续努力\n");  		i++;	 	} 	printf("你的总成绩为%d",sum); //答题总分  }  另 楼主定义的变量，最好都初始化下。   引用 1 楼 hui1989718 的回复:default,,,break  我试过了，不是default,,,break问题


Question: C语言结构体和返回值问题

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

出错时点中断，通过调用堆栈、变量窗口等观察分析原因


Question: 大家好，有个软件里面的文本信息，只能用鼠标框选后右键，然后点击跳出的复制选项，但不能用快捷键Ctrl+C复制,经常用..这样很麻烦,请问...

引用 4 楼 u010165006 的回复:要编写代码，判断这个信息窗口当按下Ctrl+C时，复制文本到剪贴板。   求大神给个方向

是不是不能额...

要编写代码，判断这个信息窗口当按下Ctrl+C时，复制文本到剪贴板。

我是不是该结贴了...来个大神拯救我..

果然没办法吗...


Question: 想问下，if语句里的下标是如何变化的，我的想法是当p=0时*k=0，这样的话就没法比较啦？

建议单步跟踪程序运行，每一步看各变量的值，这样你的收获会更大

不清楚你的代码要做什么

for循环，第一次循环确实不用比，因为两者是相等的，但是它之后只执行p++ （我猜楼主是理解成指针一直指着p了对吧，它是*k=p,所以仅仅只是改变k原来所指向的空间内的值使其值等于p，k指针并不是指着p的）


Question: 右边的是什么窗口？window系统下哪里下载？名字？

引用 6 楼 zhao4zhong1 的回复:现在的码农竟然99%都不会在cmd窗口中输入cd命令设置当前目录为程序所在目录，输入程序名运行程序了！ 要不老赵写个简单的教程？

引用 3楼ooolinux 的回复:引用 2 楼 labuboco 的回复:[quote=引用 1楼user-3 的回复:]窗口是terminal.app，运行的是bash。如果想在windows下获得类似的体验，可以使用MinGW或者Cygwin可以用自带运行cmd解决argv的调用问题么 在Win7下假如你用VC，假如你的程序目录在D:\C\151023_t2，可执行文件在D:\C\151023_t2\Debug，你在资源管理器窗口里打开D:\C\151023_t2文件夹，按住Shift键然后右键点击Debug文件夹，出现右键菜单，选择【在此处打开命令窗口】，就出现一个黑色的命令行窗口，输入：dir【回车】可以看到 151023_t2.exe ，输入：151023_t2【回车】可以运行这个程序，输入：151023_t2  aa  bbb【回车】可以带参数运行这个程序，aa和bbb就是两个参数。[/quote]谢谢哥们儿，互加个好友吧

引用 4 楼 labuboco 的回复:引用 3楼ooolinux 的回复:[quote=引用 2 楼 labuboco 的回复:] [quote=引用 1楼user-3 的回复:]窗口是terminal.app，运行的是bash。如果想在windows下获得类似的体验，可以使用MinGW或者Cygwin可以用自带运行cmd解决argv的调用问题么 在Win7下假如你用VC，假如你的程序目录在D:\C\151023_t2，可执行文件在D:\C\151023_t2\Debug，你在资源管理器窗口里打开D:\C\151023_t2文件夹，按住Shift键然后右键点击Debug文件夹，出现右键菜单，选择【在此处打开命令窗口】，就出现一个黑色的命令行窗口，输入：dir【回车】可以看到 151023_t2.exe ，输入：151023_t2【回车】可以运行这个程序，输入：151023_t2  aa  bbb【回车】可以带参数运行这个程序，aa和bbb就是两个参数。[/quote]谢谢哥们儿，互加个好友吧[/quote]  我不经常在线，有问题来论坛是最好的。

引用 2 楼 labuboco 的回复:引用 1楼user-3 的回复:窗口是terminal.app，运行的是bash。如果想在windows下获得类似的体验，可以使用MinGW或者Cygwin可以用自带运行cmd解决argv的调用问题么 在Win7下假如你用VC，假如你的程序目录在D:\C\151023_t2，可执行文件在D:\C\151023_t2\Debug，你在资源管理器窗口里打开D:\C\151023_t2文件夹，按住Shift键然后右键点击Debug文件夹，出现右键菜单，选择【在此处打开命令窗口】，就出现一个黑色的命令行窗口，输入：dir【回车】可以看到 151023_t2.exe ，输入：151023_t2【回车】可以运行这个程序，输入：151023_t2  aa  bbb【回车】可以带参数运行这个程序，aa和bbb就是两个参数。


Question: 在VC中研究C语言库函数

alloc.h 是C语言标准库中的,在VC的自带库中不包含这个头文件库  但是在VC下用 malloc.h 或者stdlib.h就能用了  因为stdlib.h是包含alloc.h的全部功能

http://www.cplusplus.com/search.do?q=allocmem  标准库没有搜到这个函数


Question: 如何在写入含有特殊符号的多行字符串时，对其进行分割

先使用 strrpl 替换掉不需要的字符 再使用 strtok 分割

多行的自然按照‘\n’分割， ascii码随便用什么分


Question: 求大神讲解两个循环的差异  运行结果完全不同啊

区别在于for循环先判断是否为'\0'然后再复制，while循环先复制然后再判断，这样for循环就无法复制最后的'\0'，造成字符串没有正确的结束。


Question: C语言printf奇葩问题

引用 11 楼 lm_whales 的回复:这种函数，有两个方法较常用 1）传递两个指针a，b（表示两个字符串），实际是字符数组 把 结果放入中返回 2）直接把结果放入 a中，只传递一个字符串，要求不能使常量串，操作时注意别删错了，设计好算法，别出错了 注意结束符的处理 PS： C返回字符串的函数，一般都是返回形参指针 也可以返回动态分配的字符数组指针，这要求用毕释放之 也可以返回静态数组（内容为字符串，有时可以返回常量字符串）； 有时候，返回外部变量数组也可以，但是不是很好 1） 传递两个指针a，b（表示两个字符串），实际是字符数组 把 结果放入b中返回

野指针，造成的

引用 8 楼 zhao4zhong1 的回复:理解和讨论之前请先学会如何观察！  说的好，这个问题完全可以自己搞明白的，楼主要加强分析问题的能力。

理解和讨论之前请先学会如何观察！  计算机组成原理→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执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）

引用 3 楼 liehu232的回复:b为栈上分配，函数返回后被回收，应该用char *b=(char *)malloc(20*sizeof(char))改为堆上分配 为什么主函数里把注释去掉而子函数不动就可以了，

引用 6 楼 qq_20218109 的回复:[quote=引用 3 楼 liehu232的回复:]b为栈上分配，函数返回后被回收，应该用char *b=(char *)malloc(20*sizeof(char))改为堆上分配 为什么主函数里把注释去掉而子函数不动就可以了，[/quote]  我上面说的不确定包括：结果是你想要的 与 结果不是你想要的

不要返回局部变量的地址，因为函数结束完变量生命周期就结束了，之后的行为是不确定的

返回的是局部变量，那么其结果是未知的，存在不确定性；

因为你返回了一个局部变量指针的地址（位于栈区），楼主应该new或者malloc出一个空间，然后返回 应该改为如下这样：  char *spcpy(char *a,char c) {     int i=0;     int j=0;     char b[20]={'\0'};     for(;i<strlen(a);++i)     {         if(a[i]!=c)         {             b[j]=a[i];             ++j;         }     } //    printf("%d",i);    // printf("修改后的字符串为：%s\n",b);     char *p=(char *)malloc(20); 	strcpy(p, b);     return p; }

局部变量退出作用域即失效，永远不要返回指向自动局部变量的指针。


Question: extern C语言中外部变量和的一些疑惑

另外图2可能是错误的

经过一段时间的学习，觉得自己似乎知道了问题的答案。 答案就在2#、3#； 再次感谢各位！！！

楼上只看到了void main()，却没有看到我具体的问题，是否因为你心里只有void main呢？我的原问题也不是出在上图上，只不过我觉得我只需要把我的症结提取出来，明确自己的问题所在，才能让喜欢分享知识的人对我的问题一目了然，而不是花更多的无用的时间在理解我的其他代码上，谢谢

看到void main我就知道一切白说。

大神的眼界果然不同凡响，小白有点懂但似乎又不太懂，能否通过上图细讲一二？

全部是弱符号，任取一个作为定义 多个强符号，重复定义错误

另外，编译器还有强符号与弱符号的分别，来区分声明和定义 有初始化的，是强符号 无初始化的，是弱符号

纯粹的声明，好处是只有一处定义，不会出现定义不一致之处  声明 和定义写在一起，好处是 看到声明就知道定义 坏处是 ，可能出现定义不一致，特别是不同文件，都这样写的时候  至于编译器，如果见到定义，那就会忽略声明 如果有两处不同定义，那就会报错 如果相同，可能回都接受吧， 最多也就是报错 其实任取一处 ，作为定义即可。


Question: 这个程序输出有问题

楼主你那句scanf_s不能这样用，直接用%s读会读到输入的字符串末尾的，并不会读到那个逗号而停下来，其实你的&a[i].score根本没有赋上值。 逗号以及score值全部读到name数组里了，可以改成以下这样（%[^,]意思是匹配字符串直到遇见逗号)  scanf_s("%d,%[^,],%d", &a[i].num, a[i].name,10, &a[i].score);


Question: 对称数问题

嗷嗷嗷，忘了打了，题目有限制，就是最多6位，所以才这么写 引用 3 楼 qq423399099 的回复:楼主你这里定义int a[6]; 一旦输入进来的数大于6位，下面判断a[--n]!=a[i]就会造成越界

代码有的用例不通过，所以想知道问题在哪，我也知道其他类型的正确代码，所以不用贴自己写的代码了谢谢大家

bool isdc(int init){     int temp=init;     int a[6];     int n=0;     while(temp/10!=0){       a[n]=temp%10;       n++;       temp=temp/10;     }        a[n]=temp%10;       n++;      for(int i=0;i<n;i++){printf("%d",a[i]);}      printf(" %d\n",n/2);      for(int i=0;i<n/2;i++){       if(a[--n]!=a[i]) return 0;    }         return 1;   }


Question: 照着课本打的却编译不了，求助!

错的离谱，哪有函数写在主函数里面的

但是我想知道什么问题？

这种教科书让人心寒，这是什么编程习惯？！


Question: 多项式相加  求改进

楼主的判断条件有问题吧？？while(p1==NULL&&p==NULL)，指针为空进入循环体，程序运行就出错了……


Question: 如何在链表中输入元素？

谢谢你的帮助，我知道怎么做了

仅供参考：#include <stdio.h> int main() {     int a,b,n,v,r,k;     char buf[80];     char *p;      k=0;     r=EOF;     while (1) {         if (EOF==r) {             fgets(buf,80,stdin);             p=buf;         }         while (1) {             r=sscanf(p,"%d%n",&v,&n);             if (1==r) {k++;break;}             if (EOF==r) break;             p++;         }         if (EOF==r) continue;         p+=n;         if (1==k) a=v;         if (2==k) {             b=v;             break;         }     }     printf("%d,%d\n",a,b);     return 0; }

………你没懂我的意思…

引用 2 楼 xd15010130025 的回复:那应该怎么循环输入呢…  for   while

int a; 	scanf("%d", &a);

那应该怎么循环输入呢…


Question: 字符串数组是怎么分配存储空间的？

引用 2楼小灸舞 的回复:常量字符串是放在常量区的，该区是只读，你不能通过指针企图修改该区域的字符串内容 如"abcdefg"，字符串中是7个字符，但默认都会在末尾加一个'\0'来表示结束，所以一共占的空间就是8个字节 楼主可以用sizeof验证每个字符串的存储空间多大

默认后面再加一个0，他们的内存都放在只读区域


Question: 关于字符型读入的问题

以下这种方式读入的话：  scanf("%c%c%c", &a ,&b, &c);  如果输入了a b n (那么a会读到a,b会读到空格，c会读到b) 要正确读入的话要输入abn(中间不要加空格)

你按回车时的换行符\n会被接收为一个字符，导致结果不对

因为%c不会跳过起始的空白字符，所以不带空格的实际读入的a,b,c是a，空格，b，最大值就是b

你在scanf后面加一条输出a,b,c语句试一下


Question: 心好累啊

写程序要保证基本的输入是正确的，scand()的参数是指针，取的是地址，所以while循环中scanf()函数的参数&day，错误应该解决，这是初学经常犯的错误，希望能帮到你


Question: 数组就是在内存中开辟一块连续的、大小相同的空间，用来存储数

引用 7 楼 labuboco 的回复:[quote=引用 6楼sdghchj 的回复:][quote=引用 4 楼 labuboco 的回复:] [quote=引用 3楼sdghchj 的回复:]这个问题我竟无言以对。 int a[10]难道不是10个相同空间大小的int类型变量么？我想问的是字符串数组是怎么分配存储空间的例如"123445","12","12344667"[/quote] 字符串数组一般是用二维的字符数组来装，如char[5][10]表示是5个最多能存储10个字符的字符串，各字符串都是10个字节，只不过print出来的时候遇到终止符就不打印了而已，但内存依旧是那么多。 即便是标准库的string类型，也是内部有一个字符指针指向申请的其它地址上的字节，string本身的大小依然是固定的。总之，相同类型的变量所占字节数就是一样的。[/quote]可是有的书上写的[][]代表行和列？什么情况[/quote] 是行和列，但你要深层次理解c\c++里所谓的字符串，本质上就是字符数组，以终止符‘\0’来默认表示字符串结束。

引用 9楼sdghchj 的回复:[quote=引用 7 楼 labuboco 的回复:] [quote=引用 6楼sdghchj 的回复:][quote=引用 4 楼 labuboco 的回复:] [quote=引用 3楼sdghchj 的回复:]这个问题我竟无言以对。 int a[10]难道不是10个相同空间大小的int类型变量么？我想问的是字符串数组是怎么分配存储空间的例如"123445","12","12344667"[/quote] 字符串数组一般是用二维的字符数组来装，如char[5][10]表示是5个最多能存储10个字符的字符串，各字符串都是10个字节，只不过print出来的时候遇到终止符就不打印了而已，但内存依旧是那么多。 即便是标准库的string类型，也是内部有一个字符指针指向申请的其它地址上的字节，string本身的大小依然是固定的。总之，相同类型的变量所占字节数就是一样的。[/quote]可是有的书上写的[][]代表行和列？什么情况[/quote] 是行和列，但你要深层次理解c\c++里所谓的字符串，本质上就是字符数组，以终止符‘\0’来默认表示字符串结束。[/quote]可是\0又不是换行符，为什么要换行啊，

引用 6楼sdghchj 的回复:[quote=引用 4 楼 labuboco 的回复:] [quote=引用 3楼sdghchj 的回复:]这个问题我竟无言以对。 int a[10]难道不是10个相同空间大小的int类型变量么？我想问的是字符串数组是怎么分配存储空间的例如"123445","12","12344667"[/quote] 字符串数组一般是用二维的字符数组来装，如char[5][10]表示是5个最多能存储10个字符的字符串，各字符串都是10个字节，只不过print出来的时候遇到终止符就不打印了而已，但内存依旧是那么多。 即便是标准库的string类型，也是内部有一个字符指针指向申请的其它地址上的字节，string本身的大小依然是固定的。总之，相同类型的变量所占字节数就是一样的。[/quote]谢谢你！

引用 6楼sdghchj 的回复:[quote=引用 4 楼 labuboco 的回复:] [quote=引用 3楼sdghchj 的回复:]这个问题我竟无言以对。 int a[10]难道不是10个相同空间大小的int类型变量么？我想问的是字符串数组是怎么分配存储空间的例如"123445","12","12344667"[/quote] 字符串数组一般是用二维的字符数组来装，如char[5][10]表示是5个最多能存储10个字符的字符串，各字符串都是10个字节，只不过print出来的时候遇到终止符就不打印了而已，但内存依旧是那么多。 即便是标准库的string类型，也是内部有一个字符指针指向申请的其它地址上的字节，string本身的大小依然是固定的。总之，相同类型的变量所占字节数就是一样的。[/quote]可是有的书上写的[][]代表行和列？什么情况

引用 4 楼 labuboco 的回复:[quote=引用 3楼sdghchj 的回复:]这个问题我竟无言以对。 int a[10]难道不是10个相同空间大小的int类型变量么？我想问的是字符串数组是怎么分配存储空间的例如"123445","12","12344667"[/quote] 字符串数组一般是用二维的字符数组来装，如char[5][10]表示是5个最多能存储10个字符的字符串，各字符串都是10个字节，只不过print出来的时候遇到终止符就不打印了而已，但内存依旧是那么多。 即便是标准库的string类型，也是内部有一个字符指针指向申请的其它地址上的字节，string本身的大小依然是固定的。总之，相同类型的变量所占字节数就是一样的。

字符串看编码,不同编码分配的空间不一样的,不过都会多加一个\0来表示结束字符串

引用 3楼sdghchj 的回复:这个问题我竟无言以对。 int a[10]难道不是10个相同空间大小的int类型变量么？我想问的是字符串数组是怎么分配存储空间的例如"123445","12","12344667"

大小相同指存储单元内存储相同类型元素

大小相同的空间 －》大小即存放的数据的数据类型的大小，总空间大小即存放的数据个数＊数据类型大小


Question: 用double定义函数，返回类型为float

引用 6 楼 paschen 的回复:再强调一下，楼主这种不会丢失精度！楼主的是float转double！  中间的运算精度损失了。

引用 11 楼 butters10 的回复:%f 强转成float了，其实你函数还是返回的double的 %f是double

这种函数，返回 double 基本上是误导大家。 计算本身，精度低，返回值精度高 纯粹胡闹， 改为返回 double 并不能提高 计算的精度。 如果函数都这么写，干脆只保留一种浮点数好了。

%f 强转成float了，其实你函数还是返回的double的

理解和讨论之前请先学会如何观察！  计算机组成原理→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执行停在该断点处的时候。

引用 7 楼 qq_34438761 的回复:如果fun函数是float行，变量定义成double型呢？会出错吗？如果在全国二级考试里会不会被扣分？ double转float编译器会发出警告，但是可以通过编译，考试的话可能会扣分。 这种情况一般要求都是“所需类型”或者“能转换成需要的类型”，楼主提出情况是float转double，可以默认转换，而且不会丢失精度，所以一般连警告都不会有，实际情况是无所谓的，但是考试就不一定了。

再强调一下，楼主这种不会丢失精度！楼主的是float转double！

会丢失精度，其实返回值内存块还是double ，只不过显示float 所占用到的内存块

这样是语法上是可以的，只不过有可能数据丢失，因为double的精度比float高

理论上可以，但会丢失精度，最好不要这么干，可以强制转换

编译器会把双精度转化为单精度返回，所以会损失掉一位小数，所以最好也用double返回

返回时会时行隐式转换，所以编译不会报错  另外float转换为double并不会丢失精度


Question: 数据结构单链表

恩 我搞明白了 谢谢

第一你要明白头节点的作用，它与首节点的区别。你这么提取数据是对的，只是你如果在头节点没放入自己数据，取出来的数据你也看不懂


Question: 小女子跪求C大神们赐教~

好感谢butters10 ~~~

xinsert和binsert要先声明后实现。 否则就要把xinsert和binsert的实现写在开头。

建议使用有函数折叠功能的IDE

#include <stdio.h> #include <string.h> #include <stdlib.h> #include <conio.h> #define N 100   typedef struct employee//职工基本情况 {     char num[6];//员工编号     char name[8];//员工姓名     char sex;//性别f为女m为男     char birth[8];//出生年月     char workplace[10];//工作部门     char phone[9];/*办公室电话号码*/     char call[12];/*手机号码*/     struct employee *next;/*结点的指针域*/      }ListNode;  /*主要函数*/ void input(ListNode*){}//输入职工信息 void search(ListNode*){}//查询职工信息 void change(ListNode*){}//修改职工信息 void insert(ListNode*);//插入职工信息 void del(ListNode*);//删除职工信息 void display(ListNode*){}//通讯录表输出  void passWord(){}//设置密码 void save(){}//保存职工信息 void searchByname(){}//按姓名查找 void searchBytel(){}//按手机号查找  int i=0;  int main() {     ListNode* head = (ListNode*)malloc(sizeof(ListNode));          while (1) {                  int choice = 0;         printf("**************************** \n\n");//系统欢迎界面         printf(" 欢迎进入职工管理系统   \n");         printf("**************************** \n");         printf(" 请您选择操作类型: \n");         printf("======================== \n");         printf("   1.输入职工信息 \n");            //用户选择         printf("   2.查询职工信息 \n");         printf("   4.插入职工信息 \n");         printf("   3.修改职工信息 \n");         printf("   5.删除职工信息 \n");         printf("   6.通讯录表输出 \n");         printf("   0.退出系统 \n");         printf("======================== \n");                           scanf("%d",&choice);         switch(choice)         {             case 1:input(head);break;             case 2:search(head);break;             case 3:change(head);break;             case 4:insert(head);break;             case 5:del(head);break;             case 6:display(head);break;             case 7:passWord();break;             case 8:searchByname();break;             case 9:searchBytel();break;             case 0:             {                 printf("谢谢您使用员工通讯录! ");        //退出系统                 exit(0);             }break;             default:                 printf("输入有错误请重新输入: ");         }              }     return false; }   void xinsert(ListNode *); void binsert(ListNode *);  void insert(ListNode * head){                                      //插入函数     int s;          printf("-----------------------------------------\n");     printf("输入1按员工姓名插入:\n");     printf("输入2按员工编号插入:\n");     printf("----------------------------------------\n");          scanf("%d",&s);     switch(s){                                   //是按照姓名插入还是按照编号插入         case 1:xinsert(head);break;         case 2:binsert(head);break;         default:printf("输入错误！请重新输入。");     } }   void xinsert(ListNode *head){                                               //按员工姓名插入          char name1[8];     int i,j;     ListNode *p,*q = NULL;     printf("请输入要插入的员工姓名：");     scanf("%s",name1);     printf("请输入要插入的位置：");     scanf("%d",&i);          p=head;     j=0;     while(p!=NULL&&j<i-1)                            //找到第i-1个结点     {         j=i+1;         p=p->next;     }          if(j == i-1)                                        //结点存在     {         ListNode* x=(ListNode *)malloc(sizeof(ListNode));         strncpy(x->name, name1, sizeof(x->name));         q->next=p->next;         p->next=x;         x->next=q;         printf("插入完成\n");     }     else         printf("不存在第i个位置。\n"); }   void binsert(ListNode *head){                                               //按员工编号插入          char num[6];     int i,j;     ListNode *p,*q;     printf("请输入要插入的员工编号：");     scanf("%s",num);     printf("请输入要插入的位置：");     scanf("%d",&i);          p=head;     j=0;     while(p!=NULL&&j<i-1)                            //找到第i-1个结点     {         j=i+1;         p=p->next;     }          if(j==i-1)                                        //结点存在     {         ListNode* x=(ListNode *)malloc(sizeof(ListNode));         strncpy(x->num,num,sizeof(x->num));         q=p->next;         p->next=x;         x->next=q;         printf("插入完成\n");     }     else         printf("不存在第i个位置。 \n"); }  void xdel(ListNode* head); void bdel(ListNode* head);  void del(ListNode* head){                                                             //删除函数     int a;     printf("-----------------------------------------\n");     printf("输入“1” 按员工姓名删除\n");     printf("输入“2”按员工编号删除\n");     printf("----------------------------------------\n");     scanf("%d",&a);     switch(a){                                   //按所选择的数字进入相应的删除函数。         case 1:xdel(head);break;         case 2:bdel(head);break;         default:printf("输入错误！请重新输入。");     } }   void xdel(ListNode* head){                                               //按员工姓名删除的函数。          char name1[8];     ListNode *p,*q;     printf("请输入要删除的员工姓名：");     scanf("%s",name1);     p=head;     if(p->next==NULL)                                          //若链表中没有信息。         printf("没有要删除的员工信息\n");     else{                       //链表中有信息，找出与姓名相符的节点或一直找到链表尾。         do{             q=p;             p=p->next;         }         while(strcmp(name1,p->name)==0&&p->next==NULL);         if(p->next==NULL)                                          //找到链表尾             printf("没有要删除的员工信息\n");         else{                                     //找到与姓名相符的节点，删除节点。             q->next=p->next;             free(p);             printf("相应信息已删除！\n");}              } }  void bdel(ListNode* head){                                               //按员工编号删除的函数。          char number[5];     ListNode *p,*q;     printf("请输入要删除的员工编号：");     scanf("%s",number);     p=head;          if(p->next==NULL)                                          //若链表中没有信息。         printf("没有要删除的员工信息\n");     else{                       //链表中有信息，找出与编号相同的节点或一直找到链表尾。         do{             q=p;             p=p->next;         }while(!strcmp(number,p->num) &&p->next==NULL);                  if(p->next==NULL)                                          //找到链表尾             printf("没有要删除的员工信息\n");         else{                                     //找到与姓名相符的节点，删除节点。             q->next=p->next;             free(p);             printf("相应信息已删除！\n");}              } }

这个没有别的原因就是少了一个右大括号“}”，报错的个数和这个函数的位置有关，好像也和作用域有关，或者和它的使用频度有关，反正报错的个数不太一样，是主应用程序的一个函数少了一个“}”。解决的方法就是：如果函数的数量少就一个一个的用Ctrl+}来查


Question: 关于C语言,调试到文件关闭时时出现了debug assertion failed

这是出错的地方，提示和楼主时一样的

可是我的在将内存数据往外写的时候报错，但是我打开文件的方式应该时对的呀，我是以“rb”打开的

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

一般来说 异常情况的处理， 应该比较直接一些,不和正常逻辑掺杂在一起  if(e){ ............. return ; ///或者 exit(0);  }  。。。。。。。。。。 这样的话 fclose(fp); 也不会出问题

if else 是很好 但是有点分不出主次的感觉。 干扰正常逻辑的表达。

引用 7 楼 qq423399099 的回复:[quote=引用 6 楼 Ackerman_lu 的回复:] [quote=引用 4 楼 qq423399099 的回复:] 你肯定是fopen失败了，所以fid 是NULL VC++的fclose如果参数是NULL将会造成程序报错退出，因为M$的fclose不检查指针的有效性，而NULL可以被默认转换成任何类型的指针，而fopen失败的时候将会返回a NULL pointer，所以再调用fclose就会咔嚓一下，系统BK了  对的，懂了！我确实是fid为NULL时会出错，不是NULL时可以正常运行. 可我的这段的思路是这样的。分两种情况 （1）如果存在这个文件的话，对这个文件执行一种操作。 （2）如果不存在的话，执行另外一种。 可我这里如果我把fclose那部删掉的话。当我fid不为null时，文件就没有关闭，导致我之后的步骤出现问题。 我应该怎么解决呢？求指导！ [/quote] 要不这样，加个else分支？  if ((fid = fopen(fname, "rt+")) == NULL) { printf("the new dxf file has been built\n"); err = 1; } else { //对该文件操作XXXXXXXXXXXXXXXXXX ........... fclose(fid); } [/quote]   是的，果然小白，蠢成狗了。。 之前加了else的，但是后面一个模块有几个调用量没改。。结果不成功、还以为是bug。。现在可以了，谢谢

引用 6 楼 Ackerman_lu 的回复:[quote=引用 4 楼 qq423399099 的回复:] 你肯定是fopen失败了，所以fid 是NULL VC++的fclose如果参数是NULL将会造成程序报错退出，因为M$的fclose不检查指针的有效性，而NULL可以被默认转换成任何类型的指针，而fopen失败的时候将会返回a NULL pointer，所以再调用fclose就会咔嚓一下，系统BK了  对的，懂了！我确实是fid为NULL时会出错，不是NULL时可以正常运行. 可我的这段的思路是这样的。分两种情况 （1）如果存在这个文件的话，对这个文件执行一种操作。 （2）如果不存在的话，执行另外一种。 可我这里如果我把fclose那部删掉的话。当我fid不为null时，文件就没有关闭，导致我之后的步骤出现问题。 我应该怎么解决呢？求指导！ [/quote] 要不这样，加个else分支？  if ((fid = fopen(fname, "rt+")) == NULL) { printf("the new dxf file has been built\n"); err = 1; } else { //对该文件操作XXXXXXXXXXXXXXXXXX ........... fclose(fid); }

引用 4 楼 qq423399099 的回复:你肯定是fopen失败了，所以fid 是NULL VC++的fclose如果参数是NULL将会造成程序报错退出，因为M$的fclose不检查指针的有效性，而NULL可以被默认转换成任何类型的指针，而fopen失败的时候将会返回a NULL pointer，所以再调用fclose就会咔嚓一下，系统BK了  对的，懂了！我确实是fid为NULL时会出错，不是NULL时可以正常运行. 可我的这段的思路是这样的。分两种情况 （1）如果存在这个文件的话，对这个文件执行一种操作。 （2）如果不存在的话，执行另外一种。 可我这里如果我把fclose那部删掉的话。当我fid不为null时，文件就没有关闭，导致我之后的步骤出现问题。 我应该怎么解决呢？求指导！

引用 1 楼 Ackerman_lu 的回复:自顶~~求指导~~那问题是我的dxf_header的函数块的引用部分吗？求指导  #include <stdio.h> #include<stdlib.h>  void DXF_head(char filename[20]) { 	FILE *fid; 	//if ((fid = fopen(filename, "wt+")) == NULL) 	//{ 		//printf("can't open\r\n"); 		//exit(1); 	//}  	fid = fopen(filename, "wt+");  那个我是这么写的，红字那行开始没用，是用上面注释掉的那部分写的。。不过两种都不行

问题不在这儿~

自顶~~求指导~~


Question: 帮忙看看什么问题，我想输出三个数的中间值

1.函数mid返回 值K没有没有初始化,所有他是一个随机值; 2.控制台输入的1 2 3  在函数mid中涉及到的3个if条件都不满足,所有K值没有改变    返回最开始的随机值;


Question: winpcap编程入门求组！

引用 6 楼 jack960330 的回复:用调试器看看进行错误堆栈追踪，有必要的话，试着贴代码发上来 我重下了一遍winpcap包，重新配置了一遍，现在好了

引用 6 楼 jack960330 的回复:用调试器看看进行错误堆栈追踪，有必要的话，试着贴代码发上来 代码就是这个http://www.cnblogs.com/blacksword/archive/2012/03/09/2387189.html 调试显示的是 用了这个函数就报错，但是这不是库函数么...

用调试器看看进行错误堆栈追踪，有必要的话，试着贴代码发上来

引用 4 楼 jack960330 的回复:你发错误信息 编译没错，一运行就弹出，

引用 1 楼 jack960330 的回复:异常啊，winpcap 网上有示例代码，打开网络适配器，设置混杂模式啥的，都有 对啊，我原原本本把代码拷贝过去了，怎么就运行出错了呢...

引用 2 楼 aiur233 的回复:[quote=引用 1 楼 jack960330 的回复:] 异常啊，winpcap 网上有示例代码，打开网络适配器，设置混杂模式啥的，都有 对啊，我原原本本把代码拷贝过去了，怎么就运行出错了呢...[/quote]  到底什么错误

引用 2 楼 aiur233 的回复:[quote=引用 1 楼 jack960330 的回复:] 异常啊，winpcap 网上有示例代码，打开网络适配器，设置混杂模式啥的，都有 对啊，我原原本本把代码拷贝过去了，怎么就运行出错了呢...[/quote] 你发错误信息

异常啊，winpcap 网上有示例代码，打开网络适配器，设置混杂模式啥的，都有


Question: C语言二维数组传递突然由字母变成乱码

单步跟踪程序运行以分析原因

贴出代码看一看啦，，，，

我单步运行过了，上一个函数还好好的，到下一个函数就乱码了QAQ

display到下一个函数之间没有其他任何操作，我是在下一个函数之前puts了一下数组，就莫名其妙变成这样了QAQ


Question: 二维数组空间分配15,30,45什么意思？

这么简单的问题没人回答吗

引用 8楼我是你的主体 的回复:引用 7楼stdcall_Jeremy 的回复:因为是你自己分配的空间,一个字符串就是一行,分配多的保留呵呵那句话说了一个字符串一行了？

因为是你自己分配的空间,一个字符串就是一行,分配多的保留

引用 4 楼 labuboco 的回复:[quote=引用 3楼小灸舞 的回复:]就是说你在定义char aname[][15] = {"XXX","XXX","XXXX"};的时候系统分配给你了45个字节那么长的空间 1-15字节给了第一个字符串 16-30字节给了第二个字符串 31-45字节给了第三个字符串15我记得代表列数吧？[/quote] 你说的没错，第一个字符串占了1行（15列），一列只有一个字节，只能存储一个char字符

引用 5楼小灸舞 的回复:[quote=引用 4 楼 labuboco 的回复:] [quote=引用 3楼小灸舞 的回复:]就是说你在定义char aname[][15] = {"XXX","XXX","XXXX"};的时候系统分配给你了45个字节那么长的空间 1-15字节给了第一个字符串 16-30字节给了第二个字符串 31-45字节给了第三个字符串15我记得代表列数吧？[/quote] 你说的没错，第一个字符串占了1行（15列），一列只有一个字节，只能存储一个char字符[/quote]那为什么第二个字符也占了一整行

引用 3楼小灸舞 的回复:就是说你在定义char aname[][15] = {"XXX","XXX","XXXX"};的时候系统分配给你了45个字节那么长的空间 1-15字节给了第一个字符串 16-30字节给了第二个字符串 31-45字节给了第三个字符串15我记得代表列数吧？

引用 1楼赵4老师 的回复:从左往右数第几个字符请说明原因

从左往右数第几个字符


Question: 初学者求助！！二维数组如何比较和输出每行的最大和每列最大？？

建议将i,j替换为y,x以免弄混行和列。

一层还是两层你扫描的数据量是不变的，一层两层都可以。 #include <stdlib.h> #include <stdio.h>  int main(int argc, char *argv[]) {     int a[5][5] = {{5, 3, 6, 8, 9}, {0, 23, 10, 30, 47}, {33, 54, 16, 80, 49}, {23, 38, 70, 67, 88}, {11, 92, 87, 64, 50}};     int b[5] = {0};     int c[5] = {0};     int i = 0;     for(i = 0; i < 25; i ++)     {         //printf("%d , %d", *(*a + i), i / 5);         if(b[(int)(i / 5)] < *(*a + i))         {             b[(int)(i / 5)] = *(*a + i);             printf("(%d, %d)", b[(int)(i / 5)], i / 5);         }         if(c[i % 5] < *(*a + i))         {             c[i % 5] = *(*a + i);         }     }     printf("\n");     for(i = 0; i < 5; i ++)     {         printf("line %d: max %d\n", i, b[i]);     }     for(i = 0; i < 5; i ++)     {         printf("raw %d: max %d\n", i, c[i]);     }     return 0; } 两层就不用我写了吧。

遍历某一行/列的最大值可以只用一层循环  下面是遍历索引为1的行所有列，其中N为列的总数  for (i = 0; i < N; ++i)       a[1][i]  .....


Question: C语言 查询订单系统进不去  还请大神指点

引用 2 楼 user-2的回复:截个运行效果图来看看 就是主界面选择订单详情，输入订单号后，直接返回主函数了

引用 1 楼 paschen的回复:自己单步跟踪程序运行，是不是文件没有打开成功，然后函数就返回了 还不会单步执行

自己单步跟踪程序运行，是不是文件没有打开成功，然后函数就返回了

截个运行效果图来看看


Question: 初学c，还请大神找下问题，谢谢了

读入数组和打印出数组必须要用循环

建议你直接在代码里初始化数组,每次都在运行时从键盘输入好麻烦

scanf("%d",&a[3][4])是错误地,因为数组是从a[0][0]开始,最多到a[2][3],而且你只输入了一个数组元素,应当用到循环输入全部数组元素

“多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，搬手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？

scanf("%d", &a[3][4]); 这个地方用下标，表示二维数组成员中的一个，而且数组开头是从a[0][0]开始，a[3][4]已经越界 要输入12个的话应该用到循环输入

最后一个printf没分号

scanf("%d", &a[3][4]); 这边你就对数组最后一个元素赋值了，其他都未初始化

楼主的scanf有问题，楼主那样写只能读取一个数字  #include<iostream> #include <stdio.h> using namespace std; int main() { 	int i, j, max, row=0, colum=0; 	int a[3][4]; 	printf("Please input 12 numbers: \n"); 	int n = 0; 	while(scanf("%d%*c", &a[n/4][n%4]))if(++n == 12)break; 	max=a[0][0]; 	for(i = 0; i < 3; i++) 	{ 		for(j=0; j < 4; j++) 		{ 			if(a[i][j] > max) 			{ 				max = a[i][j]; 				row = i; 				colum = j; 			}  		} 	} 	printf("max=%d\n", max); 	printf("row=%d\ncolum=%d\n", row, colum); 	system("pause"); 	return 0; }  输在一行或者输一个数字换一行都行

改成这样：   #include <stdio.h>  void main() { 	int i, j, max, row=0, colum=0; 	int a[3][4]; 	printf("Please input 12 numbers: \n"); 	for(i = 0; i < 3; i++) 	{ 		for(j=0; j < 4; j++) 		{ 			scanf("%d", &a[i][j]); 		} 	} 	max=a[0][0]; 	for(i = 0; i < 3; i++) 	{ 		for(j=0; j < 4; j++) 		{ 			if(a[i][j] > max) 			{ 				max = a[i][j]; 				row = i; 				colum = j; 			}  		} 	} 	printf("max=%d\n", max); 	printf("row=%d\ncolum=%d\n", row, colum); }

scanf那点错了


Question: 如何解决发送端数据突然暴增的问题？

引用 6 楼 u012879787 的回复:[quote=引用 5 楼 zilaishuichina 的回复:] 客户端数据突然暴增，发的频率快，服务器一般要做什么处理？   设置一个阀值，比如10秒最多只接受100个包，超出就断开连接   第2个问题： 网络的吞吐量到底是什么意思？   每秒接收/发送的比特数/字节数  吞吐量这个概念为什么会出现在 应用程序中？  按照你的书佛啊，这个概念是属于网络的，  为什么我去面试，面试官说什么吞吐量。　我很奇怪。  这属于　网络接收的比特数目，和应用程序有什么关系？  难道是因为应用层影响接收窗口大小，所以面试官就问我以前开发的程序的吞吐量？  [/quote]  如果你是做服务端/ 网络层相关的开发的， 涉及iocp / epoll开发， 那面试的人意思可能是问你， 你的网络层 能承受每秒收发多少个包，或者是能承受的并发连接数，  举个例子，网游服务端， 游戏的网关服务器大概是并发5000人的情况下， 每秒上行+下行30-40W个小包（100字节以内的包）

引用 5 楼 zilaishuichina 的回复:客户端数据突然暴增，发的频率快，服务器一般要做什么处理？   设置一个阀值，比如10秒最多只接受100个包，超出就断开连接   第2个问题： 网络的吞吐量到底是什么意思？   每秒接收/发送的比特数/字节数  吞吐量这个概念为什么会出现在 应用程序中？  按照你的书佛啊，这个概念是属于网络的，  为什么我去面试，面试官说什么吞吐量。　我很奇怪。  这属于　网络接收的比特数目，和应用程序有什么关系？  难道是因为应用层影响接收窗口大小，所以面试官就问我以前开发的程序的吞吐量？

吞吐：两个层面，一个吞，一个吐，吞就是接收能力，吐就是发送能力，其实就是网络的收发能力，

引用 2 楼 user-4 的回复:数据总有协议吧，发得快就处理快一些而已了。如果发现接收缓冲区中有很多无法解析的数据，把这个连接断开就是了。  第2个问题： 网络的吞吐量到底是什么意思？

接收端设置一个足够大的FIFO缓冲区。


Question: 最近在读内核代码，有一个问题一直困惑着我

谢谢回复

1.gcc等编译器扩展，取最后一个表达式的值 2.typeof(expr)不会导致expr被计算，比如typeof(i++)不会使i自增


Question: 新人遇到奇怪的问题

在C中有两种特殊的字符，八进制转义字符和十六进制转义字符，八进制字符的一般形式是'\ddd'，d是0-9的数字。十六进制字符的一般形式是'\xhh'，h是0-9或A-F内的一个。八进制字符和十六进制字符表示的是字符的ASCII码对应的数值。 \113对应10进制75，也就是字符K

C++ String Literals A string literal consists of zero or more characters from the source character set surrounded by double quotation marks ("). A string literal represents a sequence of characters that, taken together, form a null-terminated string.  Syntax  string-literal :  "s-char-sequenceopt" L"s-char-sequenceopt"  s-char-sequence :  s-char s-char-sequence s-char  s-char :  any member of the source character set except the double quotation mark ("), backslash (\), or newline character escape-sequence  C++ strings have these types:   Array of char[n], where n is the length of the string (in characters) plus 1 for the terminating '\0' that marks the end of the string   Array of wchar_t, for wide-character strings  The result of modifying a string constant is undefined. For example:  char *szStr = "1234"; szStr[2] = 'A';      // Results undefined  Microsoft Specific   In some cases, identical string literals can be “pooled” to save space in the executable file. In string-literal pooling, the compiler causes all references to a particular string literal to point to the same location in memory, instead of having each reference point to a separate instance of the string literal. The/Gf compiler option enables string pooling.  END Microsoft Specific  When specifying string literals, adjacent strings are concatenated. Therefore, this declaration:  char szStr[] = "12" "34";  is identical to this declaration:  char szStr[] = "1234";  This concatenation of adjacent strings makes it easy to specify long strings across multiple lines:  cout << "Four score and seven years "         "ago, our forefathers brought forth "         "upon this continent a new nation.";  In the preceding example, the entire string Four score and seven years ago, our forefathers brought forth upon this continent a new nation. is spliced together. This string can also be specified using line splicing as follows:  cout << "Four score and seven years \ ago, our forefathers brought forth \ upon this continent a new nation.";  After all adjacent strings in the constant have been concatenated, the NULL character, '\0', is appended to provide an end-of-string marker for C string-handling functions.  When the first string contains an escape character, string concatenation can yield surprising results. Consider the following two declarations:  char szStr1[] = "\01" "23"; char szStr2[] = "\0123";  Although it is natural to assume that szStr1 and szStr2 contain the same values, the values they actually contain are shown in Figure 1.1.  Figure 1.1   Escapes and String Concatenation    Microsoft Specific   The maximum length of a string literal is approximately 2,048 bytes. This limit applies to strings of type char[] and wchar_t[]. If a string literal consists of parts enclosed in double quotation marks, the preprocessor concatenates the parts into a single string, and for each line concatenated, it adds an extra byte to the total number of bytes.   For example, suppose a string consists of 40 lines with 50 characters per line (2,000 characters), and one line with 7 characters, and each line is surrounded by double quotation marks. This adds up to 2,007 bytes plus one byte for the terminating null character, for a total of 2,008 bytes. On concatenation, an extra character is added to the total number of bytes for each of the first 40 lines. This makes a total of 2,048 bytes. (The extra characters are not actually written to the string.) Note, however, that if line continuations (\) are used instead of double quotation marks, the preprocessor does not add an extra character for each line.  END Microsoft Specific  Determine the size of string objects by counting the number of characters and adding 1 for the terminating '\0' or 2 for type wchar_t.  Because the double quotation mark (") encloses strings, use the escape sequence (\") to represent enclosed double quotation marks. The single quotation mark (') can be represented without an escape sequence. The backslash character (\) is a line-continuation character when placed at the end of a line. If you want a backslash character to appear within a string, you must type two backslashes (\\). (SeePhases of Translation in the Preprocessor Reference for more information about line continuation.)  To specify a string of type wide-character (wchar_t[]), precede the opening double quotation mark with the character L. For example:  wchar_t wszStr[] = L"1a1g";  All normal escape codes listed in Character Constants are valid in string constants. For example:  cout << "First line\nSecond line"; cout << "Error! Take corrective action\a";  Because the escape code terminates at the first character that is not a hexadecimal digit, specification of string constants with embedded hexadecimal escape codes can cause unexpected results. The following example is intended to create a string literal containing ASCII 5, followed by the characters five:  \x05five"  The actual result is a hexadecimal 5F, which is the ASCII code for an underscore, followed by the characters ive. The following example produces the desired results:   "\005five"     // Use octal constant. "\x05" "five"  // Use string splicing.

\ddd 1到3位八进制数所代表的任意字符 三位八进制

你看下八进制和十进制和十六进制怎么表示吧

\ ooo 	 八进制表示法的 ASCII 字符

楼上说的是，\113指的是指八进制

\ ooo 	 八进制表示法的 ASCII 字符


Question: 请问我用VS2015C语言里用fseek()函数怎么不能成功移动位置呢?

引用 1 楼 user-1 的回复:估计是你fopen的打开方式有问题。  如果希望能在写入时用fseek定位，fopen的模式需要设置为“r+" 或 "rb+" fp = fopen(text_file, "r+"); or fp = fopen(binary_file, "rb+");   谢谢大神，的确是这个原因!


Question: 求大神帮忙看看问题   登陆系统无法使用

引用 1 楼 user-1的回复:scanf_s使用时，需要给出读取字符数量，否则无法获取正确的值scanf_s("%c", &xz, 1); 楼主的login中打开文件之后的if判断有问题，是== ，而不是=号。if (fp == NULL) 谢谢，已经完美解决啦


Question: 一个函数原本参数是B类型结构体，把A类型强制转换成B类型传参会打印出的不是原来的成员，而是A类型结构体最后一个成员的原理是什么？

理解和讨论之前请先学会如何观察！  计算机组成原理→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执行停在该断点处的时候。

double类型通常是用IEEE 754格式存储的， 当你在第5个字节写入‘z'时，该double值对应的内存数据为0x00000000 0000007A little-endian下会存储如下。 00: ... 04:   01111010 (0x7a) 05:   00000000 06:   00000000 07:   00000000 08:   00000000 09:   00000000 0A:   00000000 0B:   00000000  这一内存数据对应的double值 =  122.0 / (2的1023次方）。 所以当你printf输出的时候之所以会显示为0.000000，是因为这个数太小了。

引用 3 楼 qq423399099 的回复:[quote=引用 2 楼 baidu_28726667 的回复:] [quote=引用 1 楼 qq423399099 的回复:] 楼主你的初始化有问题struct A a={(3,4,7)}; 这样赋值只会让 i 赋上7,而 j 和 k 是不会赋上值的（楼主可以打印验证），所以你强转后打印出来的是7 应该改为以下这样（这样就能打印出3了）  struct A a = {3, 4, 7};   感谢回答啊，原来是这个问题。意思小括号里面的，跟= 一样的效果所以最后是7吗？   另外改了下代码。 这个强制类型转换的打印结果 o=3  i=0  j=0.000000  最后一个0.000000是因为A里面不存第3个成员吧？ 但是char j的‘z’为什么没有能把 asiii值打印出来呢？ 这样强制转换不是第一个成员对第一个成员，第二个对第二个，第三个因为缺少了所以导致打印有问题吗？  #include<stdio.h>  struct A { 	int i; 	char j;  };  struct B { 	char o; 	char i; 	double j; };  void f(struct B* pb) { 	printf("o=%d\n",pb->o); 	printf("i=%d\n",pb->i); 	printf("j=%f\n",pb->j); }  int main(void) { 	struct A a={3,'z'}; 	f((struct B*)&a);  	return 0; } [/quote] 肯定不是一个成员对一个成员的啊，你的B中的两个char都是对着A中的int的，而且一般现在的机子都是小端模式，即低位高字节 i赋成3以后在内存中存储方式为0000 0011 0000 0000 0000 0000 0000 0000,所以B中的o对应前八位0000 0011打印出3 而i对应 0000 0000所以打印出0 之后的double涉及到数据对齐,B中的char o和char i会占8字节（6个字节是补齐double的），（A由于对齐一共占8字节） 所以B中的double指的位置已经超过A了（double j从第九个位置开始）[/quote]  小端不是低字节低地址吗？ 而且stcuct b的  char o 和 char i 不是一共4字节码？我是在ubuntu 12.04 vi gcc编译的 .这个结构体一共12字节。 好像是超过cpu字长按4字节存放？ 所以char o+char i 补齐后一共4字节，而double 要占两个4字节的空间就8个字节，一共12个吧。

引用 2 楼 baidu_28726667 的回复:[quote=引用 1 楼 qq423399099 的回复:] 楼主你的初始化有问题struct A a={(3,4,7)}; 这样赋值只会让 i 赋上7,而 j 和 k 是不会赋上值的（楼主可以打印验证），所以你强转后打印出来的是7 应该改为以下这样（这样就能打印出3了）  struct A a = {3, 4, 7};   感谢回答啊，原来是这个问题。意思小括号里面的，跟= 一样的效果所以最后是7吗？   另外改了下代码。 这个强制类型转换的打印结果 o=3  i=0  j=0.000000  最后一个0.000000是因为A里面不存第3个成员吧？ 但是char j的‘z’为什么没有能把 asiii值打印出来呢？ 这样强制转换不是第一个成员对第一个成员，第二个对第二个，第三个因为缺少了所以导致打印有问题吗？  #include<stdio.h>  struct A { 	int i; 	char j;  };  struct B { 	char o; 	char i; 	double j; };  void f(struct B* pb) { 	printf("o=%d\n",pb->o); 	printf("i=%d\n",pb->i); 	printf("j=%f\n",pb->j); }  int main(void) { 	struct A a={3,'z'}; 	f((struct B*)&a);  	return 0; } [/quote] 肯定不是一个成员对一个成员的啊，你的B中的两个char都是对着A中的int的，而且一般现在的机子都是小端模式，即低位高字节 i赋成3以后在内存中存储方式为0000 0011 0000 0000 0000 0000 0000 0000,所以B中的o对应前八位0000 0011打印出3 而i对应 0000 0000所以打印出0 之后的double涉及到数据对齐,B中的char o和char i会占8字节（6个字节是补齐double的），（A由于对齐一共占8字节） 所以B中的double指的位置已经超过A了（double j从第九个位置开始）

引用 1 楼 qq423399099 的回复:楼主你的初始化有问题struct A a={(3,4,7)}; 这样赋值只会让 i 赋上7,而 j 和 k 是不会赋上值的（楼主可以打印验证），所以你强转后打印出来的是7 应该改为以下这样（这样就能打印出3了）  struct A a = {3, 4, 7};   感谢回答啊，原来是这个问题。意思小括号里面的，跟= 一样的效果所以最后是7吗？   另外改了下代码。 这个强制类型转换的打印结果 o=3  i=0  j=0.000000  最后一个0.000000是因为A里面不存第3个成员吧？ 但是char j的‘z’为什么没有能把 asiii值打印出来呢？ 这样强制转换不是第一个成员对第一个成员，第二个对第二个，第三个因为缺少了所以导致打印有问题吗？  #include<stdio.h>  struct A { 	int i; 	char j;  };  struct B { 	char o; 	char i; 	double j;  };  void f(struct B* pb) { 	printf("o=%d\n",pb->o); 	printf("i=%d\n",pb->i); 	printf("j=%f\n",pb->j); }  int main(void) { 	struct A a={3,'z'}; 	f((struct B*)&a);  	return 0; }


Question: 数组传递，在被调函数中指针的大小

好像是我自己理解错了，sizeof(ar[0])是数组ar第一个元素的字节， 而sizeof(ar)指的是数组ar第一个元素地址的大小，而系统是64位的 谢谢大家啦，今天第一次在CSDN上提问，大家的回答既及时又给力

引用 楼主 alex19941124 的回复:按理说int 型的指针是4字节啊，为什么会显示有8字节呢？ 之前看教材，视频都是说四字节。。。。。 }  那说明你看的教材和视频都在乱说，纯属误人子弟。  指针的大小一般总是与系统的 long 型保持一致。 如果在你的系统中，sizeof(long) == 8, 那么指针就为8字节。

[b]不知道为什么我的sizeof(ar)居然跟sizeof(ar[0])不一样大

引用 楼主 alex19941124 的回复:按理说int 型的指针是4字节啊，为什么会显示有8字节呢？  关于C语言的指针类型与编译运行环境有关。如果你目标环境是64位系统，那么地址宽度就是8字节的，所以指针类型就是8字节的宽度。如果是32位的，那么地址宽度就是4字节；在某些嵌入式系统中，比如8位的单片机，地址可能就是2字节甚至1个字节的……  因此，如果你用的C语言实现支持C99标准，那么请使用uintptr_t或intptr_t整数类型来存放指针的值；否则，可以使用size_t。

int 型的指针是4字节啊，为什么会显示有8字节  int型指针长度和语言，编译器，操作系统(32位/64位)等有关联，但是在书及视频中多采用32位C++语言来计算。某些编译器之间存在某些不一致的情况。

不知道楼主的环境是什么？


Question: C语言参数传递

请那些喜欢将数组作为函数参数传来传去的码农思考一下为什么不把整个互联网内容当作函数参数传来传去呢？

谢谢谢谢，功力太浅，没能完全看懂，继续努力

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

谢谢，明白了

数组作为参数传递时就退化成了指针，你得再传递一个参数记录数组的大小，如你上面代码的n  访问越界并不会导致编译失败，但可能导致运行时的崩溃


mutex和cm的加锁顺序不一致难道不会死锁吗？

多谢大神啊，mark一下

收藏一下吧，多谢


Question: 请问如何给双向链表中的指针数组，键盘输入字符串赋值

供楼主参考，这里先malloc头结点的空间，然后每次能读到一个字符串就malloc一个字符串的空间  #include <stdlib.h> #include<iostream> #include <stdio.h> using namespace std; #define NULL 0    #define amount1 100            //结构体中*arr[]数组长度，用来定义扩充成员个数    typedef struct node {     struct node  *pre;            //指向前驱     char *arr[amount1];     struct node *next;            //指向后继 }NODE; NODE *head; int main() { 	head = (NODE *)malloc(sizeof(NODE)); 	int index = 0; 	char buffer[64] = {0}; 	while (scanf("%s",buffer) != EOF)      { 		head->arr[index] = (char *)malloc(strlen(buffer) + 1); 		strcpy(head->arr[index], buffer); 		printf("index = %s\n",head->arr[index]);         index++; 		if(getchar() == '\n')break;//读到输入的字符串的末尾了，结束循环     } 	system("pause"); 	return 0; }

补充下上面的，这个是运行结果

没人回答吗？ 你的char *arr[amount1]是个指针数组，每个元素都是指针。 你可以随意申请一个存储空间，比如char* pInput，C用malloc，C++用new，然后用scanf或者cin输入你想要的字符串，输入完毕后，把pInput存到arr里面去。比如第一个字符串，就是arr[0] = pInput。 使用完毕后，记得释放pInput的内存。


Question: 来源谭c语言switch和if应用的一个很好的例子！（没想到自己比谭教授写的还精简一些）特来分享一下！

4楼的代码好靓！

顶

谭的代码好丑

不错，多思考，书上的很多例子可以优化和改进，也可以添加新的功能。

嗯嗯，学到了，但是谭c的这道题在前面，还没讲到数组。

#include<stdio.h> int main() {     int x,L,i;     char s[6];     scanf("%d",&x);     if(x<0 || 99999<x) {         printf("0<=x<=99999\n");         return 1;     }     L=sprintf(s,"%d",x);     printf("它是%d位数\n",L);     for (i=0;i<L;i++) printf("第%d位数是%c\n",i+1,s[i]);     printf("反序数字为");     for (i=L-1;i>=0;i--) printf("%c",s[i]);     printf("\n");     return 0; }

第一次发有技术性的帖子，感谢！