Question: 嵌入式 TCP链接断开问题

网络不好的情况下服务器send失败后可能会主动断开连接 客户端需要做的就是收到-1后重连

多线程并发，发现连接中断就重新连接

strerror看看error，，，建议发送帧的server发送延迟一下试试

引用 楼主 zhujinghao09 的回复:在6467t板子上做视频存储，作为tcp\客户端接收相机的视频帧，但是正常接收个几分钟就会出现recv返回值为-1,或者0。相应的error值为11和2.。测试了很久都没有解决这个问题。请高手指点一二。。。。。  1.视频传输的时候,速率是多少,在高负载下,必须确定内存足够. 2.是否使用了多线程,如果是,多核cpu排除并发造成的问题.单核cpu排除抢占. 3.视频存储部分的问题,如果存储过程长时间占用cpu,的确会导致网络连接断掉.常见的情况比如存储部分没有较好的缓存机制,来一个就写一次的话的确可能会发生这样的问题.  4.网络设备硬件或者驱动bug,或者是配置问题.  祝好运.

身边有高手指点说是网络环境造成的，单独搭建一个独立局域网，出现的频率大大减少，但还是会偶尔出现。这种问题的根本原因还是没想明白。

是阻塞的，返回0，是立即返回的。返回-1，是超时返回。因为是做实时流接收的，就想如何避免或者快速解决这个这问题。

发现断开就每隔比如10秒重连，连续比如10次重连失败，想办法通知维护人员。

在阻塞情况下。

返回为0,就是连接断开了。


Question: 求助！！求助！！求助！！求助！！

引用 2 楼 u012928672 的回复:[quote=引用 1 楼 zxhuser-3 的回复:] #include <stdio.h>  int main() {     printf("main(){char*p=%c%s%c;(void)printf(p,34,p,34,10);}%c",34,"main(){char*p=%c%s%c;(void)printf(p,34,p,34,10);}%c",34,10);     return 0; }  这样能看懂吗？ 我知道这个程序是原样输出，但是不知道为啥会有那样的效果。[/quote] 楼主我给你解答下吧，首先，你应该明白printf（）的基本原理1，利用%*对输出的变量/常量进行格式控制；2，引号中的字符%*控制字符自然输出，那么开始讲解上面的程序： 自左向右； 第一：编译器首先打印出 main(){char*p=字符串因为不收%控制； 第二：寻找第一个%c的变量替换，34非字符常量，类型不符，所以没有输出；若位‘34’，则会相应输出一字符4，楼主可实验； 第三：寻找%s的变量替换，发现"main(){char*p=%c%s%c;(void)printf(p,34,p,34,10);}%c"恰为字符串类型，所以输出字符串。 第四：与第二原因相同，没有输出； 第五：与第一原因相同，不收%控制，直接输出;(void)printf(p,34,p,34,10);}。 第六：本质与第二、第四相同，没有输出。 所以就出现了你所说的效果。  若楼主认为我说的有道理，请支持一下！

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  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对应的汇编并单步执行观察相应内存和寄存器变化。）

lz你这是根本没看书就来发帖问的吧

引用 1 楼 zxhuser-3 的回复:#include <stdio.h>  int main() {     printf("main(){char*p=%c%s%c;(void)printf(p,34,p,34,10);}%c",34,"main(){char*p=%c%s%c;(void)printf(p,34,p,34,10);}%c",34,10);     return 0; }  这样能看懂吗？ 我知道这个程序是原样输出，但是不知道为啥会有那样的效果。


Question: malloc申请内存机制，为什么申请超出我的内存空间了还能成功，很奇怪

申请失败。。。。。。。。。

C Integer Constants An “integer constant” is a decimal (base 10), octal (base 8), or hexadecimal (base 16) number that represents an integral value. Use integer constants to represent integer values that cannot be changed.  Syntax  integer-constant :  decimal-constant integer-suffix opt octal-constant integer-suffix opt hexadecimal-constant integer-suffix opt  decimal-constant :  nonzero-digit decimal-constant digit  octal-constant :  0 octal-constant octal-digit  hexadecimal-constant :  0x hexadecimal-digit 0X hexadecimal-digit hexadecimal-constant hexadecimal-digit  nonzero-digit : one of  1 2 3 4 5 6 7 8 9  octal-digit : one of  0 1 2 3 4 5 6 7  hexadecimal-digit : one of  0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F  integer-suffix :  unsigned-suffix long-suffix opt long-suffix unsigned-suffix opt   unsigned-suffix : one of  u U  long-suffix : one of  l L  64-bit integer-suffix :  i64  Integer constants are positive unless they are preceded by a minus sign (–). The minus sign is interpreted as the unary arithmetic negation operator. (See Unary Arithmetic Operators in Chapter 4 for information about this operator.)  If an integer constant begins with the letters 0x or 0X, it is hexadecimal. If it begins with the digit 0, it is octal. Otherwise, it is assumed to be decimal.   The following lines are equivalent:  0x1C   /* = Hexadecimal representation for decimal 28 */ 034    /* = Octal representation for decimal 28 */  No white-space characters can separate the digits of an integer constant. These examples show valid decimal, octal, and hexadecimal constants.   /* Decimal Constants */ 10 132 32179  /* Octal Constants */ 012 0204 076663  /* Hexadecimal Constants */ 0xa or 0xA 0x84 0x7dB3 or 0X7DB3 /*** *limits.h - implementation dependent values * *       Copyright (c) Microsoft Corporation.  All rights reserved. * *Purpose: *       Contains defines for a number of implementation dependent values *       which are commonly used in C programs. *       [ANSI] * *       [Public] * ****/  #pragma once  #include <crtdefs.h>  #ifndef _INC_LIMITS #define _INC_LIMITS  #ifndef _CRTBLD /* This version of the header files is NOT for user programs.  * It is intended for use when building the C runtimes ONLY.  * The version intended for public use will not have this message.  */ #error ERROR: Use of C runtime library internal header file. #endif  /* _CRTBLD */  #define CHAR_BIT      8         /* number of bits in a char */ #define SCHAR_MIN   (-128)      /* minimum signed char value */ #define SCHAR_MAX     127       /* maximum signed char value */ #define UCHAR_MAX     0xff      /* maximum unsigned char value */  #ifndef _CHAR_UNSIGNED #define CHAR_MIN    SCHAR_MIN   /* mimimum char value */ #define CHAR_MAX    SCHAR_MAX   /* maximum char value */ #else  /* _CHAR_UNSIGNED */ #define CHAR_MIN      0 #define CHAR_MAX    UCHAR_MAX #endif  /* _CHAR_UNSIGNED */  #define MB_LEN_MAX    5             /* max. # bytes in multibyte char */ #define SHRT_MIN    (-32768)        /* minimum (signed) short value */ #define SHRT_MAX      32767         /* maximum (signed) short value */ #define USHRT_MAX     0xffff        /* maximum unsigned short value */ #define INT_MIN     (-2147483647 - 1) /* minimum (signed) int value */ #define INT_MAX       2147483647    /* maximum (signed) int value */ #define UINT_MAX      0xffffffff    /* maximum unsigned int value */ #define LONG_MIN    (-2147483647L - 1) /* minimum (signed) long value */ #define LONG_MAX      2147483647L   /* maximum (signed) long value */ #define ULONG_MAX     0xffffffffUL  /* maximum unsigned long value */ #define LLONG_MAX     9223372036854775807i64       /* maximum signed long long int value */ #define LLONG_MIN   (-9223372036854775807i64 - 1)  /* minimum signed long long int value */ #define ULLONG_MAX    0xffffffffffffffffui64       /* maximum unsigned long long int value */  #define _I8_MIN     (-127i8 - 1)    /* minimum signed 8 bit value */ #define _I8_MAX       127i8         /* maximum signed 8 bit value */ #define _UI8_MAX      0xffui8       /* maximum unsigned 8 bit value */  #define _I16_MIN    (-32767i16 - 1) /* minimum signed 16 bit value */ #define _I16_MAX      32767i16      /* maximum signed 16 bit value */ #define _UI16_MAX     0xffffui16    /* maximum unsigned 16 bit value */  #define _I32_MIN    (-2147483647i32 - 1) /* minimum signed 32 bit value */ #define _I32_MAX      2147483647i32 /* maximum signed 32 bit value */ #define _UI32_MAX     0xffffffffui32 /* maximum unsigned 32 bit value */  /* minimum signed 64 bit value */ #define _I64_MIN    (-9223372036854775807i64 - 1) /* maximum signed 64 bit value */ #define _I64_MAX      9223372036854775807i64 /* maximum unsigned 64 bit value */ #define _UI64_MAX     0xffffffffffffffffui64  #if _INTEGRAL_MAX_BITS >= 128 /* minimum signed 128 bit value */ #define _I128_MIN   (-170141183460469231731687303715884105727i128 - 1) /* maximum signed 128 bit value */ #define _I128_MAX     170141183460469231731687303715884105727i128 /* maximum unsigned 128 bit value */ #define _UI128_MAX    0xffffffffffffffffffffffffffffffffui128 #endif  /* _INTEGRAL_MAX_BITS >= 128 */  #ifndef SIZE_MAX #ifdef _WIN64 #define SIZE_MAX _UI64_MAX #else  /* _WIN64 */ #define SIZE_MAX UINT_MAX #endif  /* _WIN64 */ #endif  /* SIZE_MAX */  #if __STDC_WANT_SECURE_LIB__ /* While waiting to the C standard committee to finalize the decision on RSIZE_MAX and rsize_t,  * we define RSIZE_MAX as SIZE_MAX  */ #ifndef RSIZE_MAX #define RSIZE_MAX SIZE_MAX #endif  /* RSIZE_MAX */ #endif  /* __STDC_WANT_SECURE_LIB__ */   #endif  /* _INC_LIMITS */

引用 7 楼 xinsuixiaofeiyu 的回复:引用 2 楼 jerry_dqh 的回复:申请的是线性空间，进程空间，并不能完全对应物理内存，你的64位的程序吧，32位的程序开始的也不能申请这么大。但程序没报错啊，很奇怪。4楼的是对的。但不明白为什么只有那么多内存   溢出了。

数值溢出。。。

因为windows由虚拟内存机制

引用 6 楼 xinsuixiaofeiyu 的回复:[quote=引用 4 楼 zjq9931 的回复:] 32位上面运行了一下： 结果是：832569344 794M  #include<stdio.h> int main() { 	size_t sA; 	sA=sizeof(int)*20000*200000*200000*20; 	printf("%u\n", sA); 	return 0; } 32位的话sizeof（int）是4个字节啊，那sizeof(int)*20000*200000*200000*20明显大于794M啊，是不是这个式子计算式把常数做了类型转换呢？[/quote] 是的，超范围的数，都会截断。只要32位的（32位平台）。由于是无符号的，所以，不会出现负数，但强制转换成有符号的就会有可能是负数了，这个时候就有问题了。

超出类型，溢出了，最终变成 832564344，也就是越位793MB 如果最后是乘以200，溢出后变成4030726144，也就是3.8G 显然，前者会成功，后者会失败

引用 4 楼 zjq9931 的回复:32位上面运行了一下： 结果是：832569344 794M  #include<stdio.h> int main() { 	size_t sA; 	sA=sizeof(int)*20000*200000*200000*20; 	printf("%u\n", sA); 	return 0; } 32位的话sizeof（int）是4个字节啊，那sizeof(int)*20000*200000*200000*20明显大于794M啊，是不是这个式子计算式把常数做了类型转换呢？

应该是64位的。

malloc的参数是一个 unsigned integer 把那个数据计算结构放到一个无符号整形里面就是申请的内存空间。 看似已经超出来范围，但得到的整形数的结果不会超出整形数。

sizeof(int)*20000*200000*200000*20溢出了，实际可能不是很大...


Question: 关于digit的解释

It works by sorting data in pieces called digits, 看到这句话我懂了

首先，楼主不必纠结于，到底翻译成什么，配合基数排序去理解digit所指的本质，然后具体翻译成什么就是寓情于景的问题。 所以，楼主还是得把基数排序稿透，理解digit也就不是问题。 举例，排序： 22 38 46 51 98 34    2   8    6   1    8   4 就是低位（右边，个位上的数） 2   3   4     5    9  就是高位（左边，十位上的数） 楼主理解了么？ 我的智能创意，请支持一下！


Question: HDOJ的一道编程题 大数加法

引用 4 楼 IAccepted 的回复: #include <cstdio> #include <cstdlib> #include <cstring>  const int MAX = 1002;  char sa[MAX],sb[MAX],res[MAX+1];  int Add(){     int pos,la,lb,ts,c;      la = strlen(sa)-1;     lb = strlen(sb)-1;     pos = MAX;     res[pos] = '\0';     c = 0;     while(la>=0 && lb>=0){         ts = (sa[la]-'0') + (sb[lb]-'0') +c;         res[--pos]=ts%10+'0';         --la,--lb;         c = ts/10;     }     while(la>=0){         ts = (sa[la]-'0')+c;         res[--pos]=ts%10+'0';         --la;         c = ts/10;     }     while(lb>=0){         ts = (sb[lb]-'0')+c;         res[--pos]=ts%10+'0';         --lb;         c = ts/10;     }     if(c!=0)res[--pos]='0'+c;     return pos; } int main(){     int pos,n,i;     scanf("%d",&n);     for(i=1;i<=n;++i){         scanf("%s %s",sa,sb);         pos = Add();         printf("Case %d:\n%s + %s = %s\n",i,sa,sb,res+pos);         if(i!=n)printf("\n");     }     return 0; }  这是我AC的代码，思路是一样的，你可以简单参考下 妙！整个字符串输出

引用 2 楼 lovesmiles 的回复:确实写得非常之烂     for(i=1;i<=t;i++)//t没有定义        {        scanf("%s%s",A,B);//这种输入可能会有问题，你没法区分a什么时候结束  第六行、、int   t；定义了啊 scanf  输入的两个字符串是用空格隔开的 应该没问题

我知道我代码写的烂、、、


Question: 求教，关于非系统分配的内存的使用权限问题

从语言角度来讲， 访问无效内存属于未定义行为（可能会crash,也可能不会） 从OS内存管理角度来说， 这块内存可能属于进程空间内已经提交的内存，free一般只是放回到自由空间(free store)中。

1你这不是内存泄漏，你是指向了一个未知的内存值，就是野指针。访问野指针通常会出错，但也不一定，假如你刚好有这个内存的访问权限的话。 2正如上面说的，内存是交还了。交还的意思是系统只是记录了这块内存是空闲内存。随时可以分配给其它线程。但它的访问权限是存在的，就是说你访问它是没有问题的。只是系统不保证它的值不会被改变。  你分配也好，收回也好，不管你free不free，内存的访问权限就在那里。你又没有将指针清为null。

malloc是上层函数，它底层由你进程中的内存管理器支持，你进程中的内存管理器事先从系统分配一批内存（系统内存是以内存页为单位分配的，最小分配一般是4096字节）。所以你即使free了，但是这部分内存只是交给了内存管理器，由内存管理器决定是否还给系统，特别是你malloc小块内存时，这部份内存不会交还给系统，此时对系统来说这块内存仍然是你process能够访问的。所以不会出错。


Question: 求助。

Both scanf and wscanf return 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-file character or the end-of-string character is encountered in the first attempt to read a character.   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.

scanf("%d",&a); 这个这个~~~

恩，scanf()语法是这样规定的，可以加一个非法输入语句控制就可以了，我编译了的，可以跑      #include <stdio.h>  int main() { 	int a=0; 	char ch; 	 	scanf("%d",&a); 	 	for(;a==0;) 	{	 		while ((ch = getchar()) != '\n') 			continue; 		scanf("%d",&a); 	} 	 	printf("%d",a); }

scanf("%d",&n); 应当输入数字，如果输入字母，scanf 语句执行失败。 int n; int flag; flag = scanf("%d",&n); if  (flag== 1) printf("good\n"); else printf("bad\n");  flag = scanf("%d",&n); 送返成功读入的数据个数。输入字母，flag 得0，n 原有值不变。  你的情况，由于输入流里的你输入的字母 没有被清掉，后面的输入语句连续执行失败。可以用 fflush(stdin);  清除 多余的东西。


Question: 各位大神，请教如何让三角形能够居中输出

先算空格，printf输出空格后在输出#个数 C++中可以用string串

如果你想计算的话，可以使用坐标法输入。这样很简单

输入空格是一种方法，每一行有多少个字符，没有星号的地方全部用空格代替。来给二维数组就解决了

用递归，比较简单

最后一行有n减几个空格没算，上面一次减一个，不就能计算出来了

#include <stdio.h> int main() { 	int n,i; 	scanf("%d", &n);  		for (int i=n;i>0;i--) 		{ 			for (int j=0;j<n+i-1;j++) 			{ 				if (j<n-i) 					printf(" "); 				 else 					 printf("#"); 			} 			printf("\n"); 		}  	return 0; } 拿去用吧，这是另外一个人问的问题。

控制好空格和行数的关系，比如第一行 空格数为0；第二行空格数为 1；第三行空格数为2，依次类推，先输入空格再输入#

每行前面输出事先计算好个数的空格。


Question: 这是一个键盘记录程序，我想把显示在控制台的内容显示保存到文件中，发现while循环中没法保存，该怎么办？

引用在每个fprintf(...);的后面加fflush(fp); 加上之后确实是正确的，可是为什么有时候不加flush(fp)也可以写入到文件呢？

在每个fprintf(...);的后面加fflush(fp);


Question: 一个关于位运算的宏定义求解（百分悬赏）！！

。。这个运算怎么逆过来啊。楼主做了吗

顶，只为赚分

GETLONG就是从data指向的地址取4个字节，组成一个32位的unsigned long  #define MCGETCHAR(data)  (*((char *)(data))) #define MCGETSHORT(data) \         ((unsigned short)(( ((unsigned short)(*((char *)(data))))<<8 )|( ((unsigned short)(*((char *)(data)+1)))&0x00ff ))) #define MCGETLONG(data) \         ( ( ((unsigned long)MCGETSHORT((data)))<<16 )|( ((unsigned long)MCGETSHORT((char *)(data)+2))&0x0000ffff ) ) #define MCGET3BN(data)  \         ( ( ((unsigned long)MCGETCHAR((data)))<<16 )|( ((unsigned long)MCGETSHORT((char *)(data)+1))&0x0000ffff ) )  #include <stdio.h>  int main(int argc, char *argv[]) {         char buf[4] = {0x12, 0x34, 0x56, 0x78};         unsigned char  uc;         unsigned short us;         unsigned long  ul;          unsigned long  u3;          /* 取一个字节 */         uc = MCGETCHAR(buf);         /* 取两个字节，组成short */         us = MCGETSHORT(buf);         /* 取四个字节，组成long */         ul = MCGETLONG(buf);         /* 取3个字节， 作为long的低24位, 高8位是零 */         u3 = MCGET3BN(buf);          printf("0x%02x 0x%04x 0x%08x 0x%08x\n", uc, us, ul, u3);          return 0; }  /* 输出:  0x12 0x1234 0x12345678 0x00123456  */

就是将高地址和低地址上的值互换

看着有中想跪的感觉

引用 24 楼 Idle_ 的回复:不就是大小端互换吗？知道啦，谢啦谢啦~~~

引用 23 楼 zilaishuichina 的回复:[quote=引用 21 楼 zilaishuichina 的回复:] 应该是 第2字节在最高位 第1字节在次高位 第4字节在次低位 第3字节在最低位  错了 还是 低地址的数据在高位，高地址的数据在低位  比如  int a = 0x12345678 int b=MCGETLONG(&a) //b = 0x78563412[/quote]搜噶····

不就是大小端互换吗？

引用 21 楼 zilaishuichina 的回复:应该是 第2字节在最高位 第1字节在次高位 第4字节在次低位 第3字节在最低位  错了 还是 低地址的数据在高位，高地址的数据在低位  比如  int a = 0x12345678 int b=MCGETLONG(&a) //b = 0x78563412

应该是 第2字节在最高位 第1字节在次高位 第4字节在次低位 第3字节在最低位

#define MCGETSHORT(data)													\ (																			\ 	(unsigned short)(														\ 						(													\ 							(												\ 								(unsigned short)(							\ 													*(						\ 														(char *)(data)		\ 													)						\ 												)							\ 							) << 8											\ 						)													\ 																			\ 						|													\ 																			\ 						(													\ 							(												\ 								(unsigned short)(							\ 													*(						\ 														(char *)(data) +1	\ 													)						\ 												)							\ 							) & 0x00ff										\ 						)													\ 					)														\ )  //data值所代表的那个地址，比如data为0x1b2ec， //(char *)(data)就是内存地址0x1b2ec //*((char *)(data))就是内存地址0x1b2ec里面的值X //(unsigned short)(*((char *)(data)))从地址0x1b2ec取一个char数据然后强转为short数据Y1 //Y1右移八位，就是比如Y1是0x12，变成0x1200  //下面类似 //(char *)(data) + 1 就是内存地址0x1b2ed //(unsigned short)(*((char *)(data)))从地址0x1b2ed取一个char数据然后强转为short数据Y2 //Y2 & 0x00ff，就是比如Y2是0x34，变成0x0034  //Y1 | Y2 就是 0x1200 | 0x0034 = 0x1234  //(unsigned short)(Y1 | Y2) 强转为short  //MCGETLONG类似  a=1b2ec // 这个应该是0x1b2ec  b=MCGETLONG(a) 取得地址为0x1b2ec里面4个字节的数据  低地址的数据在高位，高地址的数据在低位

引用 14 楼 liyachen777 的回复:[quote=引用 11 楼 lovesmiles 的回复:] 你写漏东西了  //声明宏函数 #define MCGETCHAR(data)  (*((char *)(data))) #define MCGETSHORT(data)  ((unsigned short)(( ((unsigned short)(*((char *)(data))))<<8 )|( ((unsigned short)(*((char *)(data)+1)))&0x00ff ))) //这是对short的处理，就是两个字节，将低字节复制到高位 #define MCGETLONG(data)  ( ( ((unsigned long)MCGETSHORT((data)))<<16 )|( ((unsigned long)MCGETSHORT((char *)(data)+2))&0x0000ffff ) )//这是对long的处理，就是四个字节，将低两字节复制到高位两字节  MCGETLONG展开后的结果就是四个字节的值都用低位字节的值表示。。··········额，那如果给了一个超出四位的数呢·····[/quote] unsgined long的长度就是4个字节，怎么超？超过了就当它只有4个字节，高位的全部看不见。

引用 16 楼 liyachen777 的回复:引用 5 楼 zilaishuichina 的回复:求 MCGETSHORT下面有，求解啊，大神！ 给个直观的例子你: 例如 data = 0xabcd; data1 = MCGETLONG(data); data1 就是0xdddd  就是将最低位的d复制到这四字节。

引用 12 楼 liyachen777 的回复:大神，那要是出个十六进制数，是不是先转成二进制，然后右移16位，然后跟后面那个比较？？？额···还是晕了，能通俗一点么···· 内存中的所有数据都是2进制，如果人要看的话可以转换成十六进制给人看 右移十六位是数学运算，即乘以2的16次方，和内存大小端没有关系 要容易理解，你可以把这个宏写成函数，每一个小运算都单独列一行，然后理解起来就容易得多，也可以一边调试一边观察 像这种有点复杂的运算，其实建议写成内联函数，比写成宏好得多

引用 13 楼 lovesmiles 的回复:抄个代码也不会看啊，我把你的源码在网上找到了 int read(char acFilePath[]) {  int nsizecount = 2 ;     //结构体数组从第二个位置开始存储数据 ；  FILE* pfp ;              //指针指向二进制文件 ；    char actotalsize[2] ;    //从二进制文件中读取道路信息的总体数据长度 ；  char aclinkId[4] ;       //从二进制文件中读取道路编号 ；  char acroadnamesize[2] ; //从二进制文件中读取道路名称数据长度；  char acNodeInfo[4] ;     //存储从二进制文件中读取的值 ；  pfp = FileOpen( acFilePath ) ;                           //读取文件： 打开原始文件或用户手动输入的文件路径名称 ；   start=clock();  printf("\n\t   读取文件.") ;     printf("\n\t   读取中......") ;        while( 1 )                 //循环读取数据，直到pfp指针指向文件的末尾 ；  {       if( fread( actotalsize , sizeof(actotalsize) , 1 , pfp ) == NULL )   {        fclose(pfp) ;       end=clock();       printf("\n\t   文件读取成功，用时%f秒\n\n",(double)(end-start)/CLOCKS_PER_SEC);       return nsizecount-1 ;   }        fread( aclinkId , sizeof(aclinkId) , 1 , pfp ) ;         //读取占用4字节的linkId字符串；      fread( acroadnamesize , sizeof(acroadnamesize) , 1 , pfp ) ;                              //读取占用2字节的roadnamesize字符串；      fread( acNodeInfo , sizeof(acNodeInfo) , 1 , pfp ) ;                                    //读取占用4 字节的dispclass ， brunch ， 和 roadnameflag字符串 ；                             //调用宏函数 ， 将字符串信息转化为数值类型  ；         unsigned short ustotalsize = MCGETSHORT( actotalsize ) ;         unsigned long  ullinkId = MCGETLONG( aclinkId ) ;         unsigned short usroadnamesize = MCGETSHORT( acroadnamesize ) ;                               //赋值 ：将数值信息传到结构体中  ；         road[nsizecount].ussize = ustotalsize ;         road[nsizecount].ullinkId = ullinkId ;         road[nsizecount].usroadnamesize= usroadnamesize ;                              //从一个字节中读取dispclass ， brunch 以及roadnameflag的值 ；      int m=(int)acNodeInfo[3]&255;      road[nsizecount].usdispclass=m&15;      road[nsizecount].usbrunch=(m&112)/16;      road[nsizecount].usroadnameflag=(m&128)/128;                           //从文件中读取道路名称 ；      fread( &road[nsizecount].roadname , sizeof(char) , ustotalsize - 12 , pfp ) ;            nsizecount++;  }      return 0; }额······那我的四句宏定义是不是就是这个功能·····

引用 11 楼 lovesmiles 的回复:你写漏东西了  //声明宏函数 #define MCGETCHAR(data)  (*((char *)(data))) #define MCGETSHORT(data)  ((unsigned short)(( ((unsigned short)(*((char *)(data))))<<8 )|( ((unsigned short)(*((char *)(data)+1)))&0x00ff ))) //这是对short的处理，就是两个字节，将低字节复制到高位 #define MCGETLONG(data)  ( ( ((unsigned long)MCGETSHORT((data)))<<16 )|( ((unsigned long)MCGETSHORT((char *)(data)+2))&0x0000ffff ) )//这是对long的处理，就是四个字节，将低两字节复制到高位两字节  MCGETLONG展开后的结果就是四个字节的值都用低位字节的值表示。。··········额，那如果给了一个超出四位的数呢·····


Question: 求助程序运行时的输入完毕问题。

引用 4 楼 zhao4zhong1 的回复:Linux:Ctrl+D Windows:Enter,Ctrl+Z,Enter 我的是windows,确实成功了。非常感谢你。我自己再去脑补这个知识。

Linux:Ctrl+D Windows:Enter,Ctrl+Z,Enter

我试验了一下。我的系统的回车就是\n

输入 EOF  按回车试试  还是不行的话看看有没有死循环

有的系统回车是"\r\n"


Question: [问题]c语言中，如何把一个300M的文件一次读进一个数组？

问题已经解决 #include<stdio.h> #include<stdlib.h>  int main(int num, const char * file[]) { 	char *p=NULL;  	p=(char *)malloc(1024*1024*1024); 	if(p) 		printf("memory allocated at %p\n", p); //pointer's address 	else 		printf("not enough memory!\n");  	FILE *fin; 	fin=fopen(file[1], "rb"); 	fread(p, 1, 209853182, fin);  	int loc=209853182-1;  	printf("%c\n", p[loc]); 	fclose(fin); 	  	free(p); 	return 0; }

内存映射是平台相关的，Windows下用CreateFileMapping()+MapViewOfFile(), Linux下用mmap()

妥妥的内存映射文件，具体百度下。

引用 2 楼 damaoshan 的回复:[quote=引用 1 楼 go_and_see 的回复:] 最好不要一次读300M的内容，可以根据业务做缓冲。 您的意思是？ 怎么缓冲呢？ 我是小白，不好意思[/quote]  弄一个缓冲区，每次只读一部分。一次读300M，内存消耗太多，磁盘性能也跟不上。

单独的独立程序，那是不成问题的 如果是某个程序的一个模块，那就成问题了。

引用 3 楼 Oringe_new 的回复:弄内存文件映射吧 求教具体代码

引用 4 楼 Idle_ 的回复:直接malloc分配300M内存然后一次性fread 我也是这么想的，但是代码没写出来。 总之，还在糊涂中

弄内存文件映射吧

引用 1 楼 go_and_see 的回复:最好不要一次读300M的内容，可以根据业务做缓冲。 您的意思是？ 怎么缓冲呢？ 我是小白，不好意思

最好不要一次读300M的内容，可以根据业务做缓冲。


Question: ffmpeg在安装x264播放器的时候出现 ERROR: libx264 not found

我是用楼主的方法，显示了Unknown option --extra-libs=-ldl, ignored请问这是为什么呢？

./configure  --extra-libs=-ld  直接用这个命令

要在./configure 选项的哪个地方加上 --extra-libs=-ld 啊。我现在也出现这个问题了。怎么解决呢？

引用 4 楼 zhao4zhong1 的回复:./configure         make         su         输入root用户的密码         make install  解决了。。。只要在configure选项里面加上 --extra-libs=-ldl就可以了

引用 2 楼 zz12006345 的回复:makefile使用shell写的。。找不到把路径加在哪里怎么办。。。 仔细找，应该能找到。

makefile使用shell写的。。找不到把路径加在哪里怎么办。。。

在GUI配置相应项或makefile里面的gcc命令行中添加-ldl


Question: windows 提示信息

看看pagefile.sys文件在哪个硬盘上，将那个硬盘的剩余空间留大点。

需要我翻译吗： 由于你系统的虚拟内存太小，系统正在增加虚拟内存页文件的大小，在此期间，一些应用程序的内存请求将会被拒绝，想获得更多的信息，请查看帮助文档。  基本不用理会，就是系统提示你虚拟内存太小而已

我 的 虚拟机  经常 提醒 我这个，一直没管它。  如果你需要 保存 大量文件，建议删除不必要文件，如果你本身硬盘就小，只能用大的 取而代之。

英文版的windows虚拟内存太小。 有可能的原因是，虚拟内存所在的硬盘，没有空间了。


Question: linux c 关于vfork正确执行的问题

详见以下链接： http://www.embeddedlinux.org.cn/html/xianchengjincheng/201304/14-2542.html

谢谢大家对我提问的回答，不过都是在解释 vfork，这些书上我都看过。  我想知道的答案是针对我的代码的，为什么会产生这种效果？ 从内存机制，系统的实现层面分析下，为什么两种情况执行结果是不同的

引用 楼主 zwl6695125 的回复:本人linux新手，没多少分可以给，希望大牛们看在都是搞技术的层面上帮我解决下问题。  在编译下述代码的时候  如果已经宏定义了DEBUG 产生如下结果：  child : process id is 4287 child : parent process id is 4286  havent run strcpy -> buf:THIS IS parent process line have   run strcpy -> buf:parent : process line parent : process id is 4286  如果没有宏定义DEBUG 产生如下结果：  child : process id is 4223 child : parent process id is 4222  havent run strcpy -> buf:child : process write have   run strcpy -> buf:parent : process line parent : process id is 4222  point is ： 为什么 “havent run strcpy ->” 所在行的显示会有不同 ？ 编译环境：ubuntu 10.04.3, gcc 代码如下   #include <sys/types.h> #include <unistd.h>  #include <sys/stat.h> #include <fcntl.h>  #include <stdio.h> #include <stdlib.h> #include <string.h>  #define DEBUG  char  buf[100];  int main(int argc, char **argv) {     int   fd;  #ifdef DEBUG     pid_t pid = vfork(); #else     pid_t pid = -1; #endif      if((fd = open("temp", O_CREAT | O_TRUNC | O_RDWR, S_IRWXU)) == -1)     {         perror("open file error !\n");         return 0;     }      strcpy(buf, "THIS IS parent process line\n");  #ifdef DEBUG     if(pid == 0) #else     if( (pid = vfork()) == 0) #endif     {         strcpy(buf, "child : process write\n");                  printf("\n");         printf("child : process id is %d\n", getpid());         printf("child : parent process id is %d\n\n", getppid());                 write(fd, buf, strlen(buf));         close(fd);          exit(0);    //child process must exit while work done     }     else     {         printf("havent run strcpy -> buf:%s", buf);         strcpy(buf, "parent : process line\n");         printf("have   run strcpy -> buf:%s", buf);          printf("parent : process id is %d\n", getpid());         write(fd, buf, strlen(buf));          printf("\n");         close(fd);     }     return 0; }   linux 男人一下就知道

现在假设你已经了解fork的行为了。 vfork与fork的两点区别： 1. vfork这个函数的意义就在于立马执行exec函数（当然你用作其它用途也未尝不可），因为vfork不会复制父进程的地址空间，因此可能比fork高效一些(之所以说“可能”，是因为在实现的时候，fork也未必会复制父进程的地址空间)。  在调用exec函数或exit之前，vfork出来的子进程都是在父进程的地址空间中运行的，因此对父进程的运行有影响。 2. 调用fork，父子进程的执行顺序不能保证，但是调用vfork的时候，会保证子进程先执行，直到子进程执行exec系列函数或调用exit

引用 13 楼 zhao4zhong1 的回复:[quote=引用 12 楼 zwl6695125 的回复:] [quote=引用 5 楼 zhao4zhong1 的回复:] man 2 vfork  老师，我一个新手对诸多概念都不太熟悉，真的麻烦您帮我讲的通俗易懂点[/quote] 在shell命令行中输入以上命令，查看vfork的联机帮助。 会使用man命令是Linux程序员必须掌握的技能之一。[/quote]  查看手册，这个我还是会的。就是面对英文手册上写的不知道哪点是能解决我这个问题的。 所以，希望您能针对我这个问题，详细解释下

引用 12 楼 zwl6695125 的回复:[quote=引用 5 楼 zhao4zhong1 的回复:] man 2 vfork  老师，我一个新手对诸多概念都不太熟悉，真的麻烦您帮我讲的通俗易懂点[/quote] 在shell命令行中输入以上命令，查看vfork的联机帮助。 会使用man命令是Linux程序员必须掌握的技能之一。

引用 5 楼 zhao4zhong1 的回复:man 2 vfork  老师，我一个新手对诸多概念都不太熟悉，真的麻烦您帮我讲的通俗易懂点

引用 10 楼 zxh707wk 的回复:[quote=引用 9 楼 zwl6695125 的回复:] [quote=引用 6 楼 zxh707wk 的回复:] 不用vfork行吗？  太调皮了！我是想知道到为什么，当然，不用也可以[/quote]不要写连自己也预测不了结果的代码！[/quote]  这个代码肯定不会用的，只是在学习阶段学点知识的

引用 9 楼 zwl6695125 的回复:[quote=引用 6 楼 zxh707wk 的回复:] 不用vfork行吗？  太调皮了！我是想知道到为什么，当然，不用也可以[/quote]不要写连自己也预测不了结果的代码！

引用 6 楼 zxh707wk 的回复:不用vfork行吗？  太调皮了！我是想知道到为什么，当然，不用也可以

引用 3 楼 Idle_ 的回复:好像vfork() child process可以修改parent process的局部变量的。而child和parent是并行执行的，因此release时child的        strcpy(buf, "child : process write\n"); 可能在parent的        printf("havent run strcpy -> buf:%s", buf);之前执行了  对于vfork好像是会阻塞父进程，直到子进程结束的吧？

引用 4 楼 user-6 的回复:你这个就是因为fork引起的输出缓冲区的紊乱  这个fork和vfork最近刚学，帮我解释详细点可以吗？

不用vfork行吗？

两个进程共享堆栈当然危险啦

引用 15 楼 Idle_ 的回复:fork，顾名思义，就是分叉，fork返回后，产生的子进程和父进程一样从fork后一句开始执行，两者是并行的，vfork和fork基本一样，但是vfork省略了很多父进程内存页面的复制，因此vfork后子进程和父进程是共享堆栈的，也因此子进程对局部变量的修改可以影响父进程。vfork设计的主要目的是为了执行exec族命令的，因为它不需要复制父进程所有数据，因此加载速度快。但是你在vfork后执行其它语句却是非常危险的，因为很容易和父进程产生冲突。  可以从linux 系统实现的角度分析下为什么 \ “但是你在vfork后执行其它语句却是非常危险的，因为很容易和父进程产生冲突。”吗？

man 2 vfork

你这个就是因为fork引起的输出缓冲区的紊乱

引用 1 楼 zhao4zhong1 的回复:在每个最后不带\n的printf后面加fflush(stdout);  没有作用……，麻烦您再帮我看看


Question: 新人请教C语言，用结构体写的程序

这个问题我无法解释，但只要删掉scanf里的','就一切正常了 #include <stdio.h>  struct student { 	int num; 	char name[10]; 	int score[3]; };  void input(struct student p[],int n) { 	int i; 	for(i=0;i<n;i++) 	{ 		scanf("%d%s%d%d%d",&p[i].num,p[i].name,&p[i].score[0],&p[i].score[1],&p[i].score[2]); 	} } void print(struct student m[],int n) { 	int i; 	printf("\n"); 	for(i=0;i<n;i++) 	{ 		printf("%7d,%4s,%4d,%4d,%4d\n",m[i].num,m[i].name,m[i].score[0],m[i].score[1],m[i].score[2]); 	} }  int main() { 	struct student s[2]; 	input(s,2); 	print(s,2); 	return 0; }

引用 3 楼 user-5 的回复:scanf("%d%s%d%d%d",&p[i].num,p[i].name,&p[i].score[0],&p[i].score[1],&p[i].score[2]); scanf输入格式里面是不需要其他不需要的符号的这个可以有

scanf, wscanf Read formatted data from the standard input stream.  int scanf( const char *format [,argument]... );  int wscanf( const wchar_t *format [,argument]... );  Routine Required Header Compatibility  scanf <stdio.h> ANSI, Win 95, Win NT  wscanf <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  Both scanf and wscanf return 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-file character or the end-of-string character is encountered in the first attempt to read a character.  Parameters  format  Format control string  argument  Optional arguments  Remarks  The scanf function reads data from the standard input stream stdin and writes the data into the location given by argument. Each argument must be a pointer to a variable of a type that corresponds to a type specifier in format. If copying takes place between strings that overlap, the behavior is undefined.  wscanf is a wide-character version of scanf; the format argument to wscanf is a wide-character string. wscanf and scanf behave identically otherwise.   Generic-Text Routine Mappings  TCHAR.H Routine  _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined  _tscanf scanf scanf wscanf    For more information, see Format Specification Fields — scanf functions and wscanf Functions.   Example   /* SCANF.C: This program uses the scanf and wscanf functions   * to read formatted input.   */  #include <stdio.h>  void main( void ) {    int   i, result;    float fp;    char  c, s[81];    wchar_t wc, ws[81];     printf( "\n\nEnter an int, a float, two chars and two strings\n");     result = scanf( "%d %f %c %C %s %S", &i, &fp, &c, &wc, s, ws );    printf( "\nThe number of fields input is %d\n", result );    printf( "The contents are: %d %f %c %C %s %S\n", i, fp, c, wc, s, ws);     wprintf( L"\n\nEnter an int, a float, two chars and two strings\n");     result = wscanf( L"%d %f %hc %lc %S %ls", &i, &fp, &c, &wc, s, ws );    wprintf( L"\nThe number of fields input is %d\n", result );    wprintf( L"The contents are: %d %f %C %c %hs %s\n", i, fp, c, wc, s, ws); }   Output  Enter an int, a float, two chars and two strings 71 98.6 h z Byte characters  The number of fields input is 6 The contents are: 71 98.599998 h z Byte characters  Enter an int, a float, two chars and two strings 36 92.3 y n Wide characters  The number of fields input is 6 The contents are: 456 92.300003 y n Wide characters   Floating-Point Support Routines, Stream I/O Routines, Locale Routines  See Also   fscanf, printf, sprintf, sscanf

写多几个scanf.或者像赵老师说的检查scanf的返回值，看看scanf录入了多少个变量。

引用 4 楼 benny89415 的回复:断点测试下就知道了。。。 你的录入char【10】的时候直接把“，”也录入进去了，要知道，“，”也是char的一种。明白了，谢谢

引用 3 楼 user-5 的回复:scanf("%d%s%d%d%d",&p[i].num,p[i].name,&p[i].score[0],&p[i].score[1],&p[i].score[2]); scanf输入格式里面是不需要其他不需要的符号的 哪些是其他的符号呢？不好意思，有点不太明白

引用 3 楼 user-5 的回复:scanf("%d%s%d%d%d",&p[i].num,p[i].name,&p[i].score[0],&p[i].score[1],&p[i].score[2]); scanf输入格式里面是不需要其他不需要的符号的 符号是可以作为判定的，但是，录入字符串的时候就不好判定了

引用 1 楼 zhao4zhong1 的回复:请检查scanf的返回值！ 可以说的详细点吗，scanf有返回值吗

请检查scanf的返回值！


Question: 一个求素数的小程序，为什么我的结果是从29611开始呢？

试试运行下这个代码： #include<stdio.h> #include <Windows.h> main() { int i,n; for(n=2;n<=32767;++n) { for(i=2;n%i;++i); if(i==n) {  printf("%d\n",n); 	Sleep(1000); } } } 运行了你就知道了。程序是对的，但是显示不完那么多的数字。

嗯，可以对窗口进行设置，也可以将数据输入到文本中，如下——

程序没问题，输出超过缓冲区大小了

那个黑色窗口默认好像只能输出298行，如果你想全部显示，需要对黑色窗口进行设置

输出到文件或者重定向到文件.

引用 1 楼 u012421456 的回复:那个黑色窗口默认好像只能输出298行，如果你想全部显示，需要对黑色窗口进行设置  ++

确实是cmd窗口的显示行数有限制所致


Question: fprintf(stderr, _("%s: FATAL: %s\n"), prgname, strerror(ENOMEM));

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

引用 2 楼 user-3 的回复:加/EP编译选项看看 fprintf(stderr, _("%s: FATAL: %s\n"), prgname, strerror(ENOMEM)); 这行被宏展开后变成什么了 是个宏定义…… 谢谢饿了

引用 楼主 wuzhimang 的回复:一直查不到，关于类sprintf中，出现的_()表示的意思，忘大神指点下，或告知参考资料……  为什么用_(...)这个 引用 1 楼 lovesmiles 的回复:这个一般是字符串处理宏。你的项目有没有定义#define _()  这样的宏? 确定你没有写漏什么东西？  我下的源码看到，恩，确实找到了宏定义，以前没见过类似处理的，所以一时不知道怎么想


Question: 求解一个 ld 链接问题

C程序就应该用gcc来链接啊，你这样有意义吗？

引用 11 楼 gjq_1988 的回复:[quote=引用 9 楼 dbzhang800 的回复:] [quote=引用 7 楼 gjq_1988 的回复:] [quote=引用 6 楼 dbzhang800 的回复:] 这只是举个例子，具体在那个路径下，具体叫什么名字，都是可以随编译器或你所用系统变化的。  我的ubuntu系统里没有crt0.o 但是有crt1.o和 crti.o 我把他们链进去后  还是那种情况：连接器不包错，运行的时候报错bash: ./test: No such file or directory  ps：而且我已经用-e main 参数指定了入口地址为main函数的地址，就算不链接crt0.o什么的也应该是可以的吧。。。  你可以试一下，就是无法运行，关键是链接完还不报错[/quote]  main 是C/C++ 程序的入口，但并不是真正的系统需要的入口函数，在调用main之前，C/C++ 运行库还要做大量其他工作的。[/quote]  我知道 但是我这里就是指定 我的main为进程入口， 不走_start ，不走系统运行时库，这是可以的，在《程序员的自我修养》里有这么干过[/quote] 可惜printf.c的功能依赖crt0.c中的相关初始化过程。我猜。

ldd test看下，应该是格式 不对

引用 9 楼 dbzhang800 的回复:[quote=引用 7 楼 gjq_1988 的回复:] [quote=引用 6 楼 dbzhang800 的回复:] 这只是举个例子，具体在那个路径下，具体叫什么名字，都是可以随编译器或你所用系统变化的。  我的ubuntu系统里没有crt0.o 但是有crt1.o和 crti.o 我把他们链进去后  还是那种情况：连接器不包错，运行的时候报错bash: ./test: No such file or directory  ps：而且我已经用-e main 参数指定了入口地址为main函数的地址，就算不链接crt0.o什么的也应该是可以的吧。。。  你可以试一下，就是无法运行，关键是链接完还不报错[/quote]  main 是C/C++ 程序的入口，但并不是真正的系统需要的入口函数，在调用main之前，C/C++ 运行库还要做大量其他工作的。[/quote]  我知道 但是我这里就是指定 我的main为进程入口， 不走_start ，不走系统运行时库，这是可以的，在《程序员的自我修养》里有这么干过

如果你真的这么想调用 ld，直接运行下面的命令  gcc -o test main.o -v  即可看到正常连接时，需要传递给链接器参数。而后把这一堆需要的东西传给你的 ld 即可

引用 7 楼 gjq_1988 的回复:[quote=引用 6 楼 dbzhang800 的回复:] 这只是举个例子，具体在那个路径下，具体叫什么名字，都是可以随编译器或你所用系统变化的。  我的ubuntu系统里没有crt0.o 但是有crt1.o和 crti.o 我把他们链进去后  还是那种情况：连接器不包错，运行的时候报错bash: ./test: No such file or directory  ps：而且我已经用-e main 参数指定了入口地址为main函数的地址，就算不链接crt0.o什么的也应该是可以的吧。。。  你可以试一下，就是无法运行，关键是链接完还不报错[/quote]  main 是C/C++ 程序的入口，但并不是真正的系统需要的入口函数，在调用main之前，C/C++ 运行库还要做大量其他工作的。

参考crt0.c的内容。

引用 6 楼 dbzhang800 的回复:这只是举个例子，具体在那个路径下，具体叫什么名字，都是可以随编译器或你所用系统变化的。  我的ubuntu系统里没有crt0.o 但是有crt1.o和 crti.o 我把他们链进去后  还是那种情况：连接器不包错，运行的时候报错bash: ./test: No such file or directory  ps：而且我已经用-e main 参数指定了入口地址为main函数的地址，就算不链接crt0.o什么的也应该是可以的吧。。。  你可以试一下，就是无法运行，关键是链接完还不报错

引用 4 楼 gjq_1988 的回复:[quote=引用 2 楼 user-5 的回复:] ld -o <output> /lib/crt0.o hello.o -lc This tells ld to produce a file called output as the result of linking the file "/lib/crt0.o" with "hello.o" and the library "libc.a", which will come from the standard search directories.   你好 ld: /lib/crt0.o: No such file: No such file or directory 我在/usr/lib 里没看到这个crt0.o 请问它的绝对路径在哪里 [/quote] find 一下咯

引用 2 楼 user-5 的回复:ld -o <output> /lib/crt0.o hello.o -lc This tells ld to produce a file called output as the result of linking the file "/lib/crt0.o" with "hello.o" and the library "libc.a", which will come from the standard search directories.   你好 ld: /lib/crt0.o: No such file: No such file or directory 我在/usr/lib 里没看到这个crt0.o 请问它的绝对路径在哪里

引用 1 楼 dbzhang800 的回复:直接用gcc链接多好啊  gcc -o test main.o  用ld的话，除指定C标准库外，C的 crt0 也需要指定，比如  ld -o test /lib/libcrt0.o main.o -lc  /usr/lib/libcrt0.o: No such file: No such file or directory


Question: 求助大神一个关于二叉树递归建立的问题

“给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出

仅供参考#include <iostream> #include <stack> #include <queue> #include <locale.h> using namespace std; typedef struct BiTNode {//二叉树结点     char data;                      //数据     struct BiTNode *lchild,*rchild; //左右孩子指针 } BiTNode,*BiTree; int CreateBiTree(BiTree &T) {//按先序序列创建二叉树     char data;     scanf("%c",&data);//按先序次序输入二叉树中结点的值（一个字符），‘#’表示空树     if (data == '#') {         T = NULL;     } else {         T = (BiTree)malloc(sizeof(BiTNode));         T->data = data;         //生成根结点         CreateBiTree(T->lchild);//构造左子树         CreateBiTree(T->rchild);//构造右子树     }     return 0; } void Visit(BiTree T) {//输出     if (T->data != '#') {         printf("%c ",T->data);     } } void PreOrder(BiTree T) {//先序遍历     if (T != NULL) {         Visit(T);               //访问根节点         PreOrder(T->lchild);    //访问左子结点         PreOrder(T->rchild);    //访问右子结点     } } void InOrder(BiTree T) {//中序遍历     if (T != NULL) {         InOrder(T->lchild);     //访问左子结点         Visit(T);               //访问根节点         InOrder(T->rchild);     //访问右子结点     } } void PostOrder(BiTree T) {//后序遍历     if (T != NULL) {         PostOrder(T->lchild);   //访问左子结点         PostOrder(T->rchild);   //访问右子结点         Visit(T);               //访问根节点     } } void PreOrder2(BiTree T) {//先序遍历(非递归) //访问T->data后，将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，再先序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             printf("%c ",p->data);  //访问根节点             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈             stack.pop();             p = p->rchild;          //访问右子树         }     } } void InOrder2(BiTree T) {//中序遍历(非递归) //T是要遍历树的根指针，中序遍历要求在遍历完左子树后，访问根，再遍历右子树。 //先将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，访问T->data，再中序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈，访问根节点             printf("%c ",p->data);             stack.pop();             p = p->rchild;          //访问右子树         }     } }  typedef struct BiTNodePost{     BiTree biTree;     char tag; } BiTNodePost,*BiTreePost; void PostOrder2(BiTree T) {//后序遍历(非递归)     stack<BiTreePost> stack;     BiTree p = T;//p是遍历指针     BiTreePost BT;     while (p != NULL || !stack.empty()) {//栈不空或者p不空时循环         while (p != NULL) {//遍历左子树             BT = (BiTreePost)malloc(sizeof(BiTNodePost));             BT->biTree = p;             BT->tag = 'L';//访问过左子树             stack.push(BT);             p = p->lchild;         }         while (!stack.empty() && (stack.top())->tag == 'R') {//左右子树访问完毕访问根节点             BT = stack.top();             stack.pop();//退栈             printf("%c ",BT->biTree->data);         }         if (!stack.empty()) {//遍历右子树             BT = stack.top();             BT->tag = 'R';//访问过右子树             p = BT->biTree;             p = p->rchild;         }     } }  void LevelOrder(BiTree T) {//层次遍历     if (T == NULL) return;     BiTree p = T;     queue<BiTree> queue;//队列     queue.push(p);//根节点入队     while (!queue.empty()) {    //队列不空循环         p = queue.front();      //对头元素出队         printf("%c ",p->data);  //访问p指向的结点         queue.pop();            //退出队列         if (p->lchild != NULL) {//左子树不空，将左子树入队             queue.push(p->lchild);         }         if (p->rchild != NULL) {//右子树不空，将右子树入队             queue.push(p->rchild);         }     } } int main() {     BiTree T;      setlocale(LC_ALL,"chs");     CreateBiTree(T);      printf("先序遍历        ：");PreOrder  (T);printf("\n");     printf("先序遍历(非递归)：");PreOrder2 (T);printf("\n");                                                printf("\n");     printf("中序遍历        ：");InOrder   (T);printf("\n");     printf("中序遍历(非递归)：");InOrder2  (T);printf("\n");                                                printf("\n");     printf("后序遍历        ：");PostOrder (T);printf("\n");     printf("后序遍历(非递归)：");PostOrder2(T);printf("\n");                                                printf("\n");     printf("层次遍历        ：");LevelOrder(T);printf("\n");      return 0; } //ABC##DE#G##F### //先序遍历        ：A B C D E G F //先序遍历(非递归)：A B C D E G F // //中序遍历        ：C B E G D F A //中序遍历(非递归)：C B E G D F A // //后序遍历        ：C G E F D B A //后序遍历(非递归)：C G E F D B A // //层次遍历        ：A B C D E F G //  ///       A ///      / ///     B ///    / \ ///   C   D ///      / \ ///     E   F ///      \ ///       G

个人感觉需要在创建树的代码末尾加个return 0  if(!CreateBiTree(&T))的意思是如果树没有创建成功。。。，有没有创建成功根据CreateBiTree的返回值判断  *T = (BiTNode *)malloc(sizeof(BiTNode));  这句话说明每一次创建一个节点都申请了内存，分配了空间。也就解释了你最后的问题。


Question: 一个小函数内存的bug，如何理解！

额。。。说白了：指针p中的内存地址就是指向这个字符串的第一个字符，你觉得一个定义了的字符串（系统已经为这个字符串分配好了内存），他的地址是你可以随便改变的吗？？？

引用 10 楼 zhao4zhong1 的回复:#pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！ 还是不可以写啊，linux下测试的

引用 4 楼 virtualxmars 的回复:这一句：  char *p = "WanG";   因为"WanG"对编译器来说实际上是一个常量，也就是不允许变化的量，所以将其赋值给char *p是不对的，因为 char * 实际上指出p是可以被修改的。而"WanG"其实会被放在不可编辑的全局符号表位置。那么你后面的修改就是非法的了。  解决办法是：      char name[] = "WanG";     char *p = name;   由于引入了数组，所以"WanG"会定义在函数的堆中，这样，它就变成了可被修改的内容 +1

引用 13 楼 xhw88398569 的回复:引用 3 楼 liuxiaohailxh8888 的回复:改写常量需要用memset我居然信了，还好测试了一下 恩,确实是错的,当我发完帖子突然发现是错的但是编辑不鸟帖子了

引用 14 楼 xhw88398569 的回复:[quote=引用 10 楼 zhao4zhong1 的回复:] #pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！ 还是不可以写啊，linux下测试的[/quote] 这是windows下的。

貌似向常量区写东西了

改写常量需要用memset

char q[10] = "WanG"; 	char* p = q;

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

字符串常量。基础

引用 2 楼 zhousitiaoda 的回复: char q[10] = "WanG"; 	char* p = q; +1 字符串常量不能被修改，如果你硬要修改的话有方法@赵老师

char *p = "WanG"; 这样定义一个常量字符串，是没办法用=赋值来改变的

char *p = "WanG"; // read only  //... *p =  tolower('D'); //oops

char* p和 char p［］的最大区别就是一个是const，一个不是。


Question: MFC 应用程序错误

找到原因了 pDC 没有释放！！！

我调试了 出现这个 ，请问这个和Brush用法有关吗 ！谢谢

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


Question: 关于链表释放问题，求指点

引用 3 楼 xinsuixiaofeiyu 的回复:[quote=引用 2 楼 eziowayne 的回复:] 感觉方法挺靠谱的，俺以前学链表时是这么实现的。 具体嘛还要看代码才知道有没有问题。这样写有个问题就是，本身链表是释放了，但是seg本事的地址还是会存在，只是*seg指向为NULL[/quote]  最好让我看看代码～ *seg指向NULL？不太明白你的结构了。 按照我的理解，seg的地址还会存在是因为free不会去修改seg的指向，这种情况我们叫seg为野指针，野指针在重新分配内存之前是不能使用滴～

引用 2 楼 eziowayne 的回复:感觉方法挺靠谱的，俺以前学链表时是这么实现的。 具体嘛还要看代码才知道有没有问题。这样写有个问题就是，本身链表是释放了，但是seg本事的地址还是会存在，只是*seg指向为NULL

仅供参考//假设带表头结点的单向链表头指针为head，试编写一个算法将值为5的结点插入到连接表的第k个结点前，删除第k个节点，并对该链表进行排序。 #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-> //


Question: 谁有一些c程序的例题用来练手和思维

http://www.baidu.com c程序例题

先下载Win-TC，然后参考C:\Win-TC\tcstudy.chm

Lua源码分析。可以仔细读一下Lua的源代码。才2万多行，如果觉得c语言基础还不错的话，应该没什么难度的。

pat练习 http://pat.zju.edu.cn/contests/mooc-c

我最近看了下vim for PC的源代码，企图知道vim是如何读文件的（似乎它读大文件很快），但看不太明白，能帮我看看吗？  源代码下载页面： http://www.vim.org/download.php

http://pan.baidu.com/s/1eQiofPw 这个是我老师复习时用的题目

那就去面试吧，跟面试官交流、练思维

http://download.csdn.net/detail/zidane_2014/7671075 http://download.csdn.net/detail/zidane_2014/7671093 上下部分。不需要下载积分。

如果不满足于自己用的教材上的习题，那就去做ACM题吧，各高校的ACM网站大多都是可以随意注册的吧？ 至于向别人要例题——如果有个小学生向楼主要小学练习题，楼主能拿得出来不？

我共享里有，你自己找找吧

一般来说ACM的题都比较不简单，你随便百度一下就可以了

一般来说ACM的题都比较简单，你随便百度一下就可以了


引用 6 楼 ren0065 的回复:	double n = 1.0, m = 1.0; 	for(int i=1; i<10; i++) 	{ 		m = -m; 		n += m*(1.0/(i+1)); 	} 	printf("%f\n", n); 不应该是这样吗?是的，我的数据类型弄错了。谢谢

引用 7 楼 lovesmiles 的回复:改成下面这样子：  void main() { 	long double s,m=0; 	int i,n=-1; 	for (i=1;i<=100;i=i+2) 	{ 		n=-n; 		s=n*i; 		m=m+1/s; 	} 	printf("%f\n",m*4); }谢谢

引用 4 楼 Intel0011 的回复:[quote=引用 1 楼 chlth007 的回复:] 错了，应该调试这个，上面那个是书本上给的答案。 #include<stdio.h> main() { 	long double s,m=0; 	int i,n=-1; 	for (i=1;i<=100;i++) 	{ 		n=-n; 		s=n*i; 		m=m+1/s; 	} 	printf("%ld\n",m); } m是long double类型 printf("%ld\n",m); －－－》 printf("%f\n",m);[/quote]  谢谢，现在好了。是不是新手经常容易出现这种情况，自己又找不到错误的地方？

for ( n = 1, n <=100; n++)     sum = sum + 1/n * pow(-1, (n + 1))

引用 1 楼 chlth007 的回复:错了，应该调试这个，上面那个是书本上给的答案。 #include<stdio.h> main() { 	long double s,m=0; 	int i,n=-1; 	for (i=1;i<=100;i++) 	{ 		n=-n; 		s=n*i; 		m=m+1/s; 	} 	printf("%ld\n",m); } m是long double类型 printf("%ld\n",m); －－－》 printf("%f\n",m);

计算圆周率的公式：PI=(1-1/3+1/5-1/7+1/9……)*4 引用 1 楼 chlth007 的回复:错了，应该调试这个，上面那个是书本上给的答案。 #include<stdio.h> main() { 	long double s,m=0; 	int i,n=-1; 	for (i=1;i<=100;i++) 	{ 		n=-n; 		s=n*i; 		m=m+1/s; 	} 	printf("%ld\n",m); }

计算圆周率的？记得似乎要乘以3。我找一下。


Question: 新人求指教，为什么strcpy函数没有成功复制

引用 11 楼 qq_16696537 的回复:[quote=引用 9 楼 zxx150633 的回复:] 还有个问题，把函数写成这样： void search(char (*pointer)[4]) { 	char *pt; 	pt=*(pointer); 	*(pointer)=*(pointer+1); 	*(pointer+1)=pt; } 为什么会有这样的错误error C2106: '=' : left operand must be l-value *pointer是一个字符数组，很明显它是不能作为一个可赋值的变量放在等号左边的。。。[/quote] 明白了，谢谢

引用 9 楼 zxx150633 的回复:还有个问题，把函数写成这样： void search(char (*pointer)[4]) { 	char *pt; 	pt=*(pointer); 	*(pointer)=*(pointer+1); 	*(pointer+1)=pt; } 为什么会有这样的错误error C2106: '=' : left operand must be l-value *pointer是一个字符数组，很明显它是不能作为一个可赋值的变量放在等号左边的。。。

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  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",...);】来理解指针的本质， 而要依赖调试时的反汇编窗口中的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

十分感谢，豁然开朗。确实是自己基础太不好了。

估计楼主C语言不过关。

引用 3 楼 zxx150633 的回复:pt=*(pointer);指针变量pt中存放的应该是pointer的地址，strcpy()函数中的形参不就是地址吗，我感觉这和数组是一样的呀 错了。参考楼上几位的答案。

你用指针变量保存的仅仅是个指针，strcpy(*pointer,*(pointer+1));执行后这个指针指向的数据已经被覆盖了。

我用数组试了一下，结果就正确了，但是不明白为什么结果是正确的，我感觉数组和指针变量是一样的呀。 void search(char (*pointer)[4]) { 	char pt[10]; 	//pt=*(pointer); 	strcpy(pt,*pointer); 	strcpy(*pointer,*(pointer+1)); 	strcpy(*(pointer+1),pt); } 这样结果就是对的

楼主的目的应该交换2个字符串，pt=*(pointer)；你用pt来保存其实保存的只是个指针值而不是字符串，你应该搞个数组，然后把*(pointer);拷贝到数组里，最后再把这个数组里的字符串拷贝到*(pointer+1)

你的结果并不能说明它没执行，你是怎么判断的没执行？


Question: 【求助】AT89C51的LED点阵倒计时c程序。。。大家看看哪里有错TAT

编译无误，但是有三个警告，说BT3、BT2、BT1在HC595SendData中没有使用。。。问题是效果出不来

怎么看？你是编译报错了，还是放到机子上面跑的效果不出来？


这种错误，楼主可别再犯了。。。。。。。。数组：你需要关注：是否越界，是否没有结尾（这个是针对字符数组）等等。。。。。

C:\Program Files\Microsoft Visual Studio\VC98\CRT\SRC\STRLEN.C /*** *strlen.c - contains strlen() routine * *       Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved. * *Purpose: *       strlen returns the length of a null-terminated string, *       not including the null byte itself. * *******************************************************************************/  #include <cruntime.h> #include <string.h>  #ifdef _MSC_VER #pragma function(strlen) #endif  /* _MSC_VER */  /*** *strlen - return the length of a null-terminated string * *Purpose: *       Finds the length in bytes of the given string, not including *       the final null character. * *Entry: *       const char * str - string whose length is to be computed * *Exit: *       length of the string "str", exclusive of the final null byte * *Exceptions: * *******************************************************************************/  size_t __cdecl strlen (         const char * str         ) {         const char *eos = str;          while( *eos++ ) ;          return( (int)(eos - str - 1) ); }

char c[] = {'a', 'b'};  改成：char c[] = {'a', 'b','\0'}; 或者：char c[] = "ab";

ok，感谢回复！！

没有'\0'字符串结束符号，所以strlen的值是随机的

没有'\0'字符串结束符号，所以strlen的值是随机的

运气好第七个就是‘\0’

格strlen是以遇到'\0'为结束符。你的字符数组没有定义这个'\0'值，所以它会一直找下去，直到找到或者访问了不该访问的内存，造成内存溢出报错。而你的代码刚好是第七个的内存值就是'\0'。仅此而已

引用 楼主 chy7424994 的回复: #include<string.h> #include<stdio.h> int main() { 	char c[] = {'a', 'b'}; 	//int c[] = {1, 2, 3}; 	printf("%d\n", sizeof(c)); 	printf("%d", strlen(c)); }  没有结束符，即‘\0’


Question: 关于溢出的一个问题

引用 7 楼 zxhuser-2 的回复:对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  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对应的汇编并单步执行观察相应内存和寄存器变化。）  哈哈 这句话是不是百试不爽。。。。。。。。

引用 4 楼 Monkey_Dog 的回复:[quote=引用 2 楼 caikunbob 的回复:] 假设x=-1，y=TMin， x-y应该是不会溢出的。 但是当调用tsub_ok函数的时候， 有y=-y=TMin。 而此时x=-1，y=TMin， 调用tadd_ok函数， 由于y=TMin，对于tadd_ok函数来说，只要x为负数， 那么tadd_ok就会溢出， 其实x=-1，y=TMin相减是不溢出的， 所以当x=-1，y=TMin， 调用tsub_ok会产生错误的结果。。。  那其实会不会溢出。。[/quote] 会溢出啊！！ 答案就是会溢出啊！！ 我写的里面就是分析为什么会溢出， 难道我没写明白吗？？

引用 2 楼 caikunbob 的回复:假设x=-1，y=TMin， x-y应该是不会溢出的。 但是当调用tsub_ok函数的时候， 有y=-y=TMin。 而此时x=-1，y=TMin， 调用tadd_ok函数， 由于y=TMin，对于tadd_ok函数来说，只要x为负数， 那么tadd_ok就会溢出， 其实x=-1，y=TMin相减是不溢出的， 所以当x=-1，y=TMin， 调用tsub_ok会产生错误的结果。。。  那其实会不会溢出。。

neg_over是判断负溢出的一个条件 pos_over是判断正溢出的一个条件 return那里是判断是否满足正溢出或负溢出的，都没有溢出就返回1  这是深入理解计算机系统的一道练习题，不是很懂

没明白lz说的，但看返回结果，只要neg_over或pos_over中的某一个是1的话就会返回0


Question: 以8为基数还是以2^8为基数

字符串的单位是字符，每个字符占8bit,也就是2^8次方，没有错。是你理解错了。

引用Or we might sort a set of 64-bit integers as four-digit, radix-2^16 values   64位（8个字节）的整数可以看成4组，每组2个字节（16位）， 基数数自然也就是2^16


Question: 这个程序错误出在哪？？

偶遇到类似问题都是用 “每次用/*...*/注释掉不同部分再重新编译，直到定位到具体语法出错的位置。” 的方法解决的。

char line[] = c;  //你是要闹哪样

运行了楼主的程序，没有楼主那个错误。 有一个错误：error C2440: 'initializing' : cannot convert from 'int' to 'char []'         There are no conversions to array types, although there are conversions to references or pointers to arrays Error executing cl.exe.

。。。。 自己看错误撒：语法错误，类型前面缺少分号  char line[]=c; 不是这么初始化的。看看书吧


Question: C读取文件中含有%的字符串

引用 13 楼 litch008 的回复:问题解决了，是fgets会吧\n读出来，使用fgetc控制串尾\n的读入就OK了 fgets(str,maxlen,f); if ('\n'==str[strlen(str)-1]) str[strlen(str)-1]=0;

这个两个%%下的post请求，请求的网页有问题

OH no，又忘记了，是网页不对，双引号的情况下，虽然能拿到网页

引用 9 楼 litch008 的回复:谢谢你们啊  我的问题居然莫名的解决了    虽然不知道怎么解决的 但还是十分的感谢你们，特别是赵老师 也可能只是浏览器的缓存干扰。

单%下post请求是对的，但是网页找不到

recordCursor=67&strWhere=((............=('A24B3/12' or 'A24B3/16' or 'A24B5%' or 'A24B15%' or 'A24D1%' or 'A24D3%') not ............=('A24B5/12' or 'A24B5/14' or 'A24D1/14')))&searchType=&id=86A9CF921BB54DA0BC9FD6444665F0C9&t=CN&filterChannel=&strSortMethod=-.........  中文全成......

引用 5 楼 litch008 的回复:[quote=引用 2 楼 lovesmiles 的回复:] [quote=引用 楼主 litch008 的回复:] %E4%B8BB%E588%86E7%B1BB%E58F%B73D%2827A24B5%2F12%27+or+%27A24B5%2F14%27+or+%27A24D1%2F14%27%29%29% 是网页post请求的一部分，每当我从文件中读取之后提交了就找不到相应的网页。  如果我把文件里的所有%替换为%%，请求成功了，但是请求的网页却不对  到底是怎么回事呢？  这些是汉字，你还要将它们转成汉字。[/quote] 请求的时候直接使用汉字发送post请求行不行呢？ [/quote] 不行，我猜。http协议不支持。所以需要URLencode和URLdecode

引用 2 楼 lovesmiles 的回复:[quote=引用 楼主 litch008 的回复:] %E4%B8BB%E588%86E7%B1BB%E58F%B73D%2827A24B5%2F12%27+or+%27A24B5%2F14%27+or+%27A24D1%2F14%27%29%29% 是网页post请求的一部分，每当我从文件中读取之后提交了就找不到相应的网页。  如果我把文件里的所有%替换为%%，请求成功了，但是请求的网页却不对  到底是怎么回事呢？  这些是汉字，你还要将它们转成汉字。[/quote] 请求的时候直接使用汉字发送post请求行不行呢？

请求的时候直接使用汉字发送post请求行不行呢？

我用wireshark抓包试了下，在单%号的情况下找不到网页，但是双%%号的情况下请求的网页排序规则没对 &searchType=&id=86A9CF921BB54DA0BC9FD6444665F0C9&t=CN&filterChannel=&strSortMethod=-%E7%94%B3%E8%AF%B7%E6%97%A5

引用 楼主 litch008 的回复:%E4%B8BB%E588%86E7%B1BB%E58F%B73D%2827A24B5%2F12%27+or+%27A24B5%2F14%27+or+%27A24D1%2F14%27%29%29% 是网页post请求的一部分，每当我从文件中读取之后提交了就找不到相应的网页。  如果我把文件里的所有%替换为%%，请求成功了，但是请求的网页却不对  到底是怎么回事呢？  这些是汉字，你还要将它们转成汉字。

建议用wireshark抓包。


Question: java des（DES/CBC/PKCS5Padding） 加密，对应的C openssl 加密

同求与java des（DES/CBC/PKCS5Padding）对应的dll 有高手解释：C/C++一般的des加密代码都是使用0来作为填充数据。下载一个代码把里面数据填充部分按PKCS5Padding方式填充下就OK了。

引用 楼主 chaosfun 的回复:java des（DES/CBC/PKCS5Padding） 加密，对应的C openssl 加密的函数是DES_cbc_encrypt吗？两个加密的结果不一样呢 具体应用没有做过，但DES也有多个版本。有64位的，和128位的。等等吧。


Question: 一个老生常谈的话题："tentative definition"

引用 12 楼 mymtom 的回复:[quote=引用 7 楼 Feymen 的回复:] 我现在的想法是这样的：     标准中说“在一个翻译单元中，如果出现了同名标识符既有外部又有内部链接属性，这样的行为是未定义的”。也就是说#1和#2中的情况属于未定义行为，编译器有权自行选择num的链接属性，向gcc这样要求严格一点的编译器可能对两种情况都报错，要求不严格的编译器像vc可能就会根据自己对标准的解读进行不同的安排。所以，vc编译#2时将int num;强制为内部链接属性。它这样做的理由可能是考虑到了这一点：int num;这条语句位于static int num;语句的可见作用域之内，这样可以和extern int num;的情形保持一致。     这样理解不知道准确不准确，求各位指教。 赞成楼主的理解！ 但是想说说个人的看法： VS的编译器在这个问题的处理上并不恰当，对于这种在单个编译单元内能通过静态检查就发现的linkage的不一致，编译器起码要发出警告，并指出最后的选择的linkage类型，但是VS编译器却自作主张地自己决定linkage类型（是否有警告我就不得而知了，因为我手边没有VS编译器） 个人这是明显的程序错误，更偏向于gcc的处理方式！[/quote] 标准都是未定义行为了，所以报错没有问题。 另外tentative definition是C语言才有的概念，C++不存在tentative definition，只允许定义一次，所以报错很正常。 另外都什么年代了，不要看C89的标准。C99标准进一步确定了，还是同一章节： A declaration of an identifier for an object that has file scope without an initializer, and without a storage-class specifier or with the storage-class specifier static, constitutes a tentative definition. If a translation unit contains one or more tentative definitions for an identifier, and the translation unit contains no external definition for that identifier, then the behavior is exactly as if the translation unit contains a file scope declaration of that identifier, with the composite type as of the end of the translation unit, with an initializer equal to 0. 所以static int i;不是临时性定义，你的问题解决了。

不过，既然标准明文规定这是“未定义行为”了，VS的做法也就没有任何问题了，即使编译器其遇到这种情况直接磁盘执行格式化操作 也是应该没问题的。

引用 7 楼 Feymen 的回复:我现在的想法是这样的：     标准中说“在一个翻译单元中，如果出现了同名标识符既有外部又有内部链接属性，这样的行为是未定义的”。也就是说#1和#2中的情况属于未定义行为，编译器有权自行选择num的链接属性，向gcc这样要求严格一点的编译器可能对两种情况都报错，要求不严格的编译器像vc可能就会根据自己对标准的解读进行不同的安排。所以，vc编译#2时将int num;强制为内部链接属性。它这样做的理由可能是考虑到了这一点：int num;这条语句位于static int num;语句的可见作用域之内，这样可以和extern int num;的情形保持一致。     这样理解不知道准确不准确，求各位指教。 赞成楼主的理解！ 但是想说说个人的看法： VS的编译器在这个问题的处理上并不恰当，对于这种在单个编译单元内能通过静态检查就发现的linkage的不一致，编译器起码要发出警告，并指出最后的选择的linkage类型，但是VS编译器却自作主张地自己决定linkage类型（是否有警告我就不得而知了，因为我手边没有VS编译器） 个人这是明显的程序错误，更偏向于gcc的处理方式！

基本上在一个文件不会这样重复声明或定义，用多文件测试比较能看出在说啥...

两个都编译不过嘛！ VS的编译器BUG很多，这时业界公认的！

vc 2013, /TC（C 语言）通过， /TP（c++ 语言） 报错。

引用 4 楼 Bokutake 的回复:我怀疑这个代码在C和C++编译器编译的结果可能不同。 C++里初始化类的静态变量会有类似2的写法。 恩，C++直接报重定义错误。但是C报出的错误不是这样的。

搜索 C语言的 试探性定义 问题

定义的这两句似乎没有意义。。。 在程序结束之后定义。。 好吧，也可以说是在其他函数开始之前。。。

和编译器有关吧，在GCC4.8.2下，这两个都报错

static static declarator  When modifying a variable, the static keyword specifies that the variable has static duration (it is allocated when the program begins and deallocated when the program ends) and initializes it to 0 unless another value is specified. When modifying a variable or function at file scope, the static keyword specifies that the variable or function has internal linkage (its name is not visible from outside the file in which it is declared).   In C++, when modifying a data member in a class declaration, the static keyword specifies that one copy of the member is shared by all the instances of the class. When modifying a member function in a class declaration, the static keyword specifies that the function accesses only static members.  For related information, see auto, extern, and register.  Example  // Example of the static keyword static int i;         // Variable accessible only from this file  static void func();   // Function accessible only from this file  int max_so_far( int curr ) {    static int biggest;    // Variable whose value is retained                           //    between each function call    if( curr > biggest )       biggest = curr;     return biggest; }  // C++ only  class SavingsAccount { public:    static void setInterest( float newValue )  // Member function       { currentRate = newValue; }             //    that accesses                                               //    only static                                               //    members private:    char name[30];    float total;    static float currentRate;    // One copy of this member is                                 //    shared among all instances                                 //    of SavingsAccount };  // Static data members must be initialized at file scope, even //    if private. float SavingsAccount::currentRate = 0.00154;


Question: 关于C语言指针的一些疑问。

引用 楼主 a491057947 的回复:疑问1：定义一个字符数组 char var[]={'a','b','c'}，这里的数组名为该数组的首地址。当执行printf("%s",var)时可输出全部字符a,b,c，为什么打印首地址可以输出所有字符？  疑问2：定义一个字符指针数组 char *var2[]={"aaa","bbb","ccc"}，表示一个一维数组内存放着三个指针变量，他们指向的内容分别为“aaa”,"bbb","ccc"（这个是C program language 中讲的），所以*var2[0]应该为指针var2[0]所指向的内容，为“aaa”，但测试结果却是"a"(在字符数组中，*var与var[0]的输出一样都为”a“)为什么？疑问1： char var[]={'a','b','c','\0'};用%s输出时需要在字符串结尾加一个'\0'结束标志，你那样写会在abc之后有乱码 疑问2： 表示一个一维指针数组内存放着三个指针变量 *var2[0]应该为指针var2[0]所指向的第一个元素 *var==var[0]这两个是等价的

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

LZ已经理解了指针就是内存地址。内存里面的数据都是一个字节一个字节存放的，程序用特定的方式去访问内存中的这些字节。 所以你的两个问题都是语法规定的访问方式而已。你可以自己看一下教材中关于字符串和字符的部分。 LZ能够问出这两个问题，说明距离掌握指针已经不远了。

引用 15 楼 a491057947 的回复:[quote=引用 8 楼 dalianzsl 的回复:] 1.关于疑问1，想详细了解，可以查看printf的实现代码，其实没必要。printf输出字符串时需要一个地址，可是字符串的长度却是未知的，那么它只能从，所提供的地址开始，连续输出字符，直到遇到'\0'输出结束。因此，你的第一个例子，就如一楼所说的，是有问题的。 char var[]={'a','b','c', '\0'}; printf("%s", var); 写成这样才能正常输出。 2.关于疑问2，数组var2中存储的是字符串指针，也就是char *类型，输出这个数组的第一个元素，直接写 printf("%s", var2[0]); 就可以。*var2[0]这种写法，var2[0]表示数组的第一个元素，也就是指向"aaa"的字符串指针，或者说是"aaa"的首地址。*在这里表示取地址处的值，那么*var2[0]表示取"aaa"首地址处的值，也就是字符'a'。   但在我的机器上可以运行啊 Ubuntu 11[/quote] 你的第一个例子运行时可能报错，也可能不报错，与运行时环境有关。因为定义数组时，最后没有加'\0‘，那么程序会从var这个地址开始，连续输出字符，直到在内存中遇到'\0'结束，因此输出的结果可能是abc、abc一堆其他字符或者访问了不允许访问的内存引起错误。

引用 16 楼 a491057947 的回复:[quote=引用 2 楼 dbzhang800 的回复:] *var2[0] ，类型是char，所以只能是一个字符  var[0]  <==> *(var+0)  <==> *(0+var)  <==> 0[var] <==> *var  0[var]----这个表示没看明白。。[/quote] 第一个问题不建议你用编译器去试(因为测试的结果有无数种答案，而且没什么用)，但这个东西你是真的可以去试了(如果你有兴趣)，试过就有感觉了。

引用 2 楼 dbzhang800 的回复:*var2[0] ，类型是char，所以只能是一个字符  var[0]  <==> *(var+0)  <==> *(0+var)  <==> 0[var] <==> *var  0[var]----这个表示没看明白。。

引用 8 楼 dalianzsl 的回复:1.关于疑问1，想详细了解，可以查看printf的实现代码，其实没必要。printf输出字符串时需要一个地址，可是字符串的长度却是未知的，那么它只能从，所提供的地址开始，连续输出字符，直到遇到'\0'输出结束。因此，你的第一个例子，就如一楼所说的，是有问题的。 char var[]={'a','b','c', '\0'}; printf("%s", var); 写成这样才能正常输出。 2.关于疑问2，数组var2中存储的是字符串指针，也就是char *类型，输出这个数组的第一个元素，直接写 printf("%s", var2[0]); 就可以。*var2[0]这种写法，var2[0]表示数组的第一个元素，也就是指向"aaa"的字符串指针，或者说是"aaa"的首地址。*在这里表示取地址处的值，那么*var2[0]表示取"aaa"首地址处的值，也就是字符'a'。   但在我的机器上可以运行啊 Ubuntu 11

引用 12 楼 a491057947 的回复:[quote=引用 1 楼 dbzhang800 的回复:] 首先，你的疑问一 中举得例子是错的。  你运行过吗？我的环境Ubuntu 11 OK[/quote] 呵呵，现在你还没看出来错误吗？   另外，运行是不能解决问题的，因为这样错误的代码，在某些时候某次运行时，真的可能得到正确的结果，更何况，即使结果明显是错的，可能你都会忽略。

引用 10 楼 u013162593 的回复:1、var指的是这个数组的地址，它的值正好等于数组中第一个元素var[0]的地址。它们地址的值相等，但代表的意思不同。 var代表的是整个数组的地址，&var{0}则是首个元素的地址。 你把var加1之后，发现它跳的长度是一个数组的长度，而把&var[0加1跳转的长度是一个元素的长度 2、var2[0]是什么？它是指针，它本身并不是“aaa”,，而是一个指向“aaa”的指针，也就是，它是指向存放“aaa”这片内存的指针，它只是地址而已。  var仍代表首地址，可见C program language  Page 81

引用 1 楼 dbzhang800 的回复:首先，你的疑问一 中举得例子是错的。  你运行过吗？我的环境Ubuntu 11 OK

引用 4 楼 user-10 的回复:[quote=引用 楼主 a491057947 的回复:]  疑问1：定义一个字符数组 char var[]={'a','b','c'}，这里的数组名为该数组的首地址。当执行printf("%s",var)时可输出全部字符a,b,c，为什么打印首地址可以输出所有字符？  疑问2：定义一个字符指针数组 char *var2[]={"aaa","bbb","ccc"}，表示一个一维数组内存放着三个指针变量，他们指向的内容分别为“aaa”,"bbb","ccc"（这个是C program language 中讲的），所以*var2[0]应该为指针var2[0]所指向的内容，为“aaa”，但测试结果却是"a"(在字符数组中，*var与var[0]的输出一样都为”a“)为什么？ 1.  当printf以%s格式输出字符串时，要求对应参数为字符串的首地址，这是函数接口问题，函数就是这样设计的，使用者必须按这个要求提供参数才能得到正确的结果 2. char *var2[]={"aaa","bbb","ccc"}      var2[0]为char *类型，指向字符串"aaa"      *var2[0]为char类型，指向字符串"aaa"的第一个字符'a'      两者地址值相同，但类型不同，使用时是根据类型来使用的，这一点是关键      [/quote]  恩，你说的有道理，我懂了。

引用 楼主 a491057947 的回复:疑问1：定义一个字符数组 char var[]={'a','b','c'}，这里的数组名为该数组的首地址。当执行printf("%s",var)时可输出全部字符a,b,c，为什么打印首地址可以输出所有字符？  疑问2：定义一个字符指针数组 char *var2[]={"aaa","bbb","ccc"}，表示一个一维数组内存放着三个指针变量，他们指向的内容分别为“aaa”,"bbb","ccc"（这个是C program language 中讲的），所以*var2[0]应该为指针var2[0]所指向的内容，为“aaa”，但测试结果却是"a"(在字符数组中，*var与var[0]的输出一样都为”a“)为什么？  printf中%s期望char *，而char *和char []基本等价；当然一中的例子有越界的隐患。  var2[0]是个char *，然后再解引用，只能得到一个char。

第一个，数组是连续存放的，你只要找到第一个的地址，就可以了 第二个，你的类型是char型，当然是一个字符了

引用 7 楼 zhao4zhong1 的回复:[quote=引用 6 楼 syrchina 的回复:] [quote=引用 3 楼 zhao4zhong1 的回复:] 十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495  老赵，还要10个积分，有意思吗？！[/quote]  闲着也是闲着。[/quote]  我的积分。。。

引用 6 楼 syrchina 的回复:[quote=引用 3 楼 zhao4zhong1 的回复:] 十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495  老赵，还要10个积分，有意思吗？！[/quote]  闲着也是闲着。

引用 3 楼 zhao4zhong1 的回复:十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495  老赵，还要10个积分，有意思吗？！

这是一个指针、地址、内容的问题，其实很简单只是你现在搞混了，看下这个资料： http://www.doc88.com/p-907976424060.html

引用 楼主 a491057947 的回复:疑问1：定义一个字符数组 char var[]={'a','b','c'}，这里的数组名为该数组的首地址。当执行printf("%s",var)时可输出全部字符a,b,c，为什么打印首地址可以输出所有字符？  疑问2：定义一个字符指针数组 char *var2[]={"aaa","bbb","ccc"}，表示一个一维数组内存放着三个指针变量，他们指向的内容分别为“aaa”,"bbb","ccc"（这个是C program language 中讲的），所以*var2[0]应该为指针var2[0]所指向的内容，为“aaa”，但测试结果却是"a"(在字符数组中，*var与var[0]的输出一样都为”a“)为什么？ 1.  当printf以%s格式输出字符串时，要求对应参数为字符串的首地址，这是函数接口问题，函数就是这样设计的，使用者必须按这个要求提供参数才能得到正确的结果 2. char *var2[]={"aaa","bbb","ccc"}      var2[0]为char *类型，指向字符串"aaa"      *var2[0]为char类型，指向字符串"aaa"的第一个字符'a'      两者地址值相同，但类型不同，使用时是根据类型来使用的，这一点是关键


Question: 有段代码，调试后的结果怎么都理解不了！求解惑

p溢出鸟..

仅供参考#include <stdio.h> int d[8][8]; int n; void queen8(int L) {     int x,y;      if (8==L) {         n++;         printf("%d\n",n);         for (y=0;y<8;y++) {             for (x=0;x<8;x++) { //              printf("%d",d[y][x]);                 if (d[y][x]) printf("■");                 else         printf("□");             }             printf("\n");         }         return;     }     for (x=0;x<8;x++) {         for (y=0;y<L;y++) {             if  (              d[y][x      ]              || (x-(L-y)>=0 && d[y][x-(L-y)])              || (x+(L-y)< 8 && d[y][x+(L-y)]))                 break;         }         if (y>=L) {             d[L][x]=1;             queen8(L+1);             d[L][x]=0;         }     } } int main() {     int y,x;     for (y=0;y<8;y++) {         for (x=0;x<8;x++) {             d[y][x]=0;         }     }     queen8(0);     return 0; }

“给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出

给你发私信了，请查收！  引用 2 楼 zhao4zhong1 的回复:


Question: C语言open/fopen函数移植问题

引用 2 楼 zhao4zhong1 的回复:参考： C:\Program Files\Borland\CBuilder6\Source\Rtl\Source\io\_open.c C:\Microsoft SDK\src\crt\_open.c C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\src\crt\_open.c C:\Program Files\Microsoft Visual Studio\VC98\CRT\SRC\_OPEN.C C:\Program Files\Microsoft Visual Studio 8\VC\crt\src\_open.c C:\Program Files\Microsoft Visual Studio 9.0\VC\crt\src\_open.c C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\_open.c 或Linux的open.c 多谢了，是在linux下面的嵌入式编程，直接移植过来也不行，最后通过系统内置的usbread命令去实现的

引用 7 楼 yangyunzhao 的回复:[quote=引用 6 楼 u013697891 的回复:] linux下的编译软件没有fopen函数？  应该是嵌入式编程，系统不见得是linux。 没有弄过，帮顶[/quote] 是的，是在linux下面的嵌入式编程，直接移植过来也不行，最后通过系统内置的usbread命令去实现的

引用 6 楼 u013697891 的回复:linux下的编译软件没有fopen函数？  应该是嵌入式编程，系统不见得是linux。 没有弄过，帮顶

C语言的open或者fopen函数是需要系统API接口支持的

linux下的编译软件没有fopen函数？

引用 4 楼 xxxxing 的回复:引用fopen 是C标准库中的函数，open 是 posix标准中的函数，你怎么会找不到呢？  我用系统没有 fopen和open的接口


Question: 自己写了一个程序  要求是输出字符串 不知道哪里出现问题了 帮忙看下！

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

下面是 <stdarg.h> 里面重要的几个宏定义如下： typedef char* va_list; void va_start ( va_list ap, prev_param ); /* ANSI version */ type va_arg ( va_list ap, type );  void va_end ( va_list ap );  va_list 是一个字符指针，可以理解为指向当前参数的一个指针，取参必须通过这个指针进行。 <Step 1> 在调用参数表之前，定义一个 va_list 类型的变量，(假设va_list 类型变量被定义为ap)； <Step 2> 然后应该对ap 进行初始化，让它指向可变参数表里面的第一个参数，这是通过 va_start 来实现的，第一个参数是 ap 本身，第二个参数是在变参表前面紧挨着的一个变量,即“...”之前的那个参数； <Step 3> 然后是获取参数，调用va_arg，它的第一个参数是ap，第二个参数是要获取的参数的指定类型，然后返回这个指定类型的值，并且把 ap 的位置指向变参表的下一个变量位置； <Step 4> 获取所有的参数之后，我们有必要将这个 ap 指针关掉，以免发生危险，方法是调用 va_end，他是输入的参数 ap 置为 NULL，应该养成获取完参数表之后关闭指针的习惯。说白了，就是让我们的程序具有健壮性。通常va_start和va_end是成对出现。

字符串这样搞来搞去效果不明显，如果是练习可变参数函数的使用，可以用整型来测试

引用 6 楼 Intel0011 的回复:仅供参考 #include <stdio.h> #include <stdlib.h> #include <stdarg.h>  void shuchu(char *format, ...) {        va_list cp;      va_start(cp, format);      vprintf(format, cp);      va_end(cp); }   int main(void) {   shuchu("string %s %s %d\n", "adads", "adsada", 123);  shuchu("string");   getchar();    return 0; }谢谢！！！！！

引用 4 楼 sinat_17012035 的回复:[quote=引用 1 楼 modyaj 的回复:]  卡死 首先看循环   先看看你这个循环怎么跳出来吧    for(;*data!='\0';i++)     {         temp=va_arg(cp,char *);         printf("%s",temp);          }恩我在后面加了一句 data++ for(;*data!='\0';i++)     {         temp=va_arg(cp,char *);                data++;         printf("%s",temp);     }  不卡死了 当结果还是没有出来[/quote] 我对va_XXX也没实用过，但是你去查一下，va_start说的是返回第一个可变参数！那很明显，你的第一个可变参数没有，所以循环内根本就取不到东西，再加上用data!=0来判断就更错了！问题很多，像赵老师说的，打几个断点，一步一步的调试，你会明白很多！

给你参考一下 #include <stdio.h> #include <stdarg.h>  void shuchu(char *data,...) { 	va_list ap; 	char *tmp;  	va_start(ap,data); 	printf("%s\n",data);//此处输出"string" 	while(1) 	{ 		tmp = va_arg(ap,char *); 		if(tmp == (char *)0) 		{ 			break; 		} 		printf("%s\n",tmp); //此处输出可变参数 	} 	va_end(ap); } int main() { 	shuchu("string","string2","string3",(char *)0); 	return 0; }

引用 1 楼 modyaj 的回复:卡死 首先看循环   先看看你这个循环怎么跳出来吧    for(;*data!='\0';i++)     {         temp=va_arg(cp,char *);         printf("%s",temp);          }恩我在后面加了一句 data++ for(;*data!='\0';i++)     {         temp=va_arg(cp,char *);                data++;         printf("%s",temp);     }  不卡死了 当结果还是没有出来

还是学生，才接触一些c语言，所以希望有空  帮忙看下

引用 8 楼 WXJ0415 的回复:这是C语言吗？输出怎么用shuchu   应该是printf  呀 void 是函数的写法 你说的printf 只是在mian函数中的输出输出的语句多了，想puts 什么的

shuchu~~~    建议楼主多用英文名，printf什么的命名  顾名思义，这个练好。以后有好处

这是C语言吗？输出怎么用shuchu   应该是printf  呀


Question: 用WIN32 API编写串口程序

可以先直接用同步读写的方式操作串口，可以设置接收超时的，你的代码乱了点

先用虚拟串口试试，感觉成功了再在硬件上测试


Question: 进来接分

哇 搭设在此！！围观学习中

我是来节分的

看了一下手册，你的参数值的确是取错了.函数原型int creat(const char *pathname, mode_t mode);mode的取值是               S_IRWXU， 00700 user (file owner) has  read,  write  and  execute permission                S_IRUSR  00400 user has read permission                S_IWUSR  00200 user has write permission                S_IXUSR  00100 user has execute permission                S_IRWXG  00070 group has read, write and execute permission                S_IRGRP  00040 group has read permission                S_IWGRP  00020 group has write permission                S_IXGRP  00010 group has execute permission                S_IRWXO  00007 others have read, write and execute permission                S_IROTH  00004 others have read permission                S_IWOTH  00002 others have write permission                S_IXOTH  00001 others have execute permission

这个也没用。。。。。。

用了root也是一样  umask(002)  ?

引用 13 楼 q3733353520 的回复:[quote=引用 12 楼 fang098 的回复:] 在你的程序的原有基础上加上<io.h>和<errno.h>头文件，用上面那两个标志位试下。行不行试下就知道了。 没有io.h[/quote] 不行就用root用户登陆进去编译你的程序试下看看，刚试了下你程序没问题。

creat函数的第二个参数mode，实际上创建的文件的权限不是mode，而是umask函数的参数mode&(~cmode)的结果，所以在调用该函数时，最好先调用umask函数

引用 14 楼 cyd54454 的回复:if( fd = creat("file.hole", O_WRONLY) == -1),话说这不是少了个括号么-。-，这fd要不是0要不就是1呀  确实是大意了，不过我时觉得file.hole的权限还是想不通

引用 12 楼 fang098 的回复:在你的程序的原有基础上加上<io.h>和<errno.h>头文件，用上面那两个标志位试下。行不行试下就知道了。 没有io.h

引用 9 楼 fang098 的回复:[quote=引用 楼主 q3733353520 的回复:]  #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> //#include <unistd.h>  char buf1[] = "abcdefghij"; char buf2[] = "ABCDEFGHIJ";  int main() { 	int fd;  	//if( fd = creat("file.hole", O_RDWR) == -1) 	if( fd = creat("file.hole", O_WRONLY) == -1) 		perror("creat fall\n"); #if 1	 	if(write(fd, buf1, 10) != 10) 		perror("buf1 write fall\n"); 	 	if(lseek(fd, 40, SEEK_SET) == -1) 		perror("\nlseek falli"); 	/*  offset now = 40 */  	if(write(fd, buf2, 10) != 10) 		perror("\nbuf2 write fall\n"); 	/*  offset now = 50 */ #endif 	putchar(10);  	return 0; }  很奇怪的现象，以RDWR打开文件权限为----------                              以WRONLY打开文件权限为---------x 你读写的标志是不是给错了，_S_IREAD | _S_IWRITE，用这两个试下。 你是以什么用户登陆进来的。[/quote]   请man  creat   那里来的这两个标志。。。

代码贴在那里，你觉得标志错了吗？  我是以普通用户 但是又有什么关系呢   owner 都是这个用户

引用 楼主 q3733353520 的回复: #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> //#include <unistd.h>  char buf1[] = "abcdefghij"; char buf2[] = "ABCDEFGHIJ";  int main() { 	int fd;  	//if( fd = creat("file.hole", O_RDWR) == -1) 	if( fd = creat("file.hole", O_WRONLY) == -1) 		perror("creat fall\n"); #if 1	 	if(write(fd, buf1, 10) != 10) 		perror("buf1 write fall\n"); 	 	if(lseek(fd, 40, SEEK_SET) == -1) 		perror("\nlseek falli"); 	/*  offset now = 40 */  	if(write(fd, buf2, 10) != 10) 		perror("\nbuf2 write fall\n"); 	/*  offset now = 50 */ #endif 	putchar(10);  	return 0; }  很奇怪的现象，以RDWR打开文件权限为----------                              以WRONLY打开文件权限为---------x 你读写的标志是不是给错了，_S_IREAD | _S_IWRITE，用这两个试下。 你是以什么用户登陆进来的。

权限都没有  还谈什么方式open

我是想问creat函数为什么会造成这种现象

引用 4 楼 q3733353520 的回复:[quote=引用 3 楼 user-5 的回复:] 楼主想说什么  creat  创建的文件权限为什么是那样的[/quote]    你这是对文件进行操作么？ 首先要看文件是否存在   再决定以什么方式打开（open函数）  再进行文件的都写操作 至于你说的这中现象  没见过


Question: Win7下VC++6.0同时打开多个工程的设置？

楼主，你现在能同时打开工程了吗？

我按照上面的 设置了Win7 下 的VC6.0无法打开多个工作区间啊

引用 7 楼 my_xxh 的回复: 赵老师，怎么还是不行呀？ win7 系统vc6.0同时打开两个.dsw文件，办不到吗？苦恼几天了 引用 4 楼 zhao4zhong1 的回复:"%1"前面少一空格 然后你随便 a.dsw b.dsw c.dsw

同时打开10个8个dsw也没问题啊, 不知道LZ在找啥..

我看得有点迷茫啊。标题不是说同时打开多个工程吗？为啥到了具体问题，就变成了“同时打开多个工作空间（.dsw）“？  同时打开多个.dsp，VC6本身就支持的啊。

我的方法是从网上找的http://blog.sina.com.cn/s/blog_668af1ff010108cv.html 目的是：在VC6.0同时打开多个工程( 即同时打开多个.dsw文件)， 能说说缺省设置具体怎么弄吗？苦恼好久了，谢谢！ 引用 5 楼 mLee79 的回复:难道不是缺省设置就可以的么, 我咋一直都可以开10个8个毫无压力的..

难道不是缺省设置就可以的么, 我咋一直都可以开10个8个毫无压力的..

"%1"前面少一空格

引用 1 楼 zhao4zhong1 的回复:ftype VisualStudio.dsp.10.0="F:\VC6CN\MSDev98\Bin\MSDEV.EXE" "%1" 这办法还是不行呀（如上图）！哪里有问题呀？ 谢谢

以前在xp上发现一个“歪门邪道”可以同时打开多个工程。那就是点击那个NEHE的openGL的教程里边的demo工程，然后就可以同时打开多个工程了，只是不明白原因何在


Question: 这是道题的输出是？接分的进！

参考gcc源代码相关片断。

引用 4 楼 zhao4zhong1 的回复:http://bbs.csdn.net/topics/390676437 看了您的帖子，但我这个地方有一个不解，求教 最终输出是一个随机负的浮点数，错误原因是没有加<stdlib.h>，因为之前没有加-Wall 所以没有任何提示，我的问题是我没有加stdlib应该会编译不同过才对吧？为什么编译通过而且可以运行，就是结果不对呢？ [gxp@localhost tmp]$ gcc -c -Wall test_val.c  test_val.c: 在函数 ‘main’ 中： test_val.c:7: 警告：隐式声明函数 ‘atof’ [gxp@localhost tmp]$ gcc -o test_val test_val.o  [gxp@localhost tmp]$ ./test_val  double=-1030792151.000000

引用 5 楼 angel_su 的回复:warning: implicit declaration of function 'atof' [-Wimplicit-function-declaration] 隐式声明的话，默认函数返回整形，从exa取值肯定不对，加入stdlib.h吧... 是要加入stdlib.h，但奇怪的是我不加，居然编译通过然后，输出的也不是整数，是一个负的浮点数，为什么会这样呢？如果没有头文件应该报错才对？但不知道为什么可以运行返回？

#include <stdlib.h>

...   未定义

严格说来，%lf 对C89来说是为定义的，你应该用 %f  或是你试试C99模式


Question: if语句中的语句失效

谢谢各位的帮助和教导！

引用 2 楼 user-5 的回复:// 初始化，如果不初始化的话，数组里面含有随机值， // 按照你的第一方式，如果随机值不是0－9,a-f,A-F,变量i根本不会自增，所以无限循环 // 你的第二方式即使判断不成立也会自增果然是这样……我输出了一下未初始化的数组，都是乱码……在for循环后补充一个 '\0' 就可以正常运行了。

呃……我在最后一个else if后面补了  	else break;  后，就能输出正确结果了……我输入的是  0x11，为什么会3种条件都不满足？

写if不写对应else的程序员都是在踩钢丝！

引用 楼主 u012184298 的回复:#include<stdio.h>  #define HEX 16  int htoi(char s[]); main() { 	int i,a; 	char c,s[20]; 	for(i = 0;i < 20 && (c = getchar())!= '\n'; ++i) 		s[i] = c; 	if(s[0] == '0' && (s[1] == 'x' || s[1] == 'X')){ 		a = htoi(s); 		printf("The number is %d.\n",a); 	} 	else printf("Error!"); 	return 0; }  int htoi(char s[]) { 	int i = 2; 	int n = 0; 	 	while(s[i] != '\0' && s[i] != '\n'){ 		if(s[i] >= '0' && s[i] <= '9'){ 				n = n * HEX + (s[i] - '0'); 				++i;} 		else if(s[i] >= 'a' && s[i] <= 'f'){ 				n = n * HEX + (s[i] - 'a' + 10); 				++i;} 		else if(s[i] >= 'A' && s[i] <= 'F'){ 				n = n * HEX + (s[i] - 'A' + 10); 				++i;}			   		} 	return n; }    htoi 函数中，++i全部无效，但是改为这样：  int htoi(char s[]) { 	int i = 2; 	int n = 0; 	 	while(s[i] != '\0' && s[i] != '\n'){ 		if(s[i] >= '0' && s[i] <= '9') 				n = n * HEX + (s[i] - '0'); 		else if(s[i] >= 'a' && s[i] <= 'f') 				n = n * HEX + (s[i] - 'a' + 10); 		else if(s[i] >= 'A' && s[i] <= 'F') 				n = n * HEX + (s[i] - 'A' + 10); 		++i;		   		} 	return n; }  就可以正常运行。 求各位大神，这是为什么？前一种为何输入后无任何结果输出？程序处在卡死状态。  这几种状态之外，还有别的状态。

没有什么奇怪的，前边的++i都在你的三种条件里，很明显不执行的话意味着三种条件都不满足。修改后的结构，++i就和if语句没有关系了，他只是循环中的一句，每次循环都会执行

你的 else 呢？？ 编程要严谨。

#include<stdio.h>  #define HEX 16  int htoi(char s[]); main() { 	int i,a; 	int c;    // getchar()返回int        char s[20] = { '\0' };  // 初始化，如果不初始化的话，数组里面含有随机值，按照你的第一方式，如果随机值不是0－9,a-f,A-F,变量i根本不会自增，所以无限是＝循环；你的第二方式即使判断不成立也会自增 	for(i = 0;i < 20 && (c = getchar())!= '\n'; ++i) 		s[i] = c;  	if(s[0] == '0' && (s[1] == 'x' || s[1] == 'X')){ 		a = htoi(s); 		printf("The number is %d.\n",a); 	} 	else printf("Error!"); 	return 0; }  int htoi(char s[]) { 	int i = 2; 	int n = 0; 	 	while(s[i] != '\0' && s[i] != '\n'){ 		if(s[i] >= '0' && s[i] <= '9'){ 				n = n * HEX + (s[i] - '0'); 				++i;} 		else if(s[i] >= 'a' && s[i] <= 'f'){ 				n = n * HEX + (s[i] - 'a' + 10); 				++i;} 		else if(s[i] >= 'A' && s[i] <= 'F'){ 				n = n * HEX + (s[i] - 'A' + 10); 				++i;}			   		} 	return n; }


Question: 求输入字符串长度，结果出不来，求指导。

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

ctrl+z： 如果在输入的时候ctrl+z前面有字符，返回编码值26 如果在输入的时候ctrl+z前面没字符，返回编码值-1

按Ctrl+Z 一次不行按两次

while ( getchar () != ‘\n’)

我知道可以改成while ( getchar () != '\n') ，但是这样怎么就可输出 int main () { 	int n; 	 	n = 0; 	while ( getchar () != EOF ) 	{ 		printf("%d\n", n); 		++n; 	} 	 	//printf("%d\n", n);  	return 0; }

唉，getchar()用EOF判断。。。

while ( getchar () != '\n')     换行结束输入就可以了

条件结束没写对，所以循环结束不了吧。


Question: 有关ifstream的内存占用问题

引用 1 楼 user-1 的回复:有个 cvReleaseImage() 好像是这么个函数，释放图像       stringstream ss;  // 类型转换统一转换为char* 类型     ss << "E:/temp/";     ss << nframes;     ss << ".jpg" ;     ss >> nframesstr;   string s; s+= "E:/temp/"+ nframes+".jpg"; nframesstr = s.c_str(); 不知道你是不是这个意思 嗯嗯。原来是忘了Release。opencv东西还不是很熟悉


Question: 对windows 窗口程序框架的面向对象封装

引用 14 楼 wenbo228228 的回复:[quote=引用 13 楼 bojie5744 的回复:] 很多东西，可能自己那处地方不小心了，造成的，认真看看吧。不过你为什么不去MFC区提问呢？我也无意看见这里竟然有个MFC的，然后进来了。 还有mfc区啊，多谢提醒  错误找到了，忘了wndclassex.hIconSm，不过编译器没发现这个问题，很奇怪呢，难道vs2013不给力？[/quote] 他不会管这个问题，所以一开始提醒你参考我发出来的参数，一行一行对照，是哪里缺少了，只要错误了，缺少都会导致注册失败，这里都是细节问题

引用 13 楼 bojie5744 的回复:很多东西，可能自己那处地方不小心了，造成的，认真看看吧。不过你为什么不去MFC区提问呢？我也无意看见这里竟然有个MFC的，然后进来了。 还有mfc区啊，多谢提醒  错误找到了，忘了wndclassex.hIconSm，不过编译器没发现这个问题，很奇怪呢，难道vs2013不给力？

那你直接不要自己写了，直接调用封装好的这个AfxRegisterClass函数，单步调试进入这个函数，你去看看他是怎么写的 WNDCLASS ws; AfxRegisterClass(&ws);

我把窗口类的额外属性全部去掉，结果运行正常；加上额外属性就注册失败了

引用 8 楼 bojie5744 的回复:BOOL MyWindow::PreCreateWindow(CREATESTRUCT& cs) { 	HINSTANCE hInst = AfxGetInstanceHandle(); 	ASSERT(hInst);  	WNDCLASSEX wcex; 	wcex.cbSize = sizeof(WNDCLASSEX); 	BOOL bRet = GetClassInfoEx(hInst,cs.lpszClass,&wcex);  	if(bRet) 	{ 		return TRUE; 	} 	wcex.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS; 	wcex.lpfnWndProc = AfxWndProc; 	wcex.cbClsExtra = 0; 	wcex.cbWndExtra = 0; 	wcex.hInstance = hInst; 	wcex.hIcon = wcex.hIconSm = LoadIcon(hInst,MAKEINTRESOURCE(IDR_MAINFRAME)); 	wcex.hCursor = LoadCursor(hInst,IDC_ARROW); 	wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 	wcex.lpszMenuName = NULL; 	wcex.lpszClassName = cs.lpszClass; 	bRet = RegisterClassEx(&wcex); 	if(bRet == 0) 	{ 		MessageBox("注册失败"); 	} 	return bRet; } bRet = RegisterClassEx(&wcex);用vs2013编译会提示性能警告，我最开始也是这么写的， 后来改成这样就可以了： if (!RegisterClass(&wnd))  ，性能警告提示我把返回值转换成布尔类型，这样在某些场合会出现错误的吧

终于调试出来了，窗口类有的地方有额外属性，有的地方又忘了额外属性，结果编译器没看出来

对于你这个问题 “运行时注册窗口失败”  看看是否把WNDCLASSEX 这个结构的每个成员正确填了。

引用 5 楼 wenbo228228 的回复:本人调试多次未果，你一定能从中收获很多，如果你调试出来了的话 呵呵。。

本人调试多次未果，你一定能从中收获很多，如果你调试出来了的话

就没有人有兴趣研究下吗

你直接把注册部分提取出来。。或者看看跟MSDN上的例子有什么不同了

没有人吗、、、、

我没看过mfc，这个项目是根据mfc的思路封装的，细节有很多不一样，你有兴趣具体看看吗


Question: 杭电acm 1009这道题一直WA，数据以及特殊数据测试了一些也没问题，感觉也不是精度缺失的问题，希望各位大侠能帮忙指点下，感谢！

谢谢 hnwyllmm 羽飞哈。 我后来发现原来一直是代码里面写欠了 这是改后的代码，AC了 #include<stdio.h> int main(){     double m,n;     while(scanf("%lf %lf",&m,&n)!=EOF&&(m!=-1)&&(n!=-1)){           int i,j,t;           double sum=0,a[1000]={0},b[1000]={0};           for(i=0;i<n;i++){               scanf("%lf %lf",&a[i],&b[i]);                        }           for(i=0;i<n-1;i++){               for(j=i;j<n-1;j++){                   if((a[i]/b[i])<(a[j+1]/b[j+1])){                       t=a[i],a[i]=a[j+1],a[j+1]=t;                      t=b[i],b[i]=b[j+1],b[j+1]=t;                   }               }           }           for(i=0;i<n;i++){                   if((m!=0)&&(m<b[i])){                      sum=sum+m*a[i]/b[i];                      break;                   }                                      if(m>b[i]){                      m=m-b[i];                      sum=sum+a[i];                   }                   if(m==b[i+1]){                       sum=sum+a[i+1];                      if(b[i+1]!=0)                      break;                   }           }           printf("%.3lf\n",sum);     } }

另外关于 0 1 123 0 0.000这样特殊例子没有影响的，照样AC，嗯，就这样了

然后还发现，其实代码可以在简点的 之前以为要考虑一些啥啥啥的特殊情况，然后就写了一些不必要的情况，导致了错误率提高唉 简单点的代码： #include<stdio.h> int main(){     int m,t,n;     while(scanf("%d %d",&m,&n)!=EOF&&(m!=-1)&&(n!=-1)){           int i,j;           double sum=0,a[1000]={0},b[1000]={0};           for(i=0;i<n;i++){               scanf("%lf %lf",&a[i],&b[i]);                        }           for(i=0;i<n-1;i++){               for(j=i;j<n-1;j++){                   if((a[i]/b[i])<(a[j+1]/b[j+1])){                       t=a[i],a[i]=a[j+1],a[j+1]=t;                      t=b[i],b[i]=b[j+1],b[j+1]=t;                   }               }           }           for(i=0;i<n;i++){                   if(m<b[i]){                      sum=sum+m*a[i]/b[i];                      break;                   }                                      if(m>=b[i]){                      m=m-b[i];                      sum=sum+a[i];                   } //                  if(m==b[i+1]){                //之前这一段写欠了"+1",致使WA  //                     sum=sum+a[i+1];            //而这一段其实可以去掉  //                     if(b[i+1]!=0)              //个人觉得要熟悉不同类型值之间的赋值  //                     break;                     // //                  }                             //           }           printf("%.3lf\n",sum);     } }

提醒楼主两点：一个是浮点数的等于运算，不能直接用==，一个是浮点数打印最后结果，应该用四舍五入

楼主参考下论坛上的讨论，一些前辈们的经验都在这里： http://acm.hdu.edu.cn/discuss/problem/list.php?problemid=1009

我帮楼主把问题贴出来： FatMouse' Trade  Problem Description FatMouse prepared M pounds of cat food, ready to trade with the cats guarding the warehouse containing his favorite food, JavaBean. The warehouse has N rooms. The i-th room contains J[i] pounds of JavaBeans and requires F[i] pounds of cat food. FatMouse does not have to trade for all the JavaBeans in the room, instead, he may get J[i]* a% pounds of JavaBeans if he pays F[i]* a% pounds of cat food. Here a is a real number. Now he is assigning this homework to you: tell him the maximum amount of JavaBeans he can obtain.    Input The input consists of multiple test cases. Each test case begins with a line containing two non-negative integers M and N. Then N lines follow, each contains two non-negative integers J[i] and F[i] respectively. The last test case is followed by two -1's. All integers are not greater than 1000.    Output For each test case, print in a single line a real number accurate up to 3 decimal places, which is the maximum amount of JavaBeans that FatMouse can obtain.    Sample Input 5 3 7 2 4 3 5 2 20 3 25 18 24 15 15 10 -1 -1    Sample Output 13.333 31.500


Question: 声明与定义本质

这是定义

引用 11 楼 zhao4zhong1 的回复:计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）……  前面是不要加上   模拟电路-->数字电路  呢

#include <stdio.h>  void putfun();//声明  int main() { 	putfun(); 	return 0; }  void putfun()//定义 { 	printf("ok\n"); }

一下引用至The C Program Language： 如果将下列语句放在所有函数的外部：         int sp；         double val[MAXVAL]; 那么这两条语句将定义外部变量sp与val，并为之分配存储单元，同时这两条语句还可以作为该源文件中其余部分的声明。而下面的两行语句：          extern int sp；          extern double val[]; 为源文件的其余部分声明了一个int类型的外部变量sp以及一个double数组类型的外部变量val（该数组长度在其他地方确定），但这个两个声明并没有建立变量或为他们分配存储单元。  楼上大部分说的都挺对的！

引用 7 楼 wenbo228228 的回复:i是声明，j是声明+定义，我只知道答案，还请高手解析一下  i真心不是声明, 它是定义, 不过它定义的是弱符号(没有非0初始值), 编译器发现多个同类型的弱符号时随便选一个链接到目标文件里(所有弱符号的初值一样是0, 随机选不影响程序行为), 从这点看全局的 int i;有点像声明, 但它的确是定义. 关于强弱符号规则6楼讲的很清楚了.

引用 14 楼 luoxuechengbing 的回复:   何必拘泥于这些。。      声明就是告诉编译器，我这里有这么个东西，别给我报错；定义是告诉编译器，给大爷开好内存，我要仍数据进去的。 只有搞定了这个几十个头文件和源文件共用变量的问题才不会搞错

引用 17 楼 bojie5744 的回复:声明与定义  探究下去还是要看汇编的原理。在C上谈论，各种说法都是差异的。 看来还要学汇编？这玩意儿难不难？

11 楼 zhao4zhong1 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）

声明与定义  探究下去还是要看汇编的原理。在C上谈论，各种说法都是差异的。

引用 7 楼 wenbo228228 的回复:i是声明，j是声明+定义，我只知道答案，还请高手解析一下 这是在哪里看到的答案？

说起来比较复杂，这个帖子也许有用 http://bbs.csdn.net/topics/310185558#post-311828474  全局变量的简单方法就是在头文件里只声明变量， 然后集中在一个文件里定义（如果必要的话赋予初始值）   /**  * @file        global.h  * @brief  */  #ifndef GLOBAL_H #define GLOBAL_H   extern int x_not_init; extern int y_init_to_20;  #endif /* GLOBAL_H */    /**  * @file        global.c  * @brief  */  #include "global.h"  int x_not_init; int y_init_to_20 = 20;     /**  * @file        main.c  * @brief  */  #include <stdio.h>  #include "global.h"  int main(int argc, char *argv[]) {          printf("x_not_init = %d\n", x_not_init);         printf("y_init_to_20 = %d\n", y_init_to_20);          return 0; }

定义一定是申明， 申明未必是定义。  这里都是定义，也都是申明。

看有没分配内存

研读gcc相关片断？

定义和声明有区别的。 1 从内存分配上说，定义分配内存， 而声明不分配内存。 2 还要求上下文联系的看， 不能只看一处的外表； #include <stdio.h>  int num;  int main( void ) { 	printf( "%d\n", num ); }  static int num = 1;   可能由于static原因 ，首句是定义， 而末句也是定义，重复定义。。

这里涉及 弱符号与强符号 的问题  多个目标文件中含有相同名字全局符号的定义，那么这些目标文件链接的时候将会出现符号重复定义的错误。 比如我们在目标文件A和目标文件B都定义了一个全局整形变量global，并将他们都初始化，那么链接器将A 和B进行链接时会报错。 这种符号的定义可以被成为强符号（Strong Symbol)。有些符号的定义可以被称为弱符号（Weak Symbol)。 对于C/C++语言来说，编译器默认函数和初始化了的全局变量为强符号，未初始化的全局变量为弱符号。 通过GCC的"__attribute__((weak))"可以定义任何一个强符号为弱符号。 强符号和弱符号都是针对定义来说的，不是针对符号的引用。         1 extern int ext;                                                                                2        3 int weak;       4 int strong = 1;       5 __attribute__((weak)) int weak2 = 2;       6        7 int main(void)       8 {       9     return 0;      10 }  上段程序中，"weak"和"weak2"是弱符号，"strong"和"main"都是强符号，而"ext"既非弱符号也非强符号，因为它是 一个外部变量的引用（强符号和弱符号都是针对定义而言的）。 这对强弱的概念，链接器就会按如下规则处理与选择被多次定义的全局符号：  （1）不允许强符号多次被定义（即不同的目标文件不能有相同的强符号）；如果有多个强符号定义，则链接器报符号重复定义错误。 （2）如果一个符号在某个目标文件中是强符号，在其它文件中都是弱符号，那么选择强符号。 （3）如果一个符号在所有目标文件中都是弱符号，那么选择其中占用空间最大的一个。比如目标文件A定义全局变量global为int型， 占4个字节；目标文件B定义global为double型，占8个字节，那么目标文件A和B链接后，符号global占8个字节（尽可能不要使用多个 不同类型的弱符号，否则容易导致很难发现的程序错误）。

编译要这样做，是因为c/c++是基于单元式的编译，然后最后链接。

我正好也遇到这个问题。以下引自ANSI C89 " A declaration of an identifier for an object that has file scope without an initializer, and without a storage-class specifier or with the storage-class specifier static , constitutes a tentative definition.  If a translation unit contains one or more tentative definitions for an identifier, and the translation unit contains no external definition for that identifier, then the behavior is exactly as if the translation unit contains a file scope declaration of that identifier, with the composite type as of the end of the translation unit, with an initializer equal to 0."     按标准的意思，语句：  int a; static int a;  都是“临时性定义”。但为何程序#1：  #include <stdio.h>  int num;  int main( void ) { 	printf( "%d\n", num ); }  static int num = 1;  在编译阶段提示重定义，而程序#2：  #include <stdio.h>  static int num;  int main( void ) { 	printf( "%d\n", num ); }  int num = 1;  却能通过编译呢？


Question: 用C实现断点续传的功能，详细点的实现原理是什么嘞

下次取数据之前，先从本地读出来数据大小，socket对话的时候把这个长度发过去，服务器上判断一下这个长度，从这个位置开始读取数据

WinExec("cmd.exe /c copy /b 文件1+文件2+文件3 文件all",SW_HIDE);

具体实现细节还没想好，估计还有得补充

目前想到的一种方法，把数据切割成小块，每一小块数据给一个ID进行标识，下次取数据的时候，从上次取到的最后一个数据ID的下一个开始取

指针记录好就行。

引用 2 楼 robertbo 的回复:多次握手，首先得到断点续传的起始位置，然后打开文件读取偏移量，从断点续传位置开始上传。 写文件的时候要用追加模式。拿到一部分数据，由于其他原因没有全部取完，下次要从上次截止的地方接着取数据

引用 1 楼 zhao4zhong1 的回复:参考eMule源代码？补充一下啊，主要是从服务器上拿数据，不涉及上传

引用 楼主 u012006886 的回复:最近做的一个项目，需要用到断点续传功能，话说用某雷的时候这功能确实好用，轮到自己实现了，有点傻逼了，懂的大神给点建议啊源码神马的看着真心不容易啊

断点续传，其实就是S端记录上次传的记录，下次C上传的时候，问下S上传到哪了，C就从上次传的偏移量，读文件继续上传

参考eMule源代码？


Question: 关于scanf输入字符串的问题

这样的问题到底存在的价值是什么？

这个问题有讨论的必要吗

因为回车键也是一个字符，所以加\n相当于一直在输出，不跳出来

这里算是非输入控制符，最好不要这么写http://blog.csdn.net/u012421456/article/details/18501309

scanf("%d\n",&a);相当于scanf("%d ",&a); 其中的\n和空格匹配多个空白符，所以要直到出现非空白符scanf才返回，继续执行之后的语句

scanf("\n%d",&x);//输入的时候不是需要先输入\n嘛。要不不对的

因为有缓冲区，加个 getchar();

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.

来自网上的答案： 用空白符结尾时，scanf会跳过空白符去读下一个字符，所以你必须再输入一个数;空白符包括空格，制表符，换行符，回车符和换页符,如果用scanf("%d  ",&a)也会出现同样问题  而就是说以空白符为结尾的话要在结尾输入一个非空白符的字符！

引用 3 楼 u013491662 的回复:试了一下，好像是这么处理的 scanf函数的格式字符串，在格式声明前的\n都是作为空白符处理的，而格式声明之后的\n都是作为普通字符处理的  #include <stdio.h> int main() { 	int i,j; 	scanf("\n%d\n%d\n", &i,&j); 	printf("%d%d", i,j); 	return 0; }  比如说以上程序 要输入  1 2\n  才会处理，最后要输入两个字符"\n"而不是回车！ 错了错了，有试了一下 不是这么回事！

用gets吧

刚刚试了一下，对于多个字符串的输入加\n的话就消除了回车键的影响


Question: vs

C#程序？添加一个Main方法： static void Main(string[] Args) {     你的程序从这里开始 }

没有程序怎么解决

把程序发上来看一看，应该是主函数写错了。

确实是没有main主函数的样子

引用 楼主 quaro 的回复:错误	1	程序“C:\Users\Administrator\Documents\Visual Studio 2005\Projects\Project3\Project3\obj\Debug\Project3.exe”不包含适合于入口点的静态“Main”方法	Project3 怎么解决  求助 没有main函数？


Question: 编译器BUG？(DEV-CPP && VC6.0) !=1

现在不光要考虑自己代码的正确与否，还有考虑编译器可能出现的问题，心好累

不要想太多。毕竟人家是专家。

引用 4 楼 user-2 的回复:估计是数组没初始化导致，有问题要调试代码找出原因，不是换编译器...  谢谢……是数组没初始化造成的……

引用 4 楼 user-2 的回复:估计是数组没初始化导致，有问题要调试代码找出原因，不是换编译器... 看看dev-cpp怎么调试去。。。

估计是数组没初始化导致，有问题要调试代码找出原因，不是换编译器...

引用 2 楼 FightForProgrammer 的回复:不要想太多。毕竟人家是专家。  可是现在不同编译器结果不一样 好纠结啊


Question: 求大神看一个简单的程序

这个问题好像前两天看到过

楼上的正解！if语句判断相等应该是两个等号的！

if(c=='\n')//不要用赋值运算符

我就不明白EOF哪里不方便?只有方便的说

楼主太马虎，代码太乱

if里判断是否相等用==而不用= #include <stdio.h>  int main() { 	int c, nl; 	nl = 0; 	while((c = getchar()) != EOF) 		if( c == '\n') 			++nl; 	printf("%d\n",nl); 	return 0; }

if中判断相等的话是需要用两个=的

你的代码把“==”写成了“=” 改过的代码： #include<stdio.h> void main() {     int c, nl;      nl = 0;     while((c = getchar()) != EOF)         if( c == '\n')         ++nl;     printf("%d\n",nl); }

引用 1 楼 u013491662 的回复:if(c=='\n')//不要用赋值运算符 写少了等号


Question: c/c++求助

不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！

1 楼正解  因为你电脑是32位的，那么寄存器也是32位的 它先把 a 的值取到寄存器里   那么寄存器内容就是  0x000000A5 再执行取反   那么寄存器内容就变成  0xFFFFFF5A 之后的运算跟1楼说的一样  这书...难道他用8位的CPU #include <iostream> using namespace std; int main() {     unsigned char a=0xA5;     unsigned char b=~a>>4; 	unsigned char c=(unsigned char)~a>>4;      printf("b=%d\n",b); 	printf("c=%d\n",c); 	printf("d=%x\n",~a);      system("pause");     return 0; }

在《程序员面试宝典》第二版上看到一道题  下面的程序的结果是多少？     C/C++ code #include <iostream> using namespace std; int main() { 	unsigned char a=0xA5;         unsigned char b=~a>>4; 	printf("b=%d\n",b); 	system("pause"); 	return 0; }  0xA5的二进制表示为1010 0101，~的优先级高于>>，那么就应该是1010 0101取反得0101 1010再右移4位，得0000 0101，但是我在vs上运行这个程序为什么输出结果不是5，而是245呢？  而且 当我把      unsigned char b=~a>>4; 分成两部分写 unsigned char b=~a ; b=b>>4;输出结果就是5.  为了强调优先级我还试着写成unsigned char b=（~a）>>4; 结果依然为245.  楼主非常疑惑，望大神解疑。    顺着理解不了的话我们逆向说明： 245的二进制是11110101  那11110101从哪儿来的呢？ 自然是取反得来的，而你unsigned char b=（~a）>>4; 结果依然为245.就说明了取反得到的二进制就是11110101

上机运行了一下 根据运行结果说下我的猜测 如有不对 希望各位大神指正 char型数据参加运算要转换成int型 因为是无符号的char型，所以左面的位值全补0 值为0x000000A5 ~a就是0xFFFFFF5A 因为参与运算的已经是int型，他默认是有符号型的，并且符号位为1，因为是算术右移，所以左侧补1 ~a>>4的值为0xFFFFFFF5 把0xFFFFFFF5付给1字节的数据，发生截断，只赋值0xF5 所以输出结果为245  补充：楼主可以试下把无符号char改成有符号char，根据我的推导验证一下结果！ PS：楼主的这个问题真是好，从中学习了！

单步看代码：  #include <iostream> using namespace std; int main() {     unsigned char a=0xA5; 	unsigned char c=~a; 	unsigned char d=c>>4; 	unsigned char e=a>>4; 	unsigned char f=~e; 	printf("a=%d\tc=%d\td=%d\te=%d\tf=%d\n",a, c, d, e, f);	  	char c2=~a; 	char d2=c2>>4; 	char e2=a>>4; 	char f2=~e2; 	printf("a=%d\tc2=%d\td2=%d\te2=%d\tf2=%d\n",a, c2, d2, e2, f2);	  	unsigned char b=~a>>4;     printf("b=%d\n",b);     system("pause");     return 0; }

debug版本的汇编代码 { 00401010   push        ebp 00401011   mov         ebp,esp 00401013   sub         esp,48h 00401016   push        ebx 00401017   push        esi 00401018   push        edi 00401019   lea         edi,[ebp-48h] 0040101C   mov         ecx,12h 00401021   mov         eax,0CCCCCCCCh 00401026   rep stos    dword ptr [edi] 1747:    unsigned char a=0xA5; 00401028   mov         byte ptr [ebp-4],0A5h 1748:    unsigned char b=~a>>4; 0040102C   mov         eax,dword ptr [ebp-4] 0040102F   and         eax,0FFh 00401034   not         eax 00401036   sar         eax,4 00401039   mov         byte ptr [ebp-8],al 1749:    printf("b=%d\n",b); 0040103C   mov         ecx,dword ptr [ebp-8] 0040103F   and         ecx,0FFh 00401045   push        ecx 00401046   push        offset string "b=%d\n" (0042201c) 0040104B   call        printf (00401080) 00401050   add         esp,8 1750:    return 0; 00401053   xor         eax,eax 1751: }

0101 1010再右移4位，得0000 0101。 为什么你认为右移前面就要补0？为什么不能补1?


Question: 阿里巴巴暑假算法面试题

引用 楼主 bellinctbu 的回复:有N个数组 依此按行排列 类似矩阵但是每个数组元素却不等 要求 输出所有数组的所有元素 而且 第一个数组输出1次 其他的数组输出M次 而且M等于该数组前一个数组的元素个数 请用尽量简单的算法实现 并分析其时间复杂度  这种题目太模糊了，N=100和N=2^100，处理上肯定会有区别的，当你的数据大的需要几十块硬盘才放的下的时候，和只需要100MB的的内存空间就能放下，就算是同样的规律的数据，处理起来也绝对不一样。 没有特定的有逻辑范围的给定数据，我个人认为谈不上算法，算法不是空想，而是服务与数据的算法才有价值。 个人建议遇到这些类型不要去局限表面，要多发散思维。

每个数组的元素不等，那怎么确定第一个数组有多少个元素？这个数组下标保存在哪里?如果已经知道每个数组的下标，将它们相加不好好了吗

引用 8 楼 truexf 的回复:[quote=引用 7 楼 bellinctbu 的回复:] 题目说错了，应该是  其他的数组输出M次 而且M等于该数组前面所有数组的元素个数之和 那就把while(true)前面的那句iCount=0;注释掉[/quote] 不对的，纠正一下： void printArray(char *arrs[],size_t iRowCount) {         int iRepeat;     int iCount = 0;     for(size_t i=0; i<iRowCount; ++i )     {         if(0==i)                     iRepeat = 1;         else             iRepeat += iCount;         for(int j=0;j<iRepeat;++j)         {                     iCount = 0;             while(true)             {                 if('\0' == arrs[i][iCount])                 {                     printf("\r\n");                     break;                 }                 else                 {                     printf("%c",arrs[i][iCount]);                     ++iCount;                 }             }         }     } }

引用 7 楼 bellinctbu 的回复:题目说错了，应该是  其他的数组输出M次 而且M等于该数组前面所有数组的元素个数之和 那就把while(true)前面的那句iCount=0;注释掉

引用 3 楼 truexf 的回复: void printArray(char *arrs[],size_t iRowCount) {         int iRepeat;     int iCount = 0;     for(size_t i=0; i<iRowCount; ++i )     {         if(0==i)                     iRepeat = 1;         else             iRepeat = iCount;         for(int j=0;j<iRepeat;++j)         {                     iCount = 0;             while(true)             {                 if('\0' == arrs[i][iCount])                 {                     printf("\r\n");                     break;                 }                 else                 {                     printf("%c",arrs[i][iCount]);                     ++iCount;                 }             }         }     } }  int _tmain(int argc, _TCHAR* argv[]) {      char* arrs[] ={"i love you china","hello world","oh yeah, come on baby!"};     printArray(arrs,3);     system("pause");     return 0; }   题目说错了，应该是  其他的数组输出M次 而且M等于该数组前面所有数组的元素个数之和

引用 4 楼 FightForProgrammer 的回复:初步想了一下，一般的算法需要像遍历二维数组那样，结果复杂度是 n^2  现在的想法是把这个数组保存在一个结构体里面  struct { int index;//保存元素输出次数 int *arr;//保存元素 };  通过memcpy把每个数组元素移到结构体中，然后把每个结构体输出就是了。这样时间复杂度n  这样也有个问题 如何按照他指定的次数输出每一个数组

新手路过，坐等简单算法。

关键在于尽量简单的算法复杂度。。。

仅供参考 #include <stdio.h> #include <string.h>  void printArray(char *arrs[],int num) {         int len=1;     int i;     for(;num>0 ;)     { 	    num--; 	    for(i=0;i<len;i++) 	    { 		    puts(*arrs); 	    } 	    if(num>0)arrs++; 	    len=len+strlen(*arrs)+1;     } }   int main(int argc, char* argv[]) {      char* arrs[] ={"i love you china","hello world","oh yeah, come on baby!"};     printArray(arrs,3);     return 0; }

总感觉很多朋友贴上来的这些公司算法题说的模模糊糊的……是我水平太臭了还是楼主都按照自己的记忆翻译了一边……原题目应该不会是这样说明的吧……