Question: 求助 复制C primer plus书上的程序后 运行显示未定义的符号     '_sum_squares'

找到了，double sum_suqares (int a, int b)，应该是sum_squaers

引用 1 楼 user-1 的回复:加个#include<stdlib.h>试试 加了，还是一样的错误。

加个#include<stdlib.h>试试


Question: 关于字符串的一道题，求改错

用C的标准库，专门有字符串处理的函数，多了去了

我没有学过C++，各位大神能用C做么

这是我们学校的在线测试，这是题目，可是我通过不了，不知道是什么测试数据错了，还是我题目那里理解的有问题？

for reference only /*************************************************************************     > File Name: test3.cpp     > Author: jukay     > Mail: hellojukay@163.com      > Created Time: 2014年12月18日 星期四 18时58分44秒  ************************************************************************/  #include<iostream> #include<algorithm> #include<vector> #include<string> using namespace std;   int main() { 	string str,tmp; 	vector<string> v; 	cin >> str ; 	while(cin >> tmp) 	{ 		if(tmp == "\n") 			break; 		v.push_back(tmp); 	} 	int n = count(v.begin(), v.end(), str); 	cout << n << endl;  	return 0; }

哪里错了？不明白楼主想要大家干什么。。。


Question: 请问C语言如何把链表存入文件，从文件读取到链表

引用 10 楼 q3733353520 的回复:[quote=引用 9 楼 zhao4zhong1 的回复:] [quote=引用 7 楼 q3733353520 的回复:] [quote=引用 6 楼 zhao4zhong1 的回复:] 推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,fread,fwrite,fgetc,fclose  //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了  linux 咋看呢[/quote] #include <stdio.h> #include <string.h> FILE *f; char buffer[4096]; int r,a; void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             printf("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         printf("%s\n",binstr);     } } int main(int argc,char **argv) {     if (argc<2) {         fprintf(stderr,"Usage: %s filename.ext\n",argv[0]);         return 2;     }     f=fopen(argv[1],"rb");     if (NULL==f) {         fprintf(stderr,"Can not open file [%s]!\n",argv[1]);         return 1;     }     a=0;     while (1) {         r=fread(buffer,1,4096,f);         HexDump(buffer,r,a);         a+=r;         if (r<4096) break;     }     fclose(f);     return 0; } [/quote] 哦， 谢谢赵老师[/quote]  文件的其实 od  可以，内存还是用gdb调试好点

引用 9 楼 zhao4zhong1 的回复:[quote=引用 7 楼 q3733353520 的回复:] [quote=引用 6 楼 zhao4zhong1 的回复:] 推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,fread,fwrite,fgetc,fclose  //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了  linux 咋看呢[/quote] #include <stdio.h> #include <string.h> FILE *f; char buffer[4096]; int r,a; void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             printf("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         printf("%s\n",binstr);     } } int main(int argc,char **argv) {     if (argc<2) {         fprintf(stderr,"Usage: %s filename.ext\n",argv[0]);         return 2;     }     f=fopen(argv[1],"rb");     if (NULL==f) {         fprintf(stderr,"Can not open file [%s]!\n",argv[1]);         return 1;     }     a=0;     while (1) {         r=fread(buffer,1,4096,f);         HexDump(buffer,r,a);         a+=r;         if (r<4096) break;     }     fclose(f);     return 0; } [/quote] 哦， 谢谢赵老师

引用 6 楼 zhao4zhong1 的回复:推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,fread,fwrite,fgetc,fclose  //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了  linux 咋看呢

引用 7 楼 q3733353520 的回复:[quote=引用 6 楼 zhao4zhong1 的回复:] 推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,fread,fwrite,fgetc,fclose  //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了  linux 咋看呢[/quote] #include <stdio.h> #include <string.h> FILE *f; char buffer[4096]; int r,a; void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             printf("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         printf("%s\n",binstr);     } } int main(int argc,char **argv) {     if (argc<2) {         fprintf(stderr,"Usage: %s filename.ext\n",argv[0]);         return 2;     }     f=fopen(argv[1],"rb");     if (NULL==f) {         fprintf(stderr,"Can not open file [%s]!\n",argv[1]);         return 1;     }     a=0;     while (1) {         r=fread(buffer,1,4096,f);         HexDump(buffer,r,a);         a+=r;         if (r<4096) break;     }     fclose(f);     return 0; }

好帖子。学习学习。

Consumer* read_list() { 	FILE *fp; 	if ((fp = fopen("CONSUMER.dat", "rb")) == NULL) 	{ 		printf("无法读取 CONSUMER.dat\n"); 		return NULL; 	} 	int sign; 	Consumer *s,*p,*head; 	 	head= (Consumer*)malloc(SIZE_C); 	if (head == NULL) 	{ 		printf("读取失败！内存空间申请不足！\n"); 		return NULL; 	} 	fseek(fp, 0, SEEK_END); 	if (ftell(fp) == 0) 	{ 		return NULL; 	} 	p = head; 	p->next = NULL; 	while (feof(fp)) 	{ 		s = (Consumer*)malloc(SIZE_C); 		//fread(s, SIZE_C, 1, fp);                 fread(s, sizeof(char), SIZE_C, fp); 		p->next = s; 		p = s; 		p->next = NULL; 	} 	fclose(fp); 	return head; }//读取文件到链表 int save_consumer(Consumer *p) { 	FILE *fp; 	Consumer *head; 	head = p;//p为已经构建好的链表 	//if ((fp = fopen("CONSUMER.dat", "ab+")) == NULL)         if ((fp = fopen("CONSUMER.dat", "wb")) == NULL) 	{ 		printf("无法打开 CONSUMER.dat!\n"); 		return -1; 	} 	while (p != NULL) 	{ 		//fwrite(p, SIZE_C, 1, fp);                 fwrite(p, sizeof(char), SIZE_C, fp); 		p = p->next; 	} 	fclose(fp); 	return 1; }//储存链表到文件

3楼，你的分析是对的，就是feof函数的原因，所以我改成了fread的返回值去判断，在读文件时我再设置了文件指针的位置，用fseek，这样就可以实现了，我逐语句调试，发现feof做循环控制条件的话，循环执行3次，所以feof正如你分析的一样！

while (！feof(fp))     {         s = (Consumer*)malloc(SIZE_C);         fread(s, sizeof（SIZE_C）, 1, fp);         p->next = s;         p = s;         p->next = NULL;     } 试下能不能运行，  while(!feof(fp))是循环来控制文件内容的读取， 例如当前读取的内容不是文件尾部，则feof（fp）为0，去非运算后为1，那么就继续循环执行！ 如果执行到文件尾部，则feof（fp）为1，取非为0，循环借宿，读取文件结束。

for reference only,我就只写文件到链表了,链表o大n文件用对应的fprintf就可以了 /*************************************************************************     > File Name: test3.c     > Author: jukay     > Mail: hellojukay@163.com      > Created Time: 2014年12月18日 星期四 19时29分18秒  ************************************************************************/  #include<stdio.h> #include<stdlib.h>  struct date { 	char str[3]; 	struct date *next; };  //链表长度为len struct date *create_link(int len) { 	struct date *head; 	struct date *tmp; 	int i; 	head = malloc(sizeof(struct date)); 	tmp = head; 	for(i = 1; i < len; ++i) 	{ 		head ->next = malloc(sizeof(struct date)); 		head = head ->next; 	} 	head ->next = NULL; 	return tmp; }  //读文件到链表 void read_file_to_link(struct date *head,FILE *fp) { 	if(head == NULL || fp == NULL) 	{ 		fprintf(stderr,"null pointer"); 		exit(EXIT_FAILURE); 	} 		do 		{ 			fscanf(fp,"%3s",head ->str); 			head = head ->next; 		}while(head != NULL); }  //显示链表中的内容 void print_link(struct date *head) { 	if(head == NULL) 	{ 		fprintf(stderr,"null pointer"); 		exit(EXIT_FAILURE); 	} 	do 	{ 		printf("%s",head ->str); 		head = head ->next; 	}while(head != NULL); }  int main() { 	FILE *fp; 	int len; //链表长度 	scanf("%d",&len); 	fp = fopen("a.txt","r"); 	struct date *head; 	head = create_link(len); 	read_file_to_link(head,fp); 	print_link(head);  	exit(EXIT_SUCCESS); }

有知道的吗？


引用 2 楼 u011021711 的回复:引用 1 楼 q3733353520 的回复:可以这么理解 read阻塞时，在键盘上输入字符会显示到控制台，那这些字符是存在哪儿的呢？跟STDIN_FILENO和STDOUT_FILENO有什么联系没？  我的理解是read是行缓冲，   这些内容应该放在缓冲区  跟  0  和 1 肯定是有关系的 。

可以这么理解


Question: 请问各位大神，c语言二维数组的动态分配应该怎么写？

#define ROW    3 #define COL     3 int main(void) {     int i;     int **array = (int **)malloc(sizeof(int *) * ROW);     for (i = 0; i < ROW; i++)         array[i] = (int *)malloc(sizeof(int) * COL); }

http://blog.csdn.net/judy_c/article/details/62038688 可以看一下这个。还是比较系统的

#include <stdio.h> #include <stdlib.h> #include <malloc.h> int **newarr2d(int rows,int cols) {     int **p,i;      p=(int **)malloc(rows*sizeof(int *));     if (NULL==p) exit(1);     for (i=0;i<rows;i++) {         p[i]=(int *)malloc(cols*sizeof(int));         if (NULL==p[i]) exit(1);     }     return p; } void deletearr2d(int **p,int rows) {     int i;      for (i=0;i<rows;i++) {         free(p[i]);     }     free(p); } int main() {     int **arr2d,i,j,r,c;      r=4;     c=5;     //在堆中开辟一个4×5的二维int数组     arr2d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             arr2d[i][j]=i*c+j;         }     }     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             printf(" %2d",arr2d[i][j]);         }         printf("\n");     }     deletearr2d(arr2d,r);      r=6;     c=3;     //在堆中开辟一个6×3的二维int数组     arr2d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             arr2d[i][j]=i*c+j;         }     }     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             printf(" %2d",arr2d[i][j]);         }         printf("\n");     }     deletearr2d(arr2d,r);      return 0; } //  0  1  2  3  4 //  5  6  7  8  9 // 10 11 12 13 14 // 15 16 17 18 19 //  0  1  2 //  3  4  5 //  6  7  8 //  9 10 11 // 12 13 14 // 15 16 17 //

for reference only,code for c99 only; #include <stdio.h>  int main(void) { 	// your code goes here 	int n,m; 	scanf("%d%d",&n,&m); 	int a[m][n]; 	return 0; }

参考 http://blog.chinaunix.net/uid-20698826-id-3085718.html

http://bbs.csdn.net/topics/390952047  看这个帖子

参考 http://blog.sina.com.cn/s/blog_5fd837410100n0fh.html


Question: strncpy()？

为什么不用memcpy呢？ memcpy Copies characters between buffers.  void *memcpy( void *dest, const void *src, size_t count );  Routine Required Header Compatibility  memcpy <memory.h> or <string.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  memcpy returns the value of dest.  Parameters  dest  New buffer  src  Buffer to copy from  count  Number of characters to copy  Remarks  The memcpy function copies count bytes of src to dest. If the source and destination overlap, this function does not ensure that the original source bytes in the overlapping region are copied before being overwritten. Use memmove to handle overlapping regions.  Example  /* MEMCPY.C: Illustrate overlapping copy: memmove  * handles it correctly; memcpy does not.  */  #include <memory.h> #include <string.h> #include <stdio.h>  char string1[60] = "The quick brown dog jumps over the lazy fox"; char string2[60] = "The quick brown fox jumps over the lazy dog"; /*                           1         2         3         4         5  *                  12345678901234567890123456789012345678901234567890  */  void main( void ) {    printf( "Function:\tmemcpy without overlap\n" );    printf( "Source:\t\t%s\n", string1 + 40 );    printf( "Destination:\t%s\n", string1 + 16 );    memcpy( string1 + 16, string1 + 40, 3 );    printf( "Result:\t\t%s\n", string1 );    printf( "Length:\t\t%d characters\n\n", strlen( string1 ) );     /* Restore string1 to original contents */    memcpy( string1 + 16, string2 + 40, 3 );     printf( "Function:\tmemmove with overlap\n" );    printf( "Source:\t\t%s\n", string2 + 4 );    printf( "Destination:\t%s\n", string2 + 10 );    memmove( string2 + 10, string2 + 4, 40 );    printf( "Result:\t\t%s\n", string2 );    printf( "Length:\t\t%d characters\n\n", strlen( string2 ) );     printf( "Function:\tmemcpy with overlap\n" );    printf( "Source:\t\t%s\n", string1 + 4 );    printf( "Destination:\t%s\n", string1 + 10 );    memcpy( string1 + 10, string1 + 4, 40 );    printf( "Result:\t\t%s\n", string1 );    printf( "Length:\t\t%d characters\n\n", strlen( string1 ) ); }   Output  Function:   memcpy without overlap Source:      fox Destination:   dog jumps over the lazy fox Result:      The quick brown fox jumps over the lazy fox Length:      43 characters  Function:   memmove with overlap Source:      quick brown fox jumps over the lazy dog Destination:   brown fox jumps over the lazy dog Result:      The quick quick brown fox jumps over the lazy dog Length:      49 characters  Function:   memcpy with overlap Source:      quick brown dog jumps over the lazy fox Destination:   brown dog jumps over the lazy fox Result:      The quick quick brown dog jumps over the lazy fox Length:      49 characters   Buffer Manipulation Routines  See Also   _memccpy, memchr, memcmp, memmove, memset, strcpy, strncpy

char [ ] 字符数组类型，sizeof返回整个数组的占用的字节数 char * 字符指针类型，sizeof返回指针类型的字节数，32位系统是4字节  strlen的话，遇到  \0  就终止  想要长度的话，视具体情况而定

请查看strncpy的函数原型 strncpy(char*,char*,n),不是你说的数组，可能你传进去实参是数组名，但是会被转化为char*，sizeof（）-1，至于为什么-1，是因为字符串后面有个\0 你使用sizeof(array)/sizeof(*array),这个很好解释，因为char是1个字节，int是4个字符，这样计算可以统一，不能是什么类型，sizeof(*array)代表的是一个元素的大小，而sizeof(array)整个实参所有数据的大小

//不管什么数据类型都是这样 sizeof(a) / sizeof(a[0])

不对吧，sizeof使计算字节数的，要元素可以用strlen()，如果字符数组，存字符串，字符串元素小于串长你就不对了，char str[100]="China"; int a=sizeof(str);//a为100 int b = strlen(str);//b为5

sizeof(str1)-1 计算的当然不是数组元素个数   sizeof(str1)/sizeof(*str1)是通用的方法 能计算任何数组的元素个数 sizeof(str1) 只能计算出char[] 的元素个数 对于其他类型的数组计算的是 所占内存块的大小不是元素个数

1 肯定是对的  字符数组中每个元素都是一个字节（char）  *str1 代表数组的首元素也是个char sizeof(str1)代表数组所占字节数


Question: 急！！45度角：float a = tan(45.0f) 为什么不等于1而是等于1.6197

改为 tan(PI/4)  引用 楼主 z__j__s 的回复:45度角： float a = tan(45.0f) 为什么不等于1而是等于1.6197，４５度角tan应该等于１啊 46度角： float b = tan(46.0f);为什么是等于 -2.086, 第一限象的角tan怎么会有负数

tan, tanh Calculate the tangent (tan) or hyperbolic tangent (tanh).  double tan( double x );  double tanh( double x );   Parameter  x  Angle in radians  角度要弧度

单位是弧度.


Question: C语言 帮慢看看这题关于加减问题的

for reference only #include<stdlib.h> #include<string.h> #include<stdio.h> int main() { 	char buffer[100]; 	char ch; 	int num[11]; 	char symbol[10]; 	int result ; 	int n = 0;//运算次数 	memset(num,0,sizeof(num)); 	scanf("%s",buffer);  	for(int i = 0; i < strlen(buffer); ++i) 	{ 		ch = buffer[i]; 		if(ch <= '9' && ch >= '0') 		{ 			 num[n] = 10 * num[n] + ch - '0'; 		} 		else if(ch == '+' || ch == '-') 		{ 			//保存运算符 			symbol[n++] = ch; 		} 		else if(ch == ' ') 			continue; 		else 		{ 			fprintf(stderr,"表达式包含非法符号\n"); 			exit(EXIT_FAILURE); 		} 	}  	result = num[0]; 	for(int j = 0 ; j < n;) 	{ 		switch(symbol[j++]) 		{ 			case '+':result = result + num[j]; 					 break; 			case '-':result = result - num[j]; 					 break; 			default: fprintf(stdout,"error\n"); 				    break; 		} 	}  	printf("%d\n",result);  	exit(EXIT_SUCCESS); }

你可以定义一个固定大小的buff[MAX]，然后整体读入scanf/fgets. 再你对buff里的内容进行指定的分析(数字还是符号)。  示例：  #define MAX 100 int a[MAX]; scanf("%s",a); anyle(a); ......  input:123+456-789

引用 1 楼 user-2 的回复:scanf("%d%c%d",....) 你不需要加空格吧我输入的是字符串，例如：char a[]='123' 然后用atoi函数转换，atoi是把字符串转换成长整型数的一种函数

scanf("%d%c%d",....) 你不需要加空格吧


Question: 谁有图像序列检测中管道滤波算法的代码

楼主你好，我最近也在找这个代码，你找到了吗？


Question: 《C程序设计语言》第六章6.6表查找例子中np->next = hashtab[hashval]; hashtab[hashval]=np;这句怎么解释

np->next=hashtab[hashval]; //链表是从后面往前连接，当你新建一个nlist *(name,defn)到链表中，这条语句把新建的nlist *(name,defn)的next指向链表的前面。 hashtab[hashval]=np;            //把hashtab[hashval]指向新建的nlist *(name,defn)。 free((void *)np->defn);            //只是由于当执行if( (np=lookup(name) )==NULL)语句后，指针指向的是链表中的defn,而不是新建nlist*(name,defn)中defn,所以要把它free.

能静下心来仔细分析代码是第一步。先好好分析吧

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  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对应的汇编并单步执行观察相应内存和寄存器变化。）  想要从本质上理解C指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  不要企图依赖输出指针相关表达式...的值【比如printf("%p\n",...);或者cout<<...】来理解指针的本质， 而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=(void *)(...);】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495


Question: 寻求一些建议，关于异步编程

只好不满意结贴么？

引用 7 楼 zhao4zhong1 的回复:建议楼主先确认你的代码的性能和IOCP或epoll在一个数量级上再说。  IO本质上还是用iocp或epoll，只是原来是       线程 回调 业务函数  现在是：     把业务函数做成“协程”，或者叫 fiber一类的。这样可以让业务流程更符合人类的直觉。  fiber这类东西都是用户态的，根本无需切换到内核上下文，所以，性能不是问题。

建议楼主先确认你的代码的性能和IOCP或epoll在一个数量级上再说。

引用 5 楼 zhao4zhong1 的回复:屌丝们在纠结异步的时候，Windows已经进化到IOCP了。  楼主搜"epoll"  epoll和iocp只是我这个玩意儿的部分的底层实现。  你可能还没看好问题捏。  我实现了一个类似c#的async/await机制，  比如， 一般iocp是这样的编程机制：     在线程A：      obj->callback = sent_callback;      WSASend（ 。。。。 ）      在线程B：      GetQueued。。（。&obj。）      obj->callback ( obj .... )            都是回调处理，obj是一个自动机，维护一个跟“业务相关”的状态值。  现在我的编程模型是：       op = async_send( ....  )；     。。。。。      async_wait ( op )；   这看起来像同步，没错，就是要这种效果： 异步问题，同步化处理。       但在  async_wait 的时候，当前线程被回收了，当等到op时，线程又恢复了。  也就是说，这种模型的写法跟同步一样，但外部规格却是异步的，处理N多业务，只是使用固定的线程数量。


理解和讨论之前请先学会如何观察！

这个问题不看对应汇编代码和堆栈内容很难彻底弄清楚。  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  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对应的汇编并单步执行观察相应内存和寄存器变化。）

引用 1 楼 sinservice 的回复:#define va_start(ap,v)  ( ap = (va_list)&v + _INTSIZEOF(v) )   ap是指 va_list 变量 v 是指 ...之前的那个形参，如：    int print( char const *fmt, ...  )  {       va_list  va;       va_start(va, fmt);                 .....  va_arg(va, .......)  .....        va_end(va);  }    va_list是个字符型指针吧？

VS IDE中，在不明白的符号上点鼠标右键，选转到定义。

引用 4 楼 zhao4zhong1 的回复:理解和讨论之前请先学会如何观察！ 膜拜赵老师，问题找到了，不是什么函数只不过是个宏而已，我想复杂了


Question: 将数组中的n个整数按相反顺序存放.

for(i=0;i<(n-1)/2;i++)  "i<"漏掉了，楼主要细心啊

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

void swap(int a[],int n) { int i,j,temp; for(i=0;i<(n-1)/2;i++)//这漏了i< { j=n-1-i; temp=a[i];a[i]=a[j];a[j]=temp; } }

for(i=0;(n-1)/2;i++) ===> for (i = 0; i < (n - 1) / 2; i++)


Question: 看一看这个字符串的问题

数组b分配的空间少了

然后 你的问题是什么 自己说清楚  贴图什么都没说明 能问的东西太多  没人知道你想知道什么

b[10]太短  数组越界 而且b 没有字符串尾部的0

这是为什么了


Question: 关于头文件和.nsmap的问题

soap的结构体定义文件的开头要么使用条件编译#if/#endif要么用#pragma once


Question: C语言初学者求解答，这个程序哪里出问题了？

请教各位，这个程序有更好的实现方式吗？或者哪些地方还可以改进？

请教各位，这个程序有更好的实现方式吗？或者哪些地方还可以改进？

@fly_dragon_fly 发现了，感谢~！

str [i] = str [length - i] 差1

@misskissC 是不是还有其次。。？

int i, length;       while (str[i++])        //length用来保存字符串的长度         length++;  首先，i和length未经赋值


Question: 我和我老师找了两节课都没找到的错误（图的BFS遍历）求挑错

求帮忙

引用 11 楼 zhao4zhong1 的回复:在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。

在Console中简单GDI绘图参考： #pragma comment(lib,"user32") #pragma comment(lib,"gdi32") #include <stdio.h> #include <stdlib.h> #include <time.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;     int i,x,y;       srand(time(NULL));     system("color F0");     system("cls");     HideTheCursor();     hwnd  = GetConsoleWindow();     hdc   = GetDC(hwnd);     hfont = CreateFont(48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "华文楷体");     SelectObject(hdc,hfont);     TextOut(hdc,10,10,"地球人都知道！",14);     MoveToEx(hdc,5,5,NULL);     LineTo(hdc,300,  5);     LineTo(hdc,300, 60);     LineTo(hdc,  5, 60);     LineTo(hdc,  5,  5);     for (i=0;i<100;i++) {         x=rand()%400;         y=rand()%300;         SetPixel(hdc,x,y,0);     }     DeleteObject(hfont);     ReleaseDC(hwnd,hdc);     getchar();     system("color 07");     system("cls");     ShowTheCursor();     return 0; }

如楼上，自己写一小段代码或函数在程序中几乎每一步将复杂数据结构显示为人最容易看明白的格式，是调试处理复杂数据结构程序的 基础设施。  不要依赖IDE的watch窗口来调试处理复杂数据结构的程序。  显示图可以用GDI绘图或Console文本绘图。 Console文本绘图参考下面： #include <windows.h> #include <stdio.h>  void ConPrint(char *CharBuffer, int len); void ConPrintAt(int x, int y, char *CharBuffer, int len); void gotoXY(int x, int y); void ClearConsole(void); void ClearConsoleToColors(int ForgC, int BackC); void SetColorAndBackground(int ForgC, int BackC); void SetColor(int ForgC); void HideTheCursor(void); void ShowTheCursor(void);  int main(int argc, char* argv[]) {    HideTheCursor();    ClearConsoleToColors(15, 1);    ClearConsole();    gotoXY(1, 1);    SetColor(14);    printf("This is a test...\n");    Sleep(5000);    ShowTheCursor();    SetColorAndBackground(15, 12);    ConPrint("This is also a test...\n", 23);    SetColorAndBackground(1, 7);    ConPrintAt(22, 15, "This is also a test...\n", 23);    gotoXY(0, 24);    SetColorAndBackground(7, 1);    return 0; }  //This will clear the console while setting the forground and //background colors. void ClearConsoleToColors(int ForgC, int BackC) {    WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);    //Get the handle to the current output buffer...    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    //This is used to reset the carat/cursor to the top left.    COORD coord = {0, 0};    //A return value... indicating how many chars were written    //not used but we need to capture this since it will be    //written anyway (passing NULL causes an access violation).    DWORD count;     //This is a structure containing all of the console info    // it is used here to find the size of the console.    CONSOLE_SCREEN_BUFFER_INFO csbi;    //Here we will set the current color    SetConsoleTextAttribute(hStdOut, wColor);    if(GetConsoleScreenBufferInfo(hStdOut, &csbi))    {       //This fills the buffer with a given character (in this case 32=space).       FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);        FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       //This will set our cursor position for the next print statement.       SetConsoleCursorPosition(hStdOut, coord);    } }  //This will clear the console. void ClearConsole() {    //Get the handle to the current output buffer...    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    //This is used to reset the carat/cursor to the top left.    COORD coord = {0, 0};    //A return value... indicating how many chars were written    //   not used but we need to capture this since it will be    //   written anyway (passing NULL causes an access violation).    DWORD count;    //This is a structure containing all of the console info    // it is used here to find the size of the console.    CONSOLE_SCREEN_BUFFER_INFO csbi;    //Here we will set the current color    if(GetConsoleScreenBufferInfo(hStdOut, &csbi))    {       //This fills the buffer with a given character (in this case 32=space).       FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       //This will set our cursor position for the next print statement.       SetConsoleCursorPosition(hStdOut, coord);    } }  //This will set the position of the cursor void gotoXY(int x, int y) {    //Initialize the coordinates    COORD coord = {x, y};    //Set the position    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); }  //This will set the forground color for printing in a console window. void SetColor(int ForgC) {    WORD wColor;    //We will need this handle to get the current background attribute    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    CONSOLE_SCREEN_BUFFER_INFO csbi;     //We use csbi for the wAttributes word.    if(GetConsoleScreenBufferInfo(hStdOut, &csbi))    {       //Mask out all but the background attribute, and add in the forgournd color       wColor = (csbi.wAttributes & 0xF0) + (ForgC & 0x0F);       SetConsoleTextAttribute(hStdOut, wColor);    } }  //This will set the forground and background color for printing in a console window. void SetColorAndBackground(int ForgC, int BackC) {    WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);;    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), wColor); }  //Direct console output void ConPrint(char *CharBuffer, int len) {    DWORD count;    WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), CharBuffer, len, &count, NULL); }  //Direct Console output at a particular coordinate. void ConPrintAt(int x, int y, char *CharBuffer, int len) {    DWORD count;    COORD coord = {x, y};    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    SetConsoleCursorPosition(hStdOut, coord);    WriteConsole(hStdOut, CharBuffer, len, &count, NULL); }  //Hides the console cursor void HideTheCursor() {    CONSOLE_CURSOR_INFO cciCursor;    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if(GetConsoleCursorInfo(hStdOut, &cciCursor))    {       cciCursor.bVisible = FALSE; 	  SetConsoleCursorInfo(hStdOut, &cciCursor);    } }  //Shows the console cursor void ShowTheCursor() {    CONSOLE_CURSOR_INFO cciCursor;    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if(GetConsoleCursorInfo(hStdOut, &cciCursor))    {       cciCursor.bVisible = TRUE; 	  SetConsoleCursorInfo(hStdOut, &cciCursor);    } }

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

printf("读入(vi-vj)的顶点对序号");     scanf("%d,%d",&i,&j);           int i = LocateVex(G, i);            int j = LocateVex(G, j);   至少这里是错误的，编译器会提示你的。i和j 的定义范围类有其他的i 和 j 的定义，并且被引用了。  先修改了这里再说。否则int i = LocateVex(G, i); 后面那个 i 的值是为赋值的。

标题写的不错

这只能加断点逐步调试的，F9  + F10

求解！求解

果断换个合格的老师吧。


Question: 求余数

11 楼谢了。

% 计算多次跟一次是一样的？ 也就是 a%b == a%b%b == a%b%b%b   ... %也可以说是一个幂等操作了

引用 6 楼 u014444402 的回复:aa%m = (a*10+a)%m = (a*10%m+a%m)%m =  (a*10%m+a)%m 正解！这就是简单的数论问题

谢谢  6  8  楼，帮我解释一下，谢了。

7楼    aa是十位是a各位也是a的数。。。    8  楼   这个是数论吗？怎么得出这个结论的。网上看了一下没有太明白

aa%m==（a*10%m+a）%m aa是说一个数还是一个2位数十位是a个位是a？

对不起，，表达的不清楚。。我想问的是   aa%m==（a*10%m+a）%m  这个样子为什么是对的，怎样推出来这个的。

表达式必须是可修改的左值，VS和GCC都没有通过编译，不建议这么写。 楼主的编译器允许这样的行为，那要追究楼主的编译器把程序编译成了什么样子，然后才能得出这样的语法合法是什么意思。

右边的余数赋给左边的余数  不知道有什么意义

根据表达式优先级计算就是了


Question: 求大神帮忙这个bounty hunter小弟实在不会编

别沉啊。。。

小弟跪求源代码。。。


Question: C语言字符串的问题，不是很懂，求解答！

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

懂了，谢谢了

引用 2 楼 USE_R_NAME 的回复:谢谢，后面的懂了，第一个问题还有点疑问。 for(i=0;i<n;i++)  {  scanf("%s",string[i]);  } 那在输入的这个过程中[i][j]都是怎么变化的啊？就像我这像输入 先输入个4 然后as bs cs ds        string[0]，[1]，[2]，[3]表示的是占得是第几行。。然后后边的[j]，表示的就是字符串的具体内容呗？ string[0]存储as  string[0][0]存储a  string[0][1]存储s   其他的以此类推

首先  因为你定义的是字符数组  就像一个矩阵 每个方格里放一个字符  scanf("%s",string[i]); 输入一个字符串 而c语言里字符串使用字符数组存储的  矩阵的一行代表输入的一个字符串   第二个问题  因为%s输入的是字符串  遇到换行 就会认为一个字符串结束  开始一个新的字符串  换行会自动去掉的


Question: 约瑟夫问题

为什么多次循环后还是减n

[1，n]，看成重复的， p是总步长，p<n，显示就是出局的人， 看第一次p>n时，先不考虑出局人，则应该落在p-n处，现在考虑前面有多少人出局，只需要考虑在[1，p-n-1]之间有多少人出局，步长为m， 出局之后就变成以m-1为间隔了，所以 出局为(p-n-1)/(m-1) , 加上刚才的p-n为实际位置，循环这过程一直到p<n

第二个while要是多次循环有咋理解

我想知道我上面发的那个算法的解释

用list简单，它是循环双链，iterator不停advance就可以了

<pre name="code" class="cpp">#include <iostream> #include <list> #include <vector> #include <algorithm> using namespace std; vector<int> yuesefeng(int n,int m); void main() { 	int n,m; 	cin>>n>>m; 	vector<int> out; 	out=yuesefeng(n,m); 	int i,len=out.size(); 	for(i=0;i<len;i++) 		cout<<out[i]<<" "; 	system("pause"); } vector<int> yuesefeng(int n,int m)//n代表初始人数，m代表初始号码 { 	vector<int> out; 	list<int> in; 	list<int>::iterator pos; 	int i; 	for(i=1;i<=n;i++) 		in.push_back(i); 	pos=in.begin(); 	int kk=m;     while(in.size()!=0) 	{	 		if(kk!=1) 		  { 			  pos++; 			  kk--; 		   if(pos==in.end())//注意要判断是否到尾部了，到尾部就指向头部 			pos=in.begin(); 		   } 		else 		{ 			out.push_back(*pos);//到数了，点到的人保存到输出 			pos=in.erase(pos);///将此人从列表中删除，注意erase返回的是下个人的指针 			if(pos==in.end()) 				pos=in.begin(); 		}	     	} 	return out; }  这是我以前写的，用stl 中的list来做，你可以参考下


Question: 源代码贴出大家来看看++++++

Format Specification Fields: scanf and wscanf Functions A format specification has the following form:  % [width] [{h | l | I64 | L}]type  The format argument specifies the interpretation of the input and can contain one or more of the following:   White-space characters: blank (' '); tab ('\t'); or newline ('\n'). A white-space character causes scanf to read, but not store, all consecutive white-space characters in the input up to the next non–white-space character. One white-space character in the format matches any number (including 0) and combination of white-space characters in the input.   Non–white-space characters, except for the percent sign (%). A non–white-space character causes scanf to read, but not store, a matching non–white-space character. If the next character in stdin does not match, scanf terminates.   Format specifications, introduced by the percent sign (%). A format specification causes scanf to read and convert characters in the input into values of a specified type. The value is assigned to an argument in the argument list.  The format is read from left to right. Characters outside format specifications are expected to match the sequence of characters in stdin; the matching characters in stdin are scanned but not stored. If a character in stdin conflicts with the format specification, scanf terminates, and the character is left in stdin as if it had not been read.  When the first format specification is encountered, the value of the first input field is converted according to this specification and stored in the location that is specified by the first argument. The second format specification causes the second input field to be converted and stored in the second argument, and so on through the end of the format string.  An input field is defined as all characters up to the first white-space character (space, tab, or newline), or up to the first character that cannot be converted according to the format specification, or until the field width (if specified) is reached. If there are too many arguments for the given specifications, the extra arguments are evaluated but ignored. The results are unpredictable if there are not enough arguments for the format specification.  Each field of the format specification is a single character or a number signifying a particular format option. The type character, which appears after the last optional format field, determines whether the input field is interpreted as a character, a string, or a number.   The simplest format specification contains only the percent sign and a type character (for example, %s). If a percent sign (%) is followed by a character that has no meaning as a format-control character, that character and the following characters (up to the next percent sign) are treated as an ordinary sequence of characters, that is, a sequence of characters that must match the input. For example, to specify that a percent-sign character is to be input, use %%.  An asterisk (*) following the percent sign suppresses assignment of the next input field, which is interpreted as a field of the specified type. The field is scanned but not stored.  在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。

int temp; 	scanf("%d",&temp);//吃掉回车 	scanf("%s",&z); 	while(z=='z')

scanf("%d",&cc[i]); 如果你输入10个数字 则会正常 但是如果输入字母 循环输入就会结束 字母解释成了数字 直接读完  然后下面的输入 楼上说的对 因为把回车接收了

因为回车还在输入缓冲区中 所以输入单个字符的代码， 不能接收到新输入的字符，只能收到回车


Question: 汇编问题，sse的movdqa指令报错

1. 可能IDE对源代码修改处理后再交给编译器。 2. 按照Intel的习惯，例如这句movdqa XMM0,  [eax]，内存寻址应该加上指针类型，（猜的）

寄存器前加%%，比如%%xmm0

经测试，源代码不做任何改动，6.15、7.0、8.0、9.0均可编译

我查过了，movdqa，pshufd，pshuflw都是sse2的指令，而我现在的.xmm只是开启了sse的寄存器，是不是还有类似的打开sse2的指令的伪指令呢？？？？

引用 2 楼 movsd 的回复:需要6.15以上的ml.exe才支持SSE2指令  安装了8.0，试过后还是不行的

严重怀疑楼主用的汇编器版本过低或有缺陷。


Question: 单链表逆序错误

这是我参考http://blog.csdn.net/autumn20080101/article/details/7607148 修改楼主的程序，仅供参考  #include <stdio.h> #include <stdlib.h> #include <string.h>  typedef struct list { 	char name[20]; 	int grade; 	int num; 	struct list *next; }student;  student * listInversion(student *head) { 	student *newHead; 	if((head == NULL) || (head->next == NULL)) 		return head; 	newHead = listInversion(head->next); /*递归部分*/ 	head->next->next = head; /*回朔部分*/     head->next = NULL;     return newHead; }  int main(void) { 	int i; 	student *ptr, *pnode; 	student *node = (student *)malloc(sizeof(student)); 	printf("请输入2个学生数据：\n"); 	printf("请输入座号："); 	scanf("%d", &node->num); 	printf("请输入姓名："); 	scanf("%s", node->name); 	printf("请输入成绩："); 	scanf("%d",&node->grade); 	ptr = node;//node表示头结点指针 	for (i=1;i<2;++i) 	{ 		pnode = (student *)malloc(sizeof(student)); 		printf("请输入座号："); 		scanf("%d", &pnode->num); 		printf("请输入姓名："); 		scanf("%s", pnode->name); 		printf("请输入成绩："); 		scanf("%d",&pnode->grade); 		pnode->next = NULL; 		ptr->next = pnode; 		ptr = ptr->next; 	} 	//输出单链表 	ptr = node; 	while(ptr) 	{ 		printf("%s\t%d\t%d\n", ptr->name, ptr->grade, ptr->num); 		ptr = ptr->next; 	} 	 	//单链表逆序 	ptr = listInversion(node); 	printf("逆序后输出\n"); 	while(ptr) 	{ 		printf("%s\t%d\t%d\n", ptr->name, ptr->grade, ptr->num); 		ptr = ptr->next; 	} 	return 0; }  下面是运行结果：

listInversion(node, stu2)的调用不会改变实参stu2指针的指向。

引用 4 楼 hamiltonpro 的回复:我的代码中main调用listInversion后返回的却是逆序后头结点前一个结点的数据。  引用 3 楼 zhao4zhong1 的回复: then  逻辑有问题

仅供参考//不带表头结点的单向链表 #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) {         ta=(struct NODE **)malloc(n*sizeof(struct NODE *));         if (NULL==ta) exit(1);         s=head;         for (i=0;i<n;i++) {             ta[i]=s;             s=s->next;         }         head=ta[n-1];         for (i=n-1;i>0;i--) {             ta[i]->next=ta[i-1];         }         ta[0]->next=NULL;         free(ta);     }      //输出整个单链表     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-> //

你这里一堆错误，  //student *node = malloc(sizeof(student));修改为 student *node = (student *)malloc(sizeof(student)); //pnode = malloc(sizeof(student));修改为 pnode = (student *)malloc(sizeof(student));  改完之后，能运行了，剩下还有问题就需要你自己去调试了

神马错误都不说。。还要自己运行找？


Question: 为什么我设的指针函数在调用完后，形参不释放？？？（小弟有强迫症，不弄个明白睡不着觉啊！）

你需要先搞明白释放的含义，所谓的释放是指告诉系统指定地址空间的内存已经不再使用，可以回收后再次分配了。如果没有再次被分配出去的话那块内存里的实际数据是不会被变更的（这句话并不绝对，因为理论上那块地址空间你已经宣布不再使用了，如果你等待足够的时间或者sleep 的足够久导致你的程序被swap过的话，就有可能出现未知结果）。 其实 你只需要稍微改下代码就能体会到这个释放的具体含义了就是在 p=min(a,b);            //返回最小值的地址 int a[] = { 1,2,3,4,5,6,8,10,12,13,14,15,16 } printf("min=%d\n",*p);  //输出最小值 这时输出的值如果是64程序的话 并且 a < b 则为 3  如果 a > b 则为4 （具体的可能有偏差但一定是a数组里的某一个数，32为相同原理） 另外再说下int *minp(int *i,int *j) {   int *q;      q=*i<*j?i:j;       return (q);  //指针变量q作为指针函数的返回值 } 这种写法是不妥的因为当minp执行完毕return的时候 q已经被弹出栈了，在c语言里看不出差别，但是在C++里面就有很大的区别 因此如果 这不是int *q 而是一个类对象的话 如（string list等）会调用其析构函数，导致你最后返回的值是一个奇怪的东西，如果该类是一个具有虚函数的类的话，将其返回值付给另一个对象会导致出现一个被析构过的对象，最严重的问题就是其虚指针会被重置！

栈中的基本变量退出其作用域时，没有谁执行一段代码去释放/销毁/析构它所占用的内存，仅仅是没人再去理会的留在当前栈顶上方的若干遗留下来可被后续压栈操作覆盖的无用数据而已。 而栈中的类变量退出其作用域时，会自动执行其析构函数，……  其实电脑开机后物理内存的每个字节都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  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对应的汇编并单步执行观察相应内存和寄存器变化。）

先换个编译器，那个警告是不应该出现的。

引用 2 楼 qq_24594481 的回复:谢谢你的回复。 我还有如下问题 1.每次输入，都是输出最小值！！！不会变啊。 2.其实跟申请堆上的内存是一样的   如： int* pInt = new int;   这里是想堆申请一块内存 *pInt = 3;  delete pInt;  printf("%d",*p);  这里是可以答应值的  是什么意思？（请原谅新手的无知）  那请楼主去看入门书籍了，先得知道是什么，才可以问为什么。

指针消亡了，并不表示它所指的内存会被自动释放。同样，内存被释放了，并不表示指针会消亡或者成了 NULL 指针。

再给你补充点只是 所谓调用函数其实跟局部变量类似，他会先在栈顶压入函数指针，然后在按照从左到右的顺序加入形参（根据编译器的不同这个顺序可能会不一样），你最后返回的那个指针其实就是指向这些形参位置的指针。在函数执行完毕后，他们会从栈里弹出来（其实就是把栈顶标记又缩回去了）这个时候如果你在声明临时变量的话，就会被分配到刚刚被调用的那个函数所使用的位置。其实程序的本质就是一个清理栈的过程，当栈被清理干净的时候程序也就运行完毕

没释放，运气好也是不好。。。

更一般的。参数为指针的时候，函数还可以返回指针运算的结果，只要可以确定指针运算的结果，所代表的地址，有个有效地址 例如：  int *get_index_n(int *a,int n) {            return a + n; }  //这个函数 //可以这么用  int main() {          int a[10] ={0,1,2,3,4,5,6,7,8,9}; int *p; p =get_index_n(a,5);// 没超过 10  printf("*p =%d",*p); //输出 a[5]的值，也就是 5 getchar(); return 0; }

C语言 只有一种参数传递方式，值传递 指针的值传递， 比较特殊，因为指针可以间接引用，它所指向的内存中的数据（对象） 而内存数据，和指针本身，有没有被替换无关， 只和指针所指的位置 即指针值有关系，  所以，虽然实参指针-----例如对象（变量）地址，数组名----， 和形参是两个变量对象， 这两个指针的地址所代表的指针变量占用的内存，是不同的，  但是指针的值是相同的， 二者所指向的内存是相同的 所以，可以返回(形参)指针本身。 这个函数，返回的实际是，所传递的实参指针的值。 只要这个值指向的对象（通常是变量，有时候是动态分配的无名对象）是有效的， 就可以在任何时候使用。  注意返回的不是指针的地址，而是指针的值 指针的地址是局部变量的地址 指针的值，其实也是实参指针的值（这就是值传递的含义）  只要函数调用时，传递的实参，是有效的地址。 返回形参指针的值，就不会有问题。

书上说：子函数调用完后，形参的内存空间释放   释放空间只是断开了一直关联的关系，内存的内容可能不变，也有可能边了。  这里你运气好，刚好没变而已  其实跟申请堆上的内存是一样的  如： int* pInt = new int;   这里是想堆申请一块内存 *pInt = 3; delete pInt; printf("%d",*p);  这里是可以答应值的  虽然delete了 但是还是能打印出值  因为，你向系统要了一块内存，然后赋值该内存，系统就知道了这块内存是你用的，别人就不能分配了，当你delete后，系统认为这块内存已经没人用了，别人也可以来申请，但如果此时没有人刚好申请这块内存，这块内存是没有变化的，所以能正常打印  但是如果有人用了，这块内存内容就不可知了...


Question: 找一个二维数组中在某位置上面的元素在该行上最大，在该列上最小，下面的程序哪里错了。

引用 1 楼 user-1 的回复: {        max=a[i][j];           }           jMax = j;           iMax = i;  应该为      {        max=a[i][j];        jMax = j;      }             这是个问题 我查出来哪里有毛病了，谢谢


Question: cygwin编译一个示例程序，遇到的奇怪的问题

引用 2 楼 mybc724 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] 在每个最后不带\n的printf后面加fflush(stdout);  这样的确是对了，但为什么没有\n，执行顺序就不对了呢，而fflush以后就对了呢？能说详细点吗？谢了啊[/quote] 发挥一下你的主观能动性。

引用 1 楼 zhao4zhong1 的回复:在每个最后不带\n的printf后面加fflush(stdout);  这样的确是对了，但为什么没有\n，执行顺序就不对了呢，而fflush以后就对了呢？能说详细点吗？谢了啊

在每个最后不带\n的printf后面加fflush(stdout);


Question: 这三个函数有问题吗？

引用 19 楼 bear234 的回复:[quote=引用 17 楼 s_a_n_ 的回复:] [quote=引用 13 楼 bear234 的回复:] [quote=引用 12 楼 q3733353520 的回复:] [quote=引用 11 楼 bear234 的回复:] [quote=引用 4 楼 q3733353520 的回复:]  int *f1(void) {     int x = 10;     return (&x);  //函数结束时会释放x的地址，有问题 }   int *f2(void) {     int *ptr;       *ptr = 10;  //出现断错误，指针指向了不该指向的地方     return ptr; }   int *f3(void) {     int *ptr;     ptr = (int *)malloc(sizeof(int));// 这种我猜测，分配的堆内存肯定可以用，                                                         //但是ptr是函数内定义的指针其内存地址被释放，不知会怎样     return ptr; }    你确定第一个有问题？？[/quote]  你是猴子请来的逗逼么？[/quote]   首先，第三个肯定没问题，你居然说“不知会怎样”  其次，对于第一个，我看一下x的地址不行吗？只不过不能通过指针修改值罢了  所以函数的返回值前面加个const更好  但你不能说第一个就错了啊～～～  看了你对第三个函数的注释，我觉得你不知道return这句话发生了什么 一个函数里，int i = 10; return i; 可以吗？你别告诉我说i被释放了.............[/quote] int i=10; return i;返回变量的值，与i是否释放无关。 int i=10; return &i;返回变量的地址，而该变量在函数栈中申请，变量的地址在变量所属函数执行期间有效，函数结束后相应的栈已经失效了，地址也跟着失效，所以返回的地址里不一定保存有原来i的值。也就是说，即便你从返回的地址里取到了10，也不能代表那样做是对的。[/quote]  我在上面说过了   第一个只能说不合适  因为我想看一下x的地址，这总没错吧  当然对此指针的任何解引用都是不对的  我们不应该把程序的正常运行建立在程序员的“小心”上，所以如果能在返回值前面加const更好 总之，虽然我也不知道看一下x的地址有什么实际的意义，但从语法上，没有错[/quote] 你是猴子请来的逗逼吗

引用 13 楼 bear234 的回复:[quote=引用 12 楼 q3733353520 的回复:] [quote=引用 11 楼 bear234 的回复:] [quote=引用 4 楼 q3733353520 的回复:]  int *f1(void) {     int x = 10;     return (&x);  //函数结束时会释放x的地址，有问题 }   int *f2(void) {     int *ptr;       *ptr = 10;  //出现断错误，指针指向了不该指向的地方     return ptr; }   int *f3(void) {     int *ptr;     ptr = (int *)malloc(sizeof(int));// 这种我猜测，分配的堆内存肯定可以用，                                                         //但是ptr是函数内定义的指针其内存地址被释放，不知会怎样     return ptr; }    你确定第一个有问题？？[/quote]  你是猴子请来的逗逼么？[/quote]   首先，第三个肯定没问题，你居然说“不知会怎样”  其次，对于第一个，我看一下x的地址不行吗？只不过不能通过指针修改值罢了  所以函数的返回值前面加个const更好  但你不能说第一个就错了啊～～～  看了你对第三个函数的注释，我觉得你不知道return这句话发生了什么 一个函数里，int i = 10; return i; 可以吗？你别告诉我说i被释放了.............[/quote]  i会被系统回收了，返回的值自动调用int类型的拷贝构造函数。 第一个函数用户对操作返回值会出现不确定性 第二个函数出现运行错误机率较大 第三个函数用户可以操作，但要用户释放内存。

引用 13 楼 bear234 的回复:[quote=引用 12 楼 q3733353520 的回复:] [quote=引用 11 楼 bear234 的回复:] [quote=引用 4 楼 q3733353520 的回复:]  int *f1(void) {     int x = 10;     return (&x);  //函数结束时会释放x的地址，有问题 }   int *f2(void) {     int *ptr;       *ptr = 10;  //出现断错误，指针指向了不该指向的地方     return ptr; }   int *f3(void) {     int *ptr;     ptr = (int *)malloc(sizeof(int));// 这种我猜测，分配的堆内存肯定可以用，                                                         //但是ptr是函数内定义的指针其内存地址被释放，不知会怎样     return ptr; }    你确定第一个有问题？？[/quote]  你是猴子请来的逗逼么？[/quote]   首先，第三个肯定没问题，你居然说“不知会怎样”  其次，对于第一个，我看一下x的地址不行吗？只不过不能通过指针修改值罢了  所以函数的返回值前面加个const更好  但你不能说第一个就错了啊～～～  看了你对第三个函数的注释，我觉得你不知道return这句话发生了什么 一个函数里，int i = 10; return i; 可以吗？你别告诉我说i被释放了.............[/quote] int i=10; return i;返回变量的值，与i是否释放无关。 int i=10; return &i;返回变量的地址，而该变量在函数栈中申请，变量的地址在变量所属函数执行期间有效，函数结束后相应的栈已经失效了，地址也跟着失效，所以返回的地址里不一定保存有原来i的值。也就是说，即便你从返回的地址里取到了10，也不能代表那样做是对的。

引用 13 楼 bear234 的回复:[quote=引用 12 楼 q3733353520 的回复:] [quote=引用 11 楼 bear234 的回复:] [quote=引用 4 楼 q3733353520 的回复:]  int *f1(void) {     int x = 10;     return (&x);  //函数结束时会释放x的地址，有问题 }   int *f2(void) {     int *ptr;       *ptr = 10;  //出现断错误，指针指向了不该指向的地方     return ptr; }   int *f3(void) {     int *ptr;     ptr = (int *)malloc(sizeof(int));// 这种我猜测，分配的堆内存肯定可以用，                                                         //但是ptr是函数内定义的指针其内存地址被释放，不知会怎样     return ptr; }    你确定第一个有问题？？[/quote]  你是猴子请来的逗逼么？[/quote]   首先，第三个肯定没问题，你居然说“不知会怎样”  其次，对于第一个，我看一下x的地址不行吗？只不过不能通过指针修改值罢了  所以函数的返回值前面加个const更好  但你不能说第一个就错了啊～～～  看了你对第三个函数的注释，我觉得你不知道return这句话发生了什么 一个函数里，int i = 10; return i; 可以吗？你别告诉我说i被释放了.............[/quote]  对于你这种无聊的人，我只能呵呵了

我只能说，我从来不纠结没意义的东西

引用 17 楼 s_a_n_ 的回复:[quote=引用 13 楼 bear234 的回复:] [quote=引用 12 楼 q3733353520 的回复:] [quote=引用 11 楼 bear234 的回复:] [quote=引用 4 楼 q3733353520 的回复:]  int *f1(void) {     int x = 10;     return (&x);  //函数结束时会释放x的地址，有问题 }   int *f2(void) {     int *ptr;       *ptr = 10;  //出现断错误，指针指向了不该指向的地方     return ptr; }   int *f3(void) {     int *ptr;     ptr = (int *)malloc(sizeof(int));// 这种我猜测，分配的堆内存肯定可以用，                                                         //但是ptr是函数内定义的指针其内存地址被释放，不知会怎样     return ptr; }    你确定第一个有问题？？[/quote]  你是猴子请来的逗逼么？[/quote]   首先，第三个肯定没问题，你居然说“不知会怎样”  其次，对于第一个，我看一下x的地址不行吗？只不过不能通过指针修改值罢了  所以函数的返回值前面加个const更好  但你不能说第一个就错了啊～～～  看了你对第三个函数的注释，我觉得你不知道return这句话发生了什么 一个函数里，int i = 10; return i; 可以吗？你别告诉我说i被释放了.............[/quote] int i=10; return i;返回变量的值，与i是否释放无关。 int i=10; return &i;返回变量的地址，而该变量在函数栈中申请，变量的地址在变量所属函数执行期间有效，函数结束后相应的栈已经失效了，地址也跟着失效，所以返回的地址里不一定保存有原来i的值。也就是说，即便你从返回的地址里取到了10，也不能代表那样做是对的。[/quote]  我在上面说过了   第一个只能说不合适  因为我想看一下x的地址，这总没错吧  当然对此指针的任何解引用都是不对的  我们不应该把程序的正常运行建立在程序员的“小心”上，所以如果能在返回值前面加const更好 总之，虽然我也不知道看一下x的地址有什么实际的意义，但从语法上，没有错

引用 16 楼 q3733353520 的回复:[quote=引用 13 楼 bear234 的回复:] [quote=引用 12 楼 q3733353520 的回复:] [quote=引用 11 楼 bear234 的回复:] [quote=引用 4 楼 q3733353520 的回复:]  int *f1(void) {     int x = 10;     return (&x);  //函数结束时会释放x的地址，有问题 }   int *f2(void) {     int *ptr;       *ptr = 10;  //出现断错误，指针指向了不该指向的地方     return ptr; }   int *f3(void) {     int *ptr;     ptr = (int *)malloc(sizeof(int));// 这种我猜测，分配的堆内存肯定可以用，                                                         //但是ptr是函数内定义的指针其内存地址被释放，不知会怎样     return ptr; }    你确定第一个有问题？？[/quote]  你是猴子请来的逗逼么？[/quote]   首先，第三个肯定没问题，你居然说“不知会怎样”  其次，对于第一个，我看一下x的地址不行吗？只不过不能通过指针修改值罢了  所以函数的返回值前面加个const更好  但你不能说第一个就错了啊～～～  看了你对第三个函数的注释，我觉得你不知道return这句话发生了什么 一个函数里，int i = 10; return i; 可以吗？你别告诉我说i被释放了.............[/quote]  对于你这种无聊的人，我只能呵呵了[/quote]   你自己去看你第一个函数的注释  x被释放，有问题 那我return任何函数内的量，他们在return后都会被释放 这是无聊有聊的问题吗？  而且你说第三个“不知道会怎样”，第三个人家明明就完全是对的ok？可见你完全不明白return发生了什么，也不明白到底什么叫“释放”

不是释放x的地址，x的地址永远在那里，是程序不能再控制或者直接使用这块内存地址了，第二个是没有内存空间，就给你变量赋值，没地方存放啊

这三个函数都有问题，问题稍微不太严重的是第三个，其他二个写出来应该就要被斩立决，第三个会造成内存泄露，记住内存在那里申请在那里释放

引用 11 楼 bear234 的回复:[quote=引用 4 楼 q3733353520 的回复:]  int *f1(void) {     int x = 10;     return (&x);  //函数结束时会释放x的地址，有问题 }   int *f2(void) {     int *ptr;       *ptr = 10;  //出现断错误，指针指向了不该指向的地方     return ptr; }   int *f3(void) {     int *ptr;     ptr = (int *)malloc(sizeof(int));// 这种我猜测，分配的堆内存肯定可以用，                                                         //但是ptr是函数内定义的指针其内存地址被释放，不知会怎样     return ptr; }    你确定第一个有问题？？[/quote]  你是猴子请来的逗逼么？

引用 12 楼 q3733353520 的回复:[quote=引用 11 楼 bear234 的回复:] [quote=引用 4 楼 q3733353520 的回复:]  int *f1(void) {     int x = 10;     return (&x);  //函数结束时会释放x的地址，有问题 }   int *f2(void) {     int *ptr;       *ptr = 10;  //出现断错误，指针指向了不该指向的地方     return ptr; }   int *f3(void) {     int *ptr;     ptr = (int *)malloc(sizeof(int));// 这种我猜测，分配的堆内存肯定可以用，                                                         //但是ptr是函数内定义的指针其内存地址被释放，不知会怎样     return ptr; }    你确定第一个有问题？？[/quote]  你是猴子请来的逗逼么？[/quote]   首先，第三个肯定没问题，你居然说“不知会怎样”  其次，对于第一个，我看一下x的地址不行吗？只不过不能通过指针修改值罢了  所以函数的返回值前面加个const更好  但你不能说第一个就错了啊～～～  看了你对第三个函数的注释，我觉得你不知道return这句话发生了什么 一个函数里，int i = 10; return i; 可以吗？你别告诉我说i被释放了.............

引用 4 楼 q3733353520 的回复: int *f1(void) {     int x = 10;     return (&x);  //函数结束时会释放x的地址，有问题 }   int *f2(void) {     int *ptr;       *ptr = 10;  //出现断错误，指针指向了不该指向的地方     return ptr; }   int *f3(void) {     int *ptr;     ptr = (int *)malloc(sizeof(int));// 这种我猜测，分配的堆内存肯定可以用，                                                         //但是ptr是函数内定义的指针其内存地址被释放，不知会怎样     return ptr; }    你确定第一个有问题？？

第一个函数结束后，空指针。。。 第二个指针指向常量。。。

对野指针所指内存写是错误的

第三个没问题， 但是最好同时提供配套的释放函数。  因为不知道这个函数，是怎么分配内存的 在不能看到源代码的情况下， 不知道如何释放分配的内存  只有分配不去释放，会造成内存泄露。 例如： C标准库， 同时提供了 malloc 和 free 两个函数。 这样就不会有，分配了无法释放的问题。  第一，第二个都是有严重问题的，会产生莫名其妙的错误。 第一个，返回局部非静态变量的地址，是错误的 第二个局部非静态变量， 指针 ptr 没有初始化，是个野指针。 对野指针写是错误的， 函数返回野指针同样是错误的。

只有第三个是对的

只有第三个没问题，但不推荐。

第二个有问题，可以自己动手调试看看呗 int *f2(void) {     int *ptr;      ptr = (int *)malloc(sizeof(int));     *ptr = 10;     return ptr; }

能运行，没问题啊


Question: 求助，谁能帮我解释一下这道题

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  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对应的汇编并单步执行观察相应内存和寄存器变化。）  想要从本质上理解C指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  不要企图依赖输出指针相关表达式...的值【比如printf("%p\n",...);或者cout<<...】来理解指针的本质， 而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=(void *)(...);】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495

引用 1 楼 sinat_24408145 的回复:int (*ptr)[3] = a; 这句话的意思是定义一个指针ptr，这个指针指向二维数组a，ptr就相当于a的地址   此时 ptr = a   (*ptr) [ 1 ] 是 a[0] [1]     (*ptr) [2]  是 a[0] [2]              ++ptr 就相当于  ++a  所以第七行应该就等于  a[1] [1]      a[1] [2] 可能表达的不太明白   我也是刚学到这  嘿嘿 楼上正解， ++ptr 相当于(a+1), a是数组名，不能++的

引用 1 楼 sinat_24408145 的回复:int (*ptr)[3] = a; 这句话的意思是定义一个指针ptr，这个指针指向二维数组a，ptr就相当于a的地址   此时 ptr = a   (*ptr) [ 1 ] 是 a[0] [1]     (*ptr) [2]  是 a[0] [2]              ++ptr 就相当于  ++a  所以第七行应该就等于  a[1] [1]      a[1] [2] 可能表达的不太明白   我也是刚学到这  嘿嘿  赞成，说的比较详细

int main() { 	int a[][3] = {1,2,3,4,5,6};   //二维数组，且第二维是3个元素 	int (*ptr)[3] = a;   //第二维是3个元素的二维数组指针 	printf("%d %d ", (*ptr)[1],(*ptr)[2]); 	++ptr; 	printf("%d %d",(*ptr)[1], (*ptr)[2]); 	return 0; }

数组指针的问题。


Question: 如图，找不出错误

引用 12 楼 tenmenglin 的回复:[quote=引用 11 楼 bumpbee 的回复:] 要是调用getch()：头文件<conio.h>应该被包含 没用conio.h不出错..[/quote] 嗯，我理解错了 关于头文件：<>和“” ，前者一般表示标准库，后者更多是程序员自定义的头文件，用的时候没什么差别，主要是编译的时候查找，我记得，<……>头文件编译时会到标准库进行查找，“ ……” 头文件一般会选择当前文件位置，找不到才到标准库 VS里面main函数是一般定义为int，如果有了，就要加return语句，你没有定义返回值，所以也可以运行， 我不理解你为何在程序末尾加getch（）；如果是为了显示结果，可以参考十楼的意见

引用 11 楼 bumpbee 的回复:要是调用getch()：头文件<conio.h>应该被包含 没用conio.h不出错..

要是调用getch()：头文件<conio.h>应该被包含

一闪而过是因为程序结束了，就把创建的控制台窗口给关了。getchar（）是获取一个字符，如果你敲过键盘，那么就有字符，获取后就过了。getch应该也一样。  你可以ctrl+F5（start without debug）来启动， 或者直接打开个控制台（cmd）窗口，然后启动你的程序， 或者用system("pause");这句，反正我觉得这句比getchar（）更好。

你最后一句可以写成while(1);//防止控制台退出

引用 6 楼 luciferisnotsatan 的回复:[quote=引用 5 楼 luciferisnotsatan 的回复:] 1 stdio.h这种头文件应该用尖括号<> 2 main函数要有返回类型 int main（） 3 getch不是标准的，getch在头文件conio.h里（如果你有这个的话） 4 发在C版，那你应该把文件后缀名改成.c，这样VS才会按C语言来编译。.cpp的话，是当C++来编的[/quote]  我刚刚改了，是第四点错了...忘改了 我倒  1.一定要<>括号吗？  我没用可以编译。 2.没有int  也可以编译 3.我用的getch依旧可以 我汗.. 据我所知（百度到的理解） getchar（）;  是立即结束 getch（）是等待输入任意键结束 我前俩天也纠结过这个问题，然后我发现在一个程序中 如果不 getchar（）； getchar（）； 就会一闪而过 而恰巧 getch() 不会 --- 那么能说说为什么可以编译不出错？这是特例情况？还是侥幸？诚心请教.

main() 函数没有类型

引用 5 楼 luciferisnotsatan 的回复:1 stdio.h这种头文件应该用尖括号<> 2 main函数要有返回类型 int main（） 3 getch不是标准的，getch在头文件conio.h里（如果你有这个的话） 4 发在C版，那你应该把文件后缀名改成.c，这样VS才会按C语言来编译。.cpp的话，是当C++来编的

引用 2 楼 luciferisnotsatan 的回复:问什么我就找到好几处问题呢？ 另外，getch不是标准C的，用getchar() 换了不对，有错误  error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int

引用 1 楼 user-5 的回复:You mean getchar() ? 这个  error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int

You mean getchar() ?


Question: DLL中输出信息的问题

你把代码贴全  或者说明白在哪里出的问题

是我马虎了  我特地试了一下  vs2005下正常写入文件

不用了，具体问题已经找到了。也给你评了分，鼓励你帮忙的热情。

引用 5 楼 windzhu0514 的回复:是内存异常吧   应该是fprintf(fp,.....);  传进去的fp是个空指针    vs和codeblocks是可以调试dll的 你可以跟一下看看 如果是空指针如果通过if(fp)的？大哥哥

引用 1 楼 zhao4zhong1 的回复:在微软网站上搜“C Run-Time Libraries (CRT)” 没问题啊，是使用的/MD啊

引用 2 楼 fly_dragon_fly 的回复:编译错误还是运行错误？ 运行错误

编译错误还是运行错误？

在微软网站上搜“C Run-Time Libraries (CRT)”


Question: realloc函数为什么如此之诡异？？？

打开的15个学生信息的 文件c 人  和  妖 之间没有一大堆空格。

打开的15个学生信息的 文件c 人  和  妖 之间没有一大堆空格。

没有看到检查realloc函数是否失败的代码。

仅供参考//输出PROG中有但LIST中没有的文本行，即集合PROG-LIST #include <stdio.h> #include <string.h> #include <stdlib.h> #include <search.h> #define MAXCHARS 512 int MAXLINES=10000,MAXLINES2; char *buf,*buf2; char PROG[256]="PROG";//程序Program需要的文件列表 char LIST[256]="LIST";//dir /b /s生成的实际文件列表List FILE *fp,*fl; int i,c,n,L,hh; int ignore_case=0; char ln[MAXCHARS]; int icompare(const void *arg1,const void *arg2) {    return stricmp((char *)arg1,(char *)arg2); } int compare(const void *arg1,const void *arg2) {    return strcmp((char *)arg1,(char *)arg2); } int main(int argc,char **argv) {     if (argc>1) strcpy(PROG,argv[1]);//命令行参数1覆盖PROG     if (argc>2) strcpy(LIST,argv[2]);//命令行参数2覆盖LIST     if (argc>3) ignore_case=1;//若存在命令行参数3，忽略大小写     if ((fl=fopen(LIST,"rt"))==NULL) {         fprintf(stderr,"Can not open %s\n",LIST);         fprintf(stderr,"Usage: %s [PROG] [LIST] [-i]\n",argv[0]);         return 1;     }     if ((fp=fopen(PROG,"rt"))==NULL) {         fclose(fl);         fprintf(stderr,"Can not open %s\n",PROG);         fprintf(stderr,"Usage: %s [PROG] [LIST] [-i]\n",argv[0]);         return 2;     }     buf=(char *)malloc(MAXLINES*MAXCHARS);     if (NULL==buf) {         fclose(fl);         fclose(fp);         fprintf(stderr,"Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES,MAXCHARS);         return 4;     }     n=0;     hh=0;     i=0;     while (1) {         if (fgets(ln,MAXCHARS,fl)==NULL) break;//         hh++;         L=strlen(ln)-1;         if ('\n'!=ln[L]) {//超长行忽略后面内容             fprintf(stderr,"%s Line %d too long(>%d),spilth ignored.\n",LIST,hh,MAXCHARS);             while (1) {                 c=fgetc(fl);                 if ('\n'==c || EOF==c) break;//             }         }         while (1) {//去掉行尾的'\n'和空格             if ('\n'==ln[L] || ' '==ln[L]) {                 ln[L]=0;                 L--;                 if (L<0) break;//             } else break;//         }         if (L>=0) {             strcpy(buf+i,ln);i+=MAXCHARS;             n++;             if (n>=MAXLINES) {                 MAXLINES2=MAXLINES*2;                 if (MAXLINES2==1280000) MAXLINES2=2500000;                 buf2=(char *)realloc(buf,MAXLINES2*MAXCHARS);                 if (NULL==buf2) {                     free(buf);                     fclose(fl);                     fclose(fp);                     fprintf(stderr,"Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES2,MAXCHARS);                     return 5;                 }                 buf=buf2;                 MAXLINES=MAXLINES2;             }         }     }     fclose(fl);     if (ignore_case) qsort(buf,n,MAXCHARS,icompare);     else qsort(buf,n,MAXCHARS,compare);     hh=0;     while (1) {         if (fgets(ln,MAXCHARS,fp)==NULL) break;//         hh++;         L=strlen(ln)-1;         if ('\n'!=ln[L]) {//超长行忽略后面内容             fprintf(stderr,"%s Line %d too long(>%d),spilth ignored.\n",PROG,hh,MAXCHARS);             while (1) {                 c=fgetc(fp);                 if ('\n'==c || EOF==c) break;//             }         }         while (1) {//去掉行尾的'\n'和空格             if ('\n'==ln[L] || ' '==ln[L]) {                 ln[L]=0;                 L--;                 if (L<0) break;//             } else break;//         }         if (L>=0) {             if (ignore_case) {                 if (NULL==bsearch(ln,buf,n,MAXCHARS,icompare)) printf("%s\n",ln);             } else {                 if (NULL==bsearch(ln,buf,n,MAXCHARS,compare)) printf("%s\n",ln);             }         }     }     fclose(fp);     free(buf);     return 0; }

ofile里，第一次空间扩充，p和stu不一样了，数据读到p里，你去打印stu自然是乱。最好是不用全局变量p...

检查realloc函数是否失败的代码   加上了后扔是这样问题 赵4老师说的对于我有点难 怎么直接修改代码  修复这个问题：第一次打开乱码，第二次打开正常

推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,fread,fwrite,fgetc,fclose  //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了

对不起 第一个帖子代码发错了 第二帖子      int k=10; //暂时分配100个学生的内存空间           注释内容错误 暂时分配10个 进入后输入5  打开c 显示  乱码 回到主界面 再输入5   打开c 结果就能打开正常显示的15个学生信息

我把全部代码发一下 一个学生成绩管理  写的非常之累赘，烂 #include<stdio.h> #include<stdlib.h> #include<string.h> #define LEN sizeof(struct info) typedef struct info{ 	int num; 	char name[10]; 	char sex[5]; 	int C; 	int gaoshu; 	int xiandai; } student; int stunum;  int k;  student *p;    void show(student stu[],int n); void addinfo(student stu[]); void sfile(student stu[]);//危险原有数据注意保存  void sort(student stu[]); void numup(student stu[],int n); void numdown(student stu[],int n); void c11(student stu[],int n); void c2(student stu[],int n); void g1(student stu[],int n); void g2(student stu[],int n); void x1(student stu[],int n); void x2(student stu[],int n); void n1(student stu[],int n); void n2(student stu[],int n); void statistics(student stu[]);  void segmentation1(student stu[],int n); void segmentation2(student stu[],int n);  void segmentation3(student stu[],int n);  void head(); int ofile(student stu[]); int menu(); /*=================================================================*/ int main() {	                                  	 printf("\t\t\t学生成绩管理系统\n"); 	 int i=1,j;    int k=10; //暂时分配100个学生的内存空间       p=(student*)malloc(k*LEN);   // 结构体动态数组，实现任意成绩单 操作      while(i>0) 	{     i=menu();    switch(i) 	 { 	    case 1:addinfo(p);break; 	    case 2:sort(p);break;  	    case 3:statistics(p); break; 		case 4:sfile(p);break; 		case 5:ofile(p);break;  		case 0:i=-1; break; 		default:i=1;break;  	 } 	} 	free(p); }  void show(student stu[],int n)   /*显示函数*/ {   int i;   head();  for(i=0;i<n;i++)  printf("%d\t%s\t%s\t%d\t%d\t%d\t\n",stu[i].num,stu[i].name,stu[i].sex,stu[i].C,stu[i].gaoshu,stu[i].xiandai);  /*通过循环输出数据*/  }  void addinfo(student stu[]) { 	int i; 	printf("请输入录入学生数目\n"); 	scanf("%d",&stunum); 	for(i=0;i<stunum;i++) 	{  	printf("请输入学生学号（8位）\n");     scanf("%d",&p[i].num); 	printf("请输入学生姓名\n");     scanf("%s",p[i].name); 	printf("请输入学生性别\n"); 	scanf("%s",p[i].sex);  //本身地址不用取地址     	printf("请输入C语言成绩\n");     scanf("%d",&p[i].C); 	printf("请输入线代成绩\n");     scanf("%d",&p[i].gaoshu); 	printf("请输入高数成绩\n"); 	scanf("%d",&p[i].xiandai); 	} 	show(stu,stunum) ; 	getchar();  //不用的话 空格带入缓冲区 造成目录循环你可以感受一下 } void sfile(student stu[]) { 	int i=0; 	char filename[20]; 	FILE* fp; 	printf("请输入文件名\n"); 	gets(filename);  	fp=fopen(filename,"w");         fprintf(fp,"%d\n",stunum);   	for(i=0;i<stunum;i++) 	fprintf(fp,"%d %s %s %d %d %d",p[i].num,p[i].name,p[i].sex,p[i].C,p[i].gaoshu,p[i].xiandai);  //一会加头 	fclose(fp);  	printf("已存储\n");  } int ofile(student stu[]) { 	int l=10; 	int i=0; 	char k[2]; //K为显示控制 	FILE* fp; 	char filename[20]; 	printf("请输入默认路径文件名或者文件路径:\n");      gets(filename);      stunum=0;      if((fp=fopen(filename,"rb+"))==NULL)   //rb---r 	{      printf("无法打开文件\n");      return(-1); 	}    fscanf(fp,"%d",&stunum);   if(stunum>l)  {   	l=l+50;  	p=(student*)realloc(p,l*LEN);}   fgetc(fp);      while(i<stunum)  	{      fscanf(fp,"%d",&p[i].num);      fscanf(fp,"%s",p[i].name);      fscanf(fp,"%s",p[i].sex);      fscanf(fp,"%d",&p[i].C);      fscanf(fp,"%d",&p[i].gaoshu);      fscanf(fp,"%d",&p[i].xiandai);      i++;  	}      fclose(fp);     	printf("文件读取成功\n"); 	printf("是否显示文件内容？(是y)"); 	gets(k); 	if(k[0]=='y'||k[0]=='Y')     show(stu,stunum);     else  	return(0); } int menu() { 	char m;     printf("请选择\n");     printf("1、录入    2、排序    3、统计    4、保存    5、打开    0、退出\n") ;    	m=getchar();//这里不加getchar就等死吧  	getchar();  	return (m-'0'); } void head() {  printf("学号\t        姓名\t性别\tC语言\t高数\t线代\t\n"); } void sort(student stu[]) { 	int i;  	char j;   printf("请输入排序方式\n");  printf("1、学号 2、姓名 3、成绩\n"); //为什么不敢用数字  i=getchar();  getchar();  i=i-'0';   //用再get下么     switch(i)    { case 1: {  printf("1、升序 2、降序\n");  j=getchar();  getchar();  if(j-'0'==1)   //这里如果赋值就会两个都执行 千万别赋值  {numup(p,stunum);} else {numdown(p,stunum);} break;  case 3: printf("请选择排序的科目:\n"); printf("1、C语言  2、高数  3、线代:\n"); int x; char c1; x=getchar(); getchar(); if(x-'0'==1) {printf("请选择排序方式:1、升序 2、降序\n");  c1=getchar(); getchar(); if(c1-'0'==1) c11(p,stunum); if(c1-'0'==2) c2(p,stunum); } if(x-'0'==2) { printf("请选择排序方式:1、升序 2、降序\n");  c1=getchar(); getchar(); if(c1-'0'==1) g1(p,stunum); if(c1-'0'==2) g2(p,stunum); } if(x-'0'==3) { printf("请选择排序方式:1、升序 2、降序\n");  c1=getchar(); getchar(); if(c1-'0'==1) x1(p,stunum); if(c1-'0'==2) x2(p,stunum); } break;  case 2: printf("请选择排序方式:1、升序 2、降序\n");  j=getchar();  getchar();  if(j-'0'==1)   {n1(p,stunum);} else {n2(p,stunum);} break;  }    } } /*======================= 排序=========================*/  void numup(student stu[],int n) { int i; student r; bool flag=true; while(flag) { 	flag=false;   for(i=0;i<n-1;i++)   if (p[i].num>p[i+1].num)   {   	r=p[i]; //即将更改故保存    	p[i]=p[i+1];   	p[i+1]=r ;   	flag=true;   } }  show(stu,stunum); } void numdown(student stu[],int n) { int i; student r;   bool flag=true; while(flag) { 	flag=false;   for(i=0;i<n-1;i++)   if (p[i].num<p[i+1].num)   {   	r=p[i];    	p[i]=p[i+1];   	p[i+1]=r ;   	flag=true;   } } show(stu,stunum);	 } void c11(student stu[],int n) { int i; student r; bool flag=true; while(flag) { 	flag=false;   for(i=0;i<n-1;i++)   if (p[i].C>p[i+1].C)   {   	r=p[i];    	p[i]=p[i+1];   	p[i+1]=r ;   	flag=true;   } }  show(stu,stunum); } void c2(student stu[],int n) { int i; student r;   bool flag=true; while(flag) { 	flag=false;   for(i=0;i<n-1;i++)   if (p[i].C<p[i+1].C)   {   	r=p[i];    	p[i]=p[i+1];   	p[i+1]=r ;   	flag=true;   } } show(stu,stunum);	 } /*               高                           */ void g1(student stu[],int n) { int i; student r; bool flag=true; while(flag) { 	flag=false;   for(i=0;i<n-1;i++)   if (p[i].gaoshu>p[i+1].gaoshu)   {   	r=p[i];    	p[i]=p[i+1];   	p[i+1]=r ;   	flag=true;   } }  show(stu,stunum); } void g2(student stu[],int n) { int i; student r;   bool flag=true; while(flag) { 	flag=false;   for(i=0;i<n-1;i++)   if (p[i].gaoshu<p[i+1].gaoshu)   {   	r=p[i];    	p[i]=p[i+1];   	p[i+1]=r ;   	flag=true;   } } show(stu,stunum);	 } //                               xiand void x1(student stu[],int n) { int i; student r; bool flag=true; while(flag) { 	flag=false;   for(i=0;i<n-1;i++)   if (p[i].xiandai>p[i+1].xiandai)   {   	r=p[i]; //即将更改故保存    	p[i]=p[i+1];   	p[i+1]=r ;   	flag=true;   } }  show(stu,stunum); } void x2(student stu[],int n) { int i; student r;   bool flag=true; while(flag) { 	flag=false;   for(i=0;i<n-1;i++)   if (p[i].xiandai<p[i+1].xiandai)   {   	r=p[i]; //即将更改故保存    	p[i]=p[i+1];   	p[i+1]=r ;   	flag=true;   } } show(stu,stunum);	 }  //                        字符串姓名排序  void n1(student stu[],int n) { int i,j,k; student r; for(i=0;i<n-1;i++) { j=i; for(k=i+1;k<n;k++) if(strcmp(p[i].name,p[k].name)>0)   j=k;  r=p[i]; p[i]=p[j]; p[j]=r; } show(stu,stunum);	 }  void n2(student stu[],int n) { int i,j,k; student r; for(i=0;i<n-1;i++)   { j=i; for(k=i+1;k<n;k++) if(strcmp(p[i].name,p[k].name)<0) j=k; r=p[i]; p[i]=p[j]; p[j]=r;   }   show(stu,stunum);	 } /*  -  -----------       统计函数 -----------           */  void statistics(student stu[]) { printf("请选择统计内容：\n"); printf("(1)分段成绩单计数 (2)优秀成绩单 (3)不及格成绩单\n") ; int m; int i; i=getchar(); getchar(); i=i-'0'; switch(i) { 	case 1:printf("请选择分段计数的成绩\n") ; 	printf("1、C语言   2、高数   3、线代\n") ; m=getchar(); getchar(); m=m-'0'; if(m==1) 	segmentation1(p,stunum);  if(m==2) 	segmentation2(p,stunum);  if(m==3) 	segmentation3(p,stunum);  	case 2:;break; 	case 3:;break; } } void segmentation1(student stu[],int n)//这里分段用不用打出内容而不是单计数 { int i; int a[10]={0}; for(i=0;i<n;i++) { if(p[i].C<=10) a[0]++;  if((p[i].C>=11)&&(p[i].C<=20))   a[1]++;  if(p[i].C>=21&&p[i].C<=30)    a[2]++;  if(p[i].C>=31&&p[i].C<=40)   a[3]++;  if(p[i].C>=41&&p[i].C<=50)   a[4]++;  if(p[i].C>=51&&p[i].C<=60)  a[5]++;  if(p[i].C>=61&&p[i].C<=70)    a[6]++;  if(p[i].C>=71&&p[i].C<=80)   a[7]++;  if(p[i].C>=81&&p[i].C<=90)   a[8]++;  if((p[i].C>=91)&&(p[i].C<=100))  a[9]++;  } printf("各分段人数为：\n"); printf("0~10：%d   11~20：%d   21~30：%d   31~40：%d   41~50：%d   51~60：%d   61~70：%d\n",a[0],a[1],a[2],a[3],a[4],a[5],a[6]) ;  printf("71~80：%d   81~90：%d   91~100：%d\n",a[7],a[8],a[9] ); } void segmentation2(student stu[],int n)//这里分段用不用打出内容而不是单计数 { int i; int a[10]={0};  for(i=0;i<n;i++) { if(p[i].gaoshu<=10) a[0]++;  if(p[i].gaoshu>=11&&p[i].gaoshu<=20)   a[1]++;  if(p[i].gaoshu>=21&&p[i].gaoshu<=30)    a[2]++;  if(p[i].gaoshu>=31&&p[i].gaoshu<=40)   a[3]++;  if(p[i].gaoshu>=41&&p[i].gaoshu<=50)   a[4]++;  if(p[i].gaoshu>=51&&p[i].gaoshu<=60)  a[5]++;  if(p[i].gaoshu>=61&&p[i].gaoshu<=70)    a[6]++;  if(p[i].gaoshu>=71&&p[i].gaoshu<=80)   a[7]++;  if(p[i].gaoshu>=81&&p[i].gaoshu<=90)   a[8]++;  if(p[i].gaoshu>=91&&p[i].gaoshu<=100)  a[9]++;  } printf("各分段人数为：\n"); printf("0~10：%d   11~20：%d   21~30：%d   31~40：%d   41~50：%d   51~60：%d   61~70：%d\n",a[0],a[1],a[2],a[3],a[4],a[5],a[6]) ;  printf("71~80：%d   81~90：%d   91~100：%d\n",a[7],a[8],a[9] ); } void segmentation3(student stu[],int n)//这里分段用不用打出内容而不是单计数 { int i; int a[10]={0};  for(i=0;i<n;i++) { if(p[i].xiandai<=10) a[0]=a[0]+1;  if((p[i].xiandai>=11)&&(p[i].xiandai<=20))   a[1]=a[1]+1;  if(p[i].xiandai>=21&&p[i].xiandai<=30)    a[2]++;  if(p[i].xiandai>=31&&p[i].xiandai<=40)   a[3]++;  if(p[i].xiandai>=41&&p[i].xiandai<=50)   a[4]++;  if(p[i].xiandai>=51&&p[i].xiandai<=60)   a[5]++;  if(p[i].xiandai>=61&&p[i].xiandai<=70)    a[6]++;  if(p[i].xiandai>=71&&p[i].xiandai<=80)   a[7]++;  if(p[i].xiandai>=81&&p[i].xiandai<=90)   a[8]++;  if(p[i].xiandai>=91&&p[i].xiandai<=100)  a[9]++;  } printf("各分段人数为：\n"); printf("0~10：%d   11~20：%d   21~30：%d   31~40：%d   41~50：%d   51~60：%d   61~70：%d\n",a[0],a[1],a[2],a[3],a[4],a[5],a[6]) ;  printf("71~80：%d   81~90：%d   91~100：%d\n",a[7],a[8],a[9] ); }  这里是打开的成绩文件（15个学生） 15 12345678 abc 男 11 11 11 81234567 aceb 女 22 22 22 81234567 asiaaa 女 28 29 30 10000001 wsc 人妖 100 100 100 10310001 cab 人妖 99 99 99 12345678 abc 男 11 11 11 81234567 aceb 女 22 22 22 81234567 asiaaa 女 28 29 30 10000001 wsc 人妖 100 100 100 10310001 cab 人妖 99 99 99 12345678 abc 男 11 11 11 81234567 aceb 女 22 22 22 81234567 asiaaa 女 28 29 30 10000001 wsc 人妖 100 100 100 10310001 cab 人妖 99 99 99


Question: 新手遇到问题求高手来解决，c语言，error LNK1120: 1 个无法解析的外部命令

引用 4 楼 cyn2014 的回复:引用 1 楼 ccnyou 的回复:代码是可以正常编译的，整个工程打包上来吧。或者楼主说下你的项目是怎么创建的。新建了一个win32控制台应用程序，然后“完成”。 使用的是哪个版本的VS？ 我在VS2013上面按照你的方式创建，然后贴代码，只是报找不到标识符，包含 stdlib.h 可以解决。 另外，不要在CSDN上面使用私信

有的时候先简单百度一下，也解决个差不多了

看看是否缺少那个头文件如malloc

在stdafx.h文件中加入 #include <stdlib.h>

代码是可以正常编译的，整个工程打包上来吧。或者楼主说下你的项目是怎么创建的。


Question: windows编程

sscanf, swscanf Read formatted data from a string.  int sscanf( const char *buffer, const char *format [, argument ] ... );  int swscanf( const wchar_t *buffer, const wchar_t *format [, argument ] ... );  Routine Required Header Compatibility  sscanf <stdio.h> ANSI, Win 95, Win NT  swscanf <stdio.h> or <wchar.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  Each of these functions returns the number of fields successfully converted and assigned; the return value does not include fields that were read but not assigned. A return value of 0 indicates that no fields were assigned. The return value is EOF for an error or if the end of the string is reached before the first conversion.  Parameters  buffer  Stored data  format  Format-control string  argument  Optional arguments  For more information, see Format Specifications.  Remarks  The sscanf function reads data from buffer into the location given by each argument. Every argument must be a pointer to a variable with a type that corresponds to a type specifier in format. The format argument controls the interpretation of the input fields and has the same form and function as the format argument for the scanf function; see scanf for a complete description of format. If copying takes place between strings that overlap, the behavior is undefined.  swscanf is a wide-character version of sscanf; the arguments to swscanf are wide-character strings. sscanf does not handle multibyte hexadecimal characters. swscanf does not handle Unicode fullwidth hexadecimal or “compatibility zone” characters. Otherwise, swscanf and sscanf behave identically.  Generic-Text Routine Mappings  TCHAR.H Routine  _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined  _stscanf sscanf sscanf swscanf    Example  /* SSCANF.C: This program uses sscanf to read data items  * from a string named tokenstring, then displays them.  */  #include <stdio.h>  void main( void ) {    char  tokenstring[] = "15 12 14...";    char  s[81];    char  c;    int   i;    float fp;     /* Input various data from tokenstring: */    sscanf( tokenstring, "%s", s );    sscanf( tokenstring, "%c", &c );    sscanf( tokenstring, "%d", &i );    sscanf( tokenstring, "%f", &fp );     /* Output the data read */    printf( "String    = %s\n", s );    printf( "Character = %c\n", c );    printf( "Integer:  = %d\n", i );    printf( "Real:     = %f\n", fp ); }   Output  String    = 15 Character = 1 Integer:  = 15 Real:     = 15.000000   Stream I/O Routines  See Also   fscanf, scanf, sprintf, _snprintf

囧么转换，为什么我转换得的结果是那种不认识的字符。我使用createwindow创建的edit，不是dialog哦

CEdit *pEdit = (CEdit*)GetDlgItem(IDC_EDIT1);///IDC_EDIT1改成你的 CString str1; pEdit->GetWindowText(str1); int a = = _ttoi(str1);//将CString ->int

4楼的方法可以做;将一个INT变量和文本框关联起来（这里电脑会自己帮你判断是否输入的是数字） 另一方法是每次要用时，获取文本框的内容，然后将其转化为INT(这里你要自己来判断输入是不是数字)

不是有可以添加变量吗？添加变量，然后变量类型设置为int，不就可以啦？

TCHAR tchText[64]={0};  GetDlgItemText(IDC_EDIT_ANTENNA_COMAZ,tchText,64); int iEdit = _ttoi(tchText);   BOOL flag; UINT ui=GetDlgItemInt(IDC_EDIT1,&flag,true);

是用哪一个组件，edit还是dlg，能不能给我一下核心代码

GetDlgItemInt


Question: 数据结构关键路径的程序结果有误，想知道哪里错了？

for(i=1;i<=n;i++) 	{ 		if(G[i].id==0) 		{ 			rear++; 			stack[rear]=i; 		} 		 	} 	m=0; 	while(front!=rear) 	{ 		front++; 		j=stack[front]; 		m++; 		p=G[j].link; 		while(p!=NULL) 		{ 			k=p->adjvex; 			G[k].id=G[k].id-1; 			if(ve[j]+(p->dut)>ve[k]) 				ve[k]=ve[j]+(p->dut); 			if(G[k].id==0) 			{ 				rear++; 				stack[rear]=k; 			} 			p=p->next; 		} 输了几组数据，调试进去看，这段都没执行

你一定要写清楚：我想做什么，我的代码出现了什么，结果那些地方和我的预料不一样，最好是你提供一组数据，然后预计这组数据应该出现什么结果但是程序出现了什么结果而让你不满意。比如我调试了一下你的代码：  但是我不知道你希望看到的结果和这组测试数据的关系。


Question: 在vs2010写c程怎么定义结构体

这是c跟c++的一个不同之处

vs 上用c语言定义一个结构struct  title{}  ;    再定义该结构的变量时是struct   title  a;要么用typedef   title{}a,就可以直接用a去定义该结构的变量了

typedef struct _stu{     char name[9];     int score[5];     struct _stu *next; } stu;

将文件名改成 cpp 就行了。不然标准的C写法应该是struct stu *crea(int n){}

错误	1	error C2061: 语法错误: 标识符“stu”	c:\users\administrator\documents\visual studio 2010\projects\vvvv\vvvv\vvvv.c	8	1	vvvv 错误	2	error C2059: 语法错误:“}”	c:\users\administrator\documents\visual studio 2010\projects\vvvv\vvvv\vvvv.c	9	1	vvvv 错误	3	error C2143: 语法错误 : 缺少“{”(在“*”的前面)	c:\users\administrator\documents\visual studio 2010\projects\vvvv\vvvv\vvvv.c	10	1	vvvv 错误	4	error C2065: “stu”: 未声明的标识符	c:\users\administrator\documents\visual studio 2010\projects\vvvv\vvvv\vvvv.c	11	1	vvvv 错误	5	error C2065: “head”: 未声明的标识符	c:\users\administrator\documents\visual studio 2010\projects\vvvv\vvvv\vvvv.c	11	1	vvvv 错误	6	error C2065: “p1”: 未声明的标识符	c:\users\administrator\documents\visual studio 2010\projects\vvvv\vvvv\vvvv.c	11	1	vvvv 错误	7	error C2100: 非法的间接寻址	c:\users\administrator\documents\visual studio 2010\projects\vvvv\vvvv\vvvv.c	11	1	vvvv 错误	8	error C2065: “p2”: 未声明的标识符	c:\users\administrator\documents\visual studio 2010\projects\vvvv\vvvv\vvvv.c	11	1	vvvv 错误	9	error C2100: 非法的间接寻址	c:\users\administrator\documents\visual studio 2010\projects\vvvv\vvvv\vvvv.c	11	1	vvvv 错误	10	error C2143: 语法错误 : 缺少“;”(在“类型”的前面)	c:\users\administrator\documents\visual studio 2010\projects\vvvv\vvvv\vvvv.c	12	1	vvvv 错误	11	error C2065: “head”: 未声明的标识符	c:\users\administrator\documents\visual studio 2010\projects\vvvv\vvvv\vvvv.c	13	1	vvvv 错误	12	error C2065: “p1”: 未声明的标识符	c:\users\administrator\documents\visual studio 2010\projects\vvvv\vvvv\vvvv.c	13	1	vvvv 错误	13	error C2065: “stu”: 未声明的标识符	c:\users\administrator\documents\visual studio 2010\projects\vvvv\vvvv\vvvv.c	13	1	vvvv     只贴出来部分，后面还有一大堆

贴错误提示一下


Question: 来帮忙  +++++++++++++++

我的意思是，楼主要记得把局部变量【 f 】初始化一下

引用 6 楼 wenpinglaoyao 的回复:#include "stdio.h" #define N 5 char cc(char gg[]); char cc(char gg[]) {     int i,f=0;     for(i=0;i<N;i++)     {         if(gg[i]!='\0')         {             f++;         }     }     return f; } main() {     int c;     char str[N];     printf("请输入字符");     gets(str);     c=cc(str);     printf("字符个数为%d",c);     getch(); }  你这个也犯了if错误 -~~！编译不对。

引用 5 楼 call_from_dream 的回复:- 帮尼妹！f没初始化就用！ 我错了 --！

注意第六行代码

帮尼妹！f没初始化就用！

比如你实际输入的字符是6个，但是你循环仍然是按照10次，第7位可能不是0了  就会出错了

另外还是不要用gets这个函数  警告已经告诉你很详细了

你的for循环条件有问题  既然是求字符串的长度的话  判定条件应该是gg[i] != 0;  而不是i<N

你输入的字符是不是超过9个啦、。、


Question: 这本编译书有没有c版本的

哪位大师教你脚本的运行必须要有虚拟机的？  引用 8 楼 ole_master 的回复:[quote=引用 6 楼 turingo 的回复:] 那就换这本书来看 http://product.dangdang.com/23493730.html  [quote=引用 4 楼 ole_master 的回复:] [quote=引用 2 楼 turingo 的回复:] 学吧！PASCAL很严谨也很容易上手，如果说C语言体现的是实干家的逻辑，那么PASCAL就是科学家的思维。  肯定不学[/quote][/quote]  虚拟机都没写过，就能写脚本语言了啊[/quote]

解释BASIC也是一种脚本，但她不是虚拟机。

引用 5 楼 ole_master 的回复:[quote=引用 3 楼 zhao4zhong1 的回复:] 为何不研读Tiny C Compiler源代码？  你读过吗，写过c编译器吗[/quote] 读过，没写过，只写过词法分析。

那就换这本书来看 http://product.dangdang.com/23493730.html  引用 4 楼 ole_master 的回复:[quote=引用 2 楼 turingo 的回复:] 学吧！PASCAL很严谨也很容易上手，如果说C语言体现的是实干家的逻辑，那么PASCAL就是科学家的思维。  肯定不学[/quote]

引用 6 楼 turingo 的回复:那就换这本书来看 http://product.dangdang.com/23493730.html  [quote=引用 4 楼 ole_master 的回复:] [quote=引用 2 楼 turingo 的回复:] 学吧！PASCAL很严谨也很容易上手，如果说C语言体现的是实干家的逻辑，那么PASCAL就是科学家的思维。  肯定不学[/quote][/quote]  虚拟机都没写过，就能写脚本语言了啊

引用 3 楼 zhao4zhong1 的回复:为何不研读Tiny C Compiler源代码？  你读过吗，写过c编译器吗

引用 2 楼 turingo 的回复:学吧！PASCAL很严谨也很容易上手，如果说C语言体现的是实干家的逻辑，那么PASCAL就是科学家的思维。  肯定不学

为何不研读Tiny C Compiler源代码？


Question: 关于win32汇编的一些问题

引用 1 楼 user-1 的回复:加上 .xmm，另外test是一条指令，不能用作函数名  非常感谢问题解决了。

加上 .xmm，另外test是一条指令，不能用作函数名


Question: 关于用程序实现对象的匹配

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

引用 3 楼 zhao4zhong1 的回复:仅供参考#pragma warning(disable:4786) #include <iostream> #include <string> #include <map> using namespace std; int main () {     wstring ws1,ws2;      wcin.imbue(locale("chs"));     wcout.imbue(locale("chs"));     getline(wcin,ws1);     getline(wcin,ws2);     if (ws1.size()!=ws2.size()) {         wcout<<ws1<<L" 和 "<<ws2<<L" 不对应"<<endl;         return 1;     }      map<wchar_t,wchar_t> m1,m2;     int n=ws1.size();      for (int i=0;i<n;i++) {         if (m1.find(ws1[i])==m1.end() && m2.find(ws2[i])==m2.end()) {             m1[ws1[i]]=ws2[i];             m2[ws2[i]]=ws1[i];         } else {             if (m1[ws1[i]]!=ws2[i] || m2[ws2[i]]!=ws1[i]) {                 wcout<<ws1<<L" 和 "<<ws2<<L" 不对应"<<endl;                 return 1;             }         }     }     wcout<<ws1<<L" 和 "<<ws2<<L" 对应"<<endl;     return 0; } 请问老师，你能为这程序写个备注吗，我看不懂

是不是我太菜了,完全没有看懂楼主的问题.

可以使用multimap或者自定义一个struct，记录匹配关系么,比如  struct { TCHAR a; TCHAR b[0]; }


Question: 为什么void main() {priar();prissage(); }这句放在前面编译会错误，然而放在后面居然能编译，，，，求大神告诉我原因，我用的是VC+

标识符的作用域，傻傻没弄明白。

缺少声明，main函数只认识在它之前的函数

楼主的代码...   上一个通不过，是因为main在前面，不认识priar()和prissage()函数  所以要前置申明   #include <stdio.h>                                                                    #include <string.h> void priar(); void prissage(); void main() {     priar();     prissage(); } void priar() {     printf("***************\n"); } void prissage() {     printf("asddsad\n");      printf("*******************\n"); }


Question: 新人用vs2013打c语言代码出现问题求教

明白啦，谢谢

一看这个断言，就是越界了。 要不把str申明为数组，要不scanf就用%c


Question: 跪求linux下  conio.h头文件下载地址

linux下没有conio.h 使用NCURSES库。

引用 1 楼 user-4 的回复:这玩意搜不到？？ http://download.csdn.net/detail/x931210007/4989321  这是VC目录下的，Linux环境用不了的。

非标准头文件，建议楼主不要使用。

这过时的玩意儿楼主要了想干嘛？


Question: 帮看哪里出错了 都调试一个多小时了

引用 7 楼 tenmenglin 的回复:[quote=引用 6 楼 aqiu348503 的回复:] 你的问题是什么？ 如果第一个数据小于60循环就停止了啊，这是你程序的意图吗？ 如果数组的10个分数都要评等级，for循环里的else分支         else         {             break;         } 改为         else         {            printf("不及格%d",ixj[i]);         } 奥奥，对了。我break 他不给返回值了去。。。。[/quote] 叫你说出错误信息时就知道有这问题，原来还真是这问题；我以为你是编译不过

#include <stdio.h> int jxj(int c); int jxj(int c) { 	if(c>=90) 	{ 		return 1; 	} 	else if(c>=80&&c<90) 	{ 		return 2; 	} 	else if(c>=60&&c<80) 	{ 		return 3; 	} 	else 	{  		return 0; 	} } void main() { 	int i,a,ixj[10]; 	for(i=0;i<10;i++) 	{ 		scanf("%d",&ixj[i]); 	} 	for(i=0;i<10;i++) 	{ 		a=jxj(ixj[i]); 		if(a==1) 		{ 			printf("一等奖%d\n",ixj[i]); 		} 		else if(a==2) 		{ 			printf("er等奖%d\n",ixj[i]); 		} 		else if(a==3) 		{ 			printf("san等奖%d\n",ixj[i]); 		} 		else 		{ 			printf("0未获奖%d\n",ixj[i]); 		} 	} 	getch(); }

break改成continue，要不然只要有小于60的，后面的不会输出直接退出了。 另外，建议printf("一等奖%d",ixj[i]);里面增加一个回车printf("一等奖%d\n",ixj[i]);

引用 6 楼 aqiu348503 的回复:你的问题是什么？ 如果第一个数据小于60循环就停止了啊，这是你程序的意图吗？ 如果数组的10个分数都要评等级，for循环里的else分支         else         {             break;         } 改为         else         {            printf("不及格%d",ixj[i]);         } 奥奥，对了。我break 他不给返回值了去。。。。

引用 1 楼 linxin3333520 的回复:你最好是贴出来错误信息  无值。

引用 3 楼 qqh_n 的回复:[quote=引用 2 楼 qqh_n 的回复:] 自定义函数里面缺少一个接收参数的变量？？  int jxj(int a) {         int c;     c=a;     if(c>=90)        {                 return 1;         }         else if(c>=80&&c<90)         {         return 2;     }         else if(c>=60&&c<80)         {         return 3;     }         else     {          return 0;     } }原来主函数有a了啊，那自定义函数里面形参改成b好了[/quote] 可以输入值 但不返回值

引用 2 楼 qqh_n 的回复:自定义函数里面缺少一个接收参数的变量？？  int jxj(int a) {         int c;     c=a;     if(c>=90)        {                 return 1;         }         else if(c>=80&&c<90)         {         return 2;     }         else if(c>=60&&c<80)         {         return 3;     }         else     {          return 0;     } }原来主函数有a了啊，那自定义函数里面形参改成b好了

你最好是贴出来错误信息


Question: c语言中static数组和非static数组编译时间差距绝大（高手进）

其实不见得是编译器的bug，因为加上static是在运行时动态分配的存储空间，而不加的话，则是由存储器预编译阶段分配的。

引用 18 楼 lm_whales 的回复:[quote=引用 15 楼 angel_su 的回复:] 编译器的问题吧，被你搞出bug了...  ++ 找到了一个bug 赶紧跟编译器厂家反应 估计有奖励[/quote] 微软会说，没事在代码里初始化一个200000的栈上数组的每个元素干嘛。这个用例太特殊了，不支持。

引用 15 楼 angel_su 的回复:编译器的问题吧，被你搞出bug了...  ++ 找到了一个bug 赶紧跟编译器厂家反应 估计有奖励

估计编译器在计算堆栈占用了多少 结果计算不出来了，陷入死循环了

引用 3 楼 user-11 的回复:生成的 mov 指令太多了。  正解

没有放到头文件中。

lz不会是将这么大的数组放进头文件了吧？不然就一个文件对这个数组初始化，不可能会很慢的。当然这么大的数组我也是醉了。

把数组改小一点，编译好后看看汇编文件就什么都明白了

这个程序我跑了24个小时都没编译完，我已经终止了。

编译器的问题吧，被你搞出bug了...

想深究的话，可以用gdb调试gcc或g++编译你的代码。

引用 12 楼 thinkperson_x201 的回复:[quote=引用 11 楼 zhao4zhong1 的回复:] 在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。 你说的很对，我想知道的是：为什么使用栈空间，当数组元素很大的时候，编译速度会变态的慢？[/quote]  说不定vs编译时，先把生成指令放在一个动态数组里。然后这个数组不是用均摊算法，而是有个最大增长上限，如我以前看得MFC的CArray（vs2005）源代码里，好像最多一次加512元素。大量时间都浪费在数组容量变大时做的复制粘贴上了。

引用 11 楼 zhao4zhong1 的回复:在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。 你说的很对，我想知道的是：为什么使用栈空间，当数组元素很大的时候，编译速度会变态的慢？

一晚上这是多么夸张？！

可不可以这样理解：加上static，用的存储时全局的，程序运行的时候再对数组初始化；不加static，用的是栈的空间，需要在编译阶段预先为数组分配空间，时间都花费到数组空间的预分频和初始化上面了。不知道我的理解对不对？

同意user-11。进一步说明，static之后，那些东西在编译阶段直接写到exe里面去了，用的时候系统直接用映射的方式来获取。不加的话，就是好多好多的mov

生成的 mov 指令太多了。

结构体很小，另外，200000是个极限值，一般为4000多，但即使4000，编译时间也很长（一分钟以上）；如果加上static修饰，瞬间完成编译。

不清楚为什么编译要那么久，但200000个元素放栈上，你不怕运行时把栈崩了？


Question: 求个关于位的算法

#define bit(x)   (1<<(x))  int clrbit(int number, int n) {        number = (number & (~bit(n)));      return number; }  int main(void) {         int in, i;        scanf("%d", &in);       scanf("%d", &i);    in = clrbit(in,i); printf("%d\n",in); return 0; }

#define bit(x)   (1<<(x))  int clrbit(int number, int n) {        number = (number & (~bit(n)));      return number; }  int main(void) {         int in, i, out=0, k = 1;        scanf("%d", &in);       scanf("%d", &i);    clrbit(in,i); printf("%d\n",in); return 0; }

#include <stdio.h>  int main() {    int in, i, out=0, k = 1;    scanf("%d", &in);    scanf("%d", &i);    while (in>0)    { 		if (i!=0) 		{ 			out = out  + k * (in % 2) ; 			k=k*2 ; 		} 		in = in / 2; 		i--;    }    printf("%d  ",out);    return 0; }


我也遇到了这个问题 但是切换到amd64选项的时候就可以编译了

有个参考网站： http://sourceforge.net/projects/qtx64/?source=typ_redirect

难到要结帖给分么

不死心，求指导

参考 http://www.cnsecer.com/695.html

没有  引用 3 楼 liu15073458538 的回复:我看了，我也是这样完成编译的，VS创建Qt工程也遇到同样的问题，都已经解决了 我想问有没有直接是Windows 64的Qt版本？ 方便的话提供链接

呼叫大神！！！ 大神求帮助！！！


Question: 求推荐一本编译原理的书

龙书，虎书，鲸书

还是建议看龙书，如果只是想简单了解，就不要挨页去读了。


Question: 本人是个学生，希望能帮助我修改下程序

希望你能把你代码整理了，用标准格式发  int a;

Status CreatString(HString &S){        int i=0;        int temp=0;        scanf("%d",&temp);        S.ch=(char *)malloc(MAXSIZE*sizeof(char));        scanf("%c",&S.ch[i]);         while((S.ch[i]!=' ')&&i<=MAXSIZE-1){              i++;             scanf("%c",&S.ch[i]); }         S.length=i;        return 1; }  给你改了下，试试吧

#include"stdio.h" #include"stdlib.h"  #include"string.h" #define ERROR  0 #define MAXSIZE 100 typedef int Status; typedef struct{   char *ch;   int length; }HString;  Status CreatString(HString &S){        int i=0;        S.ch=(char *)malloc(MAXSIZE*sizeof(char));        scanf("%c",&S.ch[i]);         while((S.ch[i]!=' ')&&i<=MAXSIZE-1){              i++;             scanf("%c",&S.ch[i]); }         S.length=i;        return 1; }  Status StrLength(HString &S){    return S.length; }  Status SubString(HString &Sub,HString S,int pos,int len){     if(pos<1||pos>S.length||len>S.length-pos+1||len<0)  return 0;     if(Sub.ch){ free(Sub.ch); Sub.length=0; }       if(len==0){ Sub.ch=NULL; Sub.length =0; }     else{      Sub.ch=(char *)malloc(len *sizeof(char));      for(int i=0;i<=len-1;i++){         Sub.ch[i]=S.ch[pos-1];         pos++;         if(pos<=S.length);}         Sub.length=len;   }  return 1; }  Status IndexStr(HString S,HString T,int pos){    int i,j;    if(pos>=1&&pos<=S.length-1){         i=pos-1;         j=0;         while(i<=S.length-1&&j<=T.length-1){              if(S.ch[i]==T.ch[j])                    {++i;                ++j;}              else                      {i=i-j+1;                  j=0;}                                  }        if(j>T.length-1){         pos=i-T.length;            return pos;           }        else{           return 0;           }       }    else      return 0; }  Status Concat(HString &S,HString T){     for(int i=0;i<=T.length-1;i++){     S.ch[S.length]=T.ch[i];     S.length++;     }    // free(T.ch);           return 1; }     Status Search(HString S,HString Sub,int i){  } void output(HString &S){  printf("输出字符串:");  for(int i=0;i<=S.length-1;i++)     //if(S.ch[i]!='\n')         printf("%c,\n",S.ch[i]); }  main(){  HString S,Sub,T;  int pos,len,i;       printf("创建字符串(以空格结束):");     CreatString(S);     output(S);     printf("\n输出字符串的长度:%d\n",StrLength(S));               printf("求字符串的子串:\n");     printf("输入起始位置:");     scanf("%d",&pos);     printf("输入读取字符长度:");     scanf("%d",&len);     SubString(Sub,S,pos,len);     output(Sub);     printf("\n输出子串长度:%d\n",StrLength(Sub));           printf("字符串的索引\n");        printf("创建索引字符串(以空格结束):");     CreatString(T);     output(T);       //为什么第一行总是逗号，而不是我输入的数据     printf("\n输出索引字符串长度:%d\n",StrLength(T)) ;     // 为什么长度加了1         //索引为什么不能索引出他的位置     printf("输入开始的索引位置:");     scanf("%d",&i);     IndexStr(S,T,i);     printf("输出索引位置:%d\n",i);       printf("连接字符串:\n");     Concat(S,T);      output(S);     printf("\n输出连接后字符串的长度:%d\n",S.length);      }   替你整一下~~

真心看着有点乱。。。

恩   这样好看一些


Question: Linux fprintf不输出日志

引用 7 楼 iloyou19 的回复:谢谢你的回答！写日志的磁盘被别的程序写满了。。。。 如果用我这段代码写日志的话，就几乎不可能出现磁盘被写满的情况。

引用 1 楼 turingo 的回复:建议先单步调试缩小目标范围。 程序调试过了，没有问题。还有就是调试的时候，一定会正确输出日志。 现在问题是：程序持续执行的时候，每个小时创建一个统计日志。有些日志能正确输出到文件，有些日志没有日志为0

建议先单步调试缩小目标范围。

引用 5 楼 zhao4zhong1 的回复:#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中  谢谢你的回答！写日志的磁盘被别的程序写满了。。。。

引用 3 楼 luciferisnotsatan 的回复:w+ 打开可读写文件，若文件存在则文件长度清为零，即该文件内容会消失。若文件不存在则建立该文件 a+ 以附加方式打开可读写的文件。若文件不存在，则会建立该文件，如果文件存在，写入的数据会被加到文件尾后，即文件原先的内容会被保留。 （原来的EOF符不保留）  你确定你要用w+？ stream = fopen((statisticDir + strtm + ".txt").c_str(), "w+b"); 这个函数是每个小时被调用一次，只是记录程序一个小时的统计量。每次调用，创建一个文件并写入一个小时的统计量。W+是为了只写入一次的统计量。

三楼正解，日志用a➕ 中间记得留出足够空间


Question: 指数和底数都是double类型的幂指运算

首先你要搞清楚，是double的精度不够，还是pow的精度不够 double：2^52 = 4503599627370496，一共16位，double的精度为15~16位。 你要求小数点后18位，double本身的精度都不够，算法你再改也没用

我的精度是小数点后18位

扩展精度浮点可以达到小数点后19位。

我编译configure时出现cannot determine how to define 32-bite word 我的系统是64位的

我没用过gmp，我是win8能不能说说安装过程啊，我装了msys但是make时出错

楼主要多大的精度呢？？  引用 2 楼 zhao4zhong1 的回复:使用GMP库。 不明觉厉！！

exp(Exponent * ln(Base))这样精度不够？那只能用汇编做扩展精度运算，结果必然可以保证双精度。

使用GMP库。

用一个字节来存一位数，比如50字节就可以达到50位精度，用2步来计算power， 先求出ln，然后再做e的冪，把ln和e的算法都用泰勒级数，考虑泰勒展开每一项比较方便迭代。


Question: c语言初学者，编写了一个扫雷程序，但是代码有错误，怎么改正

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

看不懂  复制 粘贴也不会？