Question: 请教高手一个关于循环处理字符串的程序问题，多谢

ctrl+c有时候不行就用Ctrl+Break，如果还是不行，点cmd窗口右上角的×，如果还是不行，在任务管理器里面结束进程cmd.exe!

引用 1 楼 zhao4zhong1 的回复:#include<ctype.h> #include<stdbool.h> #define STOP '|' int main() {     char c;     char prev;     long n_chars;     int n_lines;     int n_words;     int p_lines;     bool inword;      while (1) {         n_chars = 0L;         n_lines = 0;         n_words = 0;         p_lines = 0;         inword = false;         printf("Enter text to be analyzed(|to terminate,Ctrl+C to exit);\n");         prev = '\n';         while ((c = getchar()) != STOP) {             n_chars++;             if (c == '\n')                 n_lines++;             if (!isspace(c) && !inword) {                 inword = true;                 n_words++;             }             if (isspace(c) && inword)                 inword = false;             prev = c;         }         if (prev != '\n')             p_lines = 1;         printf("characters=%ld,words=%d,lines=%d,", n_chars, n_words, n_lines);         printf("partial lines=%d\n", p_lines);     }     return 0; } 赵老师，不好意思，我才查了吓知道ctrl+c是强制退出

引用 1 楼 zhao4zhong1 的回复:#include<ctype.h> #include<stdbool.h> #define STOP '|' int main() {     char c;     char prev;     long n_chars;     int n_lines;     int n_words;     int p_lines;     bool inword;      while (1) {         n_chars = 0L;         n_lines = 0;         n_words = 0;         p_lines = 0;         inword = false;         printf("Enter text to be analyzed(|to terminate,Ctrl+C to exit);\n");         prev = '\n';         while ((c = getchar()) != STOP) {             n_chars++;             if (c == '\n')                 n_lines++;             if (!isspace(c) && !inword) {                 inword = true;                 n_words++;             }             if (isspace(c) && inword)                 inword = false;             prev = c;         }         if (prev != '\n')             p_lines = 1;         printf("characters=%ld,words=%d,lines=%d,", n_chars, n_words, n_lines);         printf("partial lines=%d\n", p_lines);     }     return 0; } 赵老师，请问实现ctrl+c退出是那一句，我觉得在输入ctrl+c以后第二个while虽然没实现但是第一个while条件仍然为真，应该会继续等待输入，而不是退出，请赵老师解答


Question: 使用指针数组进行字典排序的问题

这个指针数组排序，理论上是不是应该直接换指针就可以了吗，，那个swap换的不是字符串的第一个字符吗。。。

引用 1 楼 user-3 的回复:我这一个都运行不正常。。swap出错。 你的dic保存的字符串是常量，不能更改吧   +1


Question: 一个设备插上以后驱动是如何被调用的

VID 和 PID 相同的产品太多了，只要是同一个产品，她们就是相同的。 假定我们生产鼠标，我们的鼠标都有同一个 VID ，这是需要申请的。 然后，我们不同的产品类型使用不同的 PID 。这样在驱动里就可以使用不同的驱动程序了。


Question: N皇后问题的两种算法速度比较

在第一种算法中，同一个数字出现多次也只进行一次计算，第二种算法则每次都要重新计算。

参考代码 https://github.com/user-2/Practice-Code-For-CPP/blob/master/20150326001.c


Question: 如何解决vs打开制作好的控制台程序会闪退的问题

static void Main(string[] args) {                                     Console.ReadLine(); //后面加一个这个语句 }

system("pause")；

加上  system("pause")

在return 0前面加个getchar();


Question: 用循环让scanf函数输入字符串的问题

刚才忘了，还有一种情况，就是程序结束的时候，缓冲区里的内容也会输出。  试试这个：   printf("123");   sleep(3);   printf("abc\n"); 如果改成"123\n"，或者在sleep之前加上fflush(stdout)，运行结果就会有变化。

printf的输出是有缓冲的。printf的第一步把要输出的内容放到一个缓冲区里，第二步才是真正输出。 两种情况下缓冲区里的内容会被输出：一个是遇到\n，另一个是强制flush 13         printf("%c",ch); fflush(stdout); /* 加上这行试试 */  15         sleep(3);


Question: C语言，信息系统如何做到删除数组？

读取->判断写-> 完

吧文件读到内存中来，不想删除的部分重新写进磁盘，要删除部分则不写。吧原文件删除。


Question: gcc下面enum要怎么用啊，好像跟其他的不一样，好奇怪

谢啦

enum x{aa,bb,cc};  C:       enum x x1;  c++:      x x1;   // ----------------------------- 对于 struct 也一样. 所以才会常常搭配 typedef

enum x{aa,bb,cc}; enum x x1;


Question: 关于fopen打开失败的问题

加 sync

FindFirstChangeNotification The FindFirstChangeNotification function creates a change notification handle and sets up initial change notification filter conditions. A wait on a notification handle succeeds when a change matching the filter conditions occurs in the specified directory or subtree.   HANDLE FindFirstChangeNotification(   LPCTSTR lpPathName,    // pointer to name of directory to watch   BOOL bWatchSubtree,    // flag for monitoring directory or                           // directory tree   DWORD dwNotifyFilter   // filter conditions to watch for );   Parameters lpPathName  Pointer to a null-terminated string that specifies the path of the directory to watch.  bWatchSubtree  Specifies whether the function will monitor the directory or the directory tree. If this parameter is TRUE, the function monitors the directory tree rooted at the specified directory; if it is FALSE, it monitors only the specified directory.  dwNotifyFilter  Specifies the filter conditions that satisfy a change notification wait. This parameter can be one or more of the following values: Value Meaning  FILE_NOTIFY_CHANGE_FILE_NAME   Any filename change in the watched directory or subtree causes a change notification wait operation to return. Changes include renaming, creating, or deleting a filename.  FILE_NOTIFY_CHANGE_DIR_NAME   Any directory-name change in the watched directory or subtree causes a change notification wait operation to return. Changes include creating or deleting a directory.  FILE_NOTIFY_CHANGE_ATTRIBUTES   Any attribute change in the watched directory or subtree causes a change notification wait operation to return.  FILE_NOTIFY_CHANGE_SIZE   Any file-size change in the watched directory or subtree causes a change notification wait operation to return. The operating system detects a change in file size only when the file is written to the disk. For operating systems that use extensive caching, detection occurs only when the cache is sufficiently flushed.  FILE_NOTIFY_CHANGE_LAST_WRITE   Any change to the last write-time of files in the watched directory or subtree causes a change notification wait operation to return. The operating system detects a change to the last write-time only when the file is written to the disk. For operating systems that use extensive caching, detection occurs only when the cache is sufficiently flushed.  FILE_NOTIFY_CHANGE_SECURITY   Any security-descriptor change in the watched directory or subtree causes a change notification wait operation to return.    Return Values If the function succeeds, the return value is a handle to a find change notification object.  If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError.   Remarks The wait functions can monitor the specified directory or subtree by using the handle returned by the FindFirstChangeNotification function. A wait is satisfied when one of the filter conditions occurs in the monitored directory or subtree.   After the wait has been satisfied, the application can respond to this condition and continue monitoring the directory by calling the FindNextChangeNotification function and the appropriate wait function. When the handle is no longer needed, it can be closed by using the FindCloseChangeNotification function.   QuickInfo   Windows NT: Requires version 3.1 or later.   Windows: Requires Windows 95 or later.   Windows CE: Unsupported.   Header: Declared in winbase.h.   Import Library: Use kernel32.lib.   Unicode: Implemented as Unicode and ANSI versions on Windows NT.  See Also File I/O Overview, File Functions, FindCloseChangeNotification, FindNextChangeNotification

in A in A in A in T in G in A in G 没有打开，继续打开：H:\mcm\info\414.txt 没有打开，继续打开：H:\mcm\info\414.txt 没有打开，继续打开：H:\mcm\info\414.txt 没有打开，继续打开：H:\mcm\info\414.txt 没有打开，继续打开：H:\mcm\info\414.txt 没有打开，继续打开：H:\mcm\info\414.txt 没有打开，继续打开：H:\mcm\info\414.txt 没有打开，继续打开：H:\mcm\info\414.txt 没有打开，继续打开：H:\mcm\info\414.txt 没有打开，继续打开：H:\mcm\info\414.txt 没有打开，继续打开：H:\mcm\info\414.txt 没有打开，继续打开：H:\mcm\info\414.txt 没有打开，继续打开：H:\mcm\info\414.txt 没有打开，继续打开：H:\mcm\info\414.txt in G in A in A in T  有时候像这样经过几次while(!(rp=open(route,"a")){cout << "......."<<endl;} 之后成功打开，但这并不理想。。


Question: 不能调试了，不是程序问题，我用了好多个正确的例子尝试了，有不用重装的方 法吗？？

重装吧  要不了多久

路径是否包含中文？

你确定你选的不是release？


Question: C的字符串与数组问题请教

#pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！

谢谢楼上 各位的解答。看来我对这个存储空间没怎么考虑，以为有个地址就行了。

楼上各位大哥已说出原委，，，，char *只分配了自己这个指针数据类型的4个字节的内存，而字符数组是真真正正的在内存中开辟了一块用于存字符的空间。

char *str;只是定义了一个指针，没有指向可用的内存，而char str[100]是定义了一个字符数组，长度为100，本身就是一块可用的内存。

引用 2 楼 u011076569 的回复:[quote=引用 1 楼 zhangxiangDavaid 的回复:] 都没有分配内存，往哪里读入呢？ 意思是必须用malloc分配一块空间才行是吧。  我试过 char *buffer;  buffer = malloc(100* sizeof(char)); 确实可以。谢谢。另外请教是不是我们给char *buffer = "test"这么赋值的时候 会自动分配空间是吧。我之前 的char*buffer是没有分配空间的。[/quote] char *buffer = "test" 这并不是自动分配空间，而是指向一个已存在的空间，"test"在常量区

没地方存。。。

引用 1 楼 zhangxiangDavaid 的回复:都没有分配内存，往哪里读入呢？ 意思是必须用malloc分配一块空间才行是吧。  我试过 char *buffer;  buffer = malloc(100* sizeof(char)); 确实可以。谢谢。另外请教是不是我们给char *buffer = "test"这么赋值的时候 会自动分配空间是吧。我之前 的char*buffer是没有分配空间的。

都没有分配内存，往哪里读入呢？


Question: 想询问下下面这个我搞不清的是啥意思

引用 8 楼 zhangxiangDavaid 的回复:参考4楼的，进行解析 谢谢捧场！

参考4楼的，进行解析

把一个参数是俩uint8_t，返回值是int32_t的函数指针改名为m_set_t

有个简单的方法： 没有typedef就是定义变量； 有了typedef就是定义类型。  int a; // 定义a为int类型变量 typedef int a; // 定义a为类型  void (*foo)(); // 定义foo为函数指针变量 typedef void (*foo)(); // 定义foo为函数指针类型

引用 3 楼 ForestDB 的回复:1L2L都忽略了typedef么？就是被那个typedef的有点误导

m_set_t 是函数指针，指向返回值是int32_t，参数0是uint8_t，参数1是uint8_t b的函数。

仅供参考：//char (*(*x[3])())[5];//x是什么类型的变量? // //分析C语言声明，关键是搞清楚这个变量是个什么东西（函数、指针、数组）， //是函数那么剩下的就是他的参数和返回值， //是指针那剩下部分是说明他指向什么， //是数组剩下的部分就是说明数组的成员是什么类型。 //解析C语言声明规则： //从左侧第一个标识符开始，按照优先级进行结合。*表示是..的指针，const表示只读的，volatile表示可变的，[]表示是数组，()表示是函数。 // //x和[3]结合说明是一个大小为3的数组，该数组的每个元素为一类指针，该类指针指向一类函数，该类函数无参数，返回一类指针，该类指针指向一个大小为5的char型数组 #include <stdio.h> #include <typeinfo.h> char num[5]; char (*x00())[5] {     return # } int main() {     char (*(*x[3])())[5];//是个数组，大小为3     char (*(*x0  )())[5];//数组的元素，是个函数指针     char (*( x00 )())[5];//函数原型，参数为空，返回值为指针     char (*  x000   )[5];//返回值      x0 = x00;     x[0] = x0;     x[1] = x0;     x[2] = x0;     printf("typeid(x).name() is %s\n",typeid(x).name());     return 0; } //typeid(x).name() is char (* (__cdecl**)(void))[5]

声明一个指针函数，m_set_t 是函数指针，指向返回值是int32_t，最后面的是参数


Question: C语言求助

另一个问题 #include<stdio.h> char *fun(char *p) { 	int i,j=0; 	char *q=p; 	for(i=0;i<20;i++) 	{ 		if('0'<=q[i]&&q[i]<='9') 			p[j++]=q[i]; 	} 	for(i=0;i<20;i++) 	{ 		if('0'<=q[i]&&q[i]<='9') 			continue; 		else	p[j++]=q[i]; 	} 	 	return(p);//为什么不能返回局部变量q的地址 } /*{ 	char *q=NULL; 	for(i=0;i<20;i++) 	{ 		if('0'<=p[i]&&p[i]<='9') 			q[j++]=p[i]; 	} 	for(i=0;i<20;i++) 	{ 		if('0'<=p[i]&&p[i]<='9') 			continue; 		else	q[j++]=p[i]; 	} 	 	return(q);//为什么不能返回局部变量q的地址,如果在前一句加p=q；返回q也是错误的，为什么？ 	} */ main() { 	 	char s[20]="asd123fgh5##43df";//为什么输出为123543fgh##df 	char *b=NULL; 	b=fun(s);  	printf("%s\n",b); }

char *q=p;           // 这样写 for(i=0;i<20;i++) { if('0'<=p[i]&&p[i]<='9') q[j++]=p[i]; } for(i=0;i<20;i++) { if('0'<=p[i]&&p[i]<='9') continue; else q[j++]=p[i]; }  return q;

正确来讲，是第一个出现两次以上的字符

2.这样可好：  int i, pos1, pos2, n; unsigned char bm[32]; int main(void) { 	char *s = "beijing"; 	n = strlen(s); 	memset(bm, 0, 32); 	for (i = 0; i < n; i++) 	{ 		pos1 = s[i] / 8; 		pos2 = s[i] % 8; 		if (0 == (bm[pos1] & (1u << pos2))) 		{ 			bm[pos1] |= 1u << pos2; 		} 		else 		{ 			printf("%c\n", s[i]); 			break; 		} 	} 	if (i == n) printf("non a character occurs twice!\n"); 	return 0; }

1.修改如下：  #include<stdio.h> void fun(char x[5][10], int n) { 	x[n][0] = 0; } int main() { 	char x[5][10] = { "create","modify","sort","skip","delete" }; 	int i; 	printf("the original string:\n"); 	for (i = 0; i<5; i++) 		puts(x[i]); 	printf("\n"); 	printf("the string after delect:\n"); 	fun(x, 4); 	for (i = 0; i<5; i++) 		puts(x[i]); 	printf("\n"); 	return 0; }


Question: 如何使用c语言通过域名得到ip。服务器是域名转发的技术

续求解决方案

引用 18 楼 yhlzxq 的回复:用的是域名转发技术来把ip转发回来，而不是解析 ？？？

用的是域名转发技术来把ip转发回来，而不是解析

引用 16 楼 dooX8086 的回复:域名---->IP ： 我们常常称为 域名解析，是通过 DNS 服务器进行解析的 域名转发(URL跳转) ：DNS服务器是没有这功能的，是由 DNS服务商提供的特殊处理的功能,是专门针对浏览器的( http 客户端) 如：www.a.com  做了转发到  www.b.com 过程大概是这样: 1). 浏览器 -----  向  DNS服务 请求 www.a.com 的 IP -----> DNS 返回一个 IP (这是个"虚假"的IP, 是DSN服务商专为url转发准备好的) 2). 浏览器 ----- 使用http协议访问: IP -----> IP主机会返回 http 301/302   location:www.b.com 的 内容给 浏览器 3). 浏览器 处理 http 301/302 location:www.b.com, 然后访问  www.b.com   (这就是所为的  跳转 ) 4). 浏览器 -----  向  DNS服务 请求 www.b.com 的 IP  (这个才是真的目的IP) 5).  ......  ps:怎么感觉我把它说复杂了  - -!!!!  -------------------------------------------------------------------------------------- 拿 csdn  的域名来的看看  www.csdn.com 是做了跳转到  www.csdn.net 的 用工具 curl 看看它  可以看到 是采用 http 302 显式 跳转 你再用 浏览器 访问下 www.csdn.com 就应该明白了, 所为的URL跳转 是 http 客户端干的  说了一陀陀都是关于 域名跳转/url转发 的  ------------------------------------------------------------ 如果楼主环境的相关服务对  www.xxxx.local  "转发" 所做的特殊处理是直接返回目的  IP 的... ...那请无视我上面所说的。 因为这就是 DNS 的 A记录了 非常感谢你的解答，非常详细，有点诚惶诚恐。嗯，之前问过领导，他说服务器是直接返回ip地址的。那就是说我现在应该朝着a记录这个线索走了？

引用 14 楼 dooX8086 的回复:哦。url 转发(跳转) 走的是 http 301/ 302 . 可以用curl 或其它工具 抓一下  www.xxxx.local  验证一下 如： curl -I www.xxxx.local 如果是的话。  那就需要从 http 301/302 中取出 真正的目的 host 再用 getaddrinfo  才可以获取到地址 = = 本人愚钝。。。没太明白。。。对于网络方便几乎一穷二白。。。c 语言网络方面更是。。。 它这个是这样的，正常的url转发是给你另一个域名，但是它是转发回一个ip地址，然后我这边取到，它就当是域名解析用了。。。。

用的是域名转发技术来把ip转发回来，而不是解析。。。

引用 10 楼 ForestDB 的回复:要么把服务器配好，要么直接在hosts中加上name，ip的对应。 问题是就是，它服务器不是正常的dns服务器啊。。。是域名转发的啊。。。

引用 9 楼 dooX8086 的回复:你的这个 www.xxxx.local  域名记录 有没在你公司的 dns 服务器上? 没有就让你同事帮你添加 不是dns服务器。。。它那个是域名转发的服务器。。。。

要么把服务器配好，要么直接在hosts中加上name，ip的对应。

引用 7 楼 dooX8086 的回复:域名 ----> ip  先查找本地 dns 表记录(缓存),如果没有)-----请求----> dns 服务器  如果 www.xxxx.local  是个私有域名  (自己定的，没有通过公共dns服申请) . 可以通过修改本地的 hosts 文件或在 dns 服务(自己服务器)上添加 A 记录, 为 www.xxxx.local 指定 ip 只有这样 gethostbyname 跟 getaddrinfo 等。函数才能取得IP  ----------------------------------------- ps: 好像 gethostbyname 跟 getaddrinfo 还支持  netbios 协议...嗯..忘记了  非常感谢您的回答。主要这边问题在于，它这个服务器是url转发，而不是正常的dns服务器。所以这个才不能正常得到ip地址把。但是安卓那边确可以使用正常的java代码返回得到ip。。。

引用 5 楼 super_admi 的回复:为什么我看不懂你的意思呢？  按我自己的理解说说吧：我觉得你是没有办法解析你们公司的域名的。为啥？因为你们公司没有自己的域名服务器，而网上的域名服务器中的解析表又没有你们公司的域名。  = = 是可以的。我们公司那个服务器应该不是正常的域名服务器。它是用的域名转发实现的。你问我为什么会这样。。。对不起。。。我不知道。。。然后，安卓端那边已经实现了。- - 我这是ios。主要是url转发11年就全面下掉了，根本没什么资料了。。。真实头大

gethostbyname 跟 getaddrinfo 我都试过了。只能解析到百度这类的域名。不过我们那个域名是www.xxxx.local这个样式的，不知道这个会不会有影响。

我是做移动端开发的。自带的实现不了，就想利用c语言解决。

DNSQuery? 我忘了这货有没有类似接口了, 不过这或许是个C艹接口, 但是也不必在意, C艹接口也可以给C用

参考c:\WINDOWS\system32\drivers\etc\hosts文件的内容？


Question: assignment from incompatible pointer type [enabled by default]警告如何排错

你确定15、16行这样做合适？ 暂且不论常量赋值给非常量，ptr[1...11] 貌似也没用吧。

已找到原因，数组被定义成常量，而指针是非常量，将常量数组赋值于非常量指针，可能会导致利用指针修改常量的值，所以警告。


Question: 菜鸟求助帖，寻大神解释程序运行的毛病

还得确保你的输入是合法的

修改如下：  //对一个长度为n的字符串从其第k个字符起，删去m个字符，组成长度为n-m新字符串，并输出处理后的字符串。用自定义函数实现。 #include <stdio.h> #include <stdlib.h> char *fact(int n, int m, int k, char *str1, char *str2); int main() { 	int n, m, k, i; 	char *str1, *str2; 	printf("请输入长度n:\n"); 	scanf("%d", &n); 	str1 = (char*)malloc(n*sizeof(char)); 	printf("请输入删去字符的个数m:\n"); 	scanf("%d", &m); 	str2 = (char*)malloc((n - m)*sizeof(char)); 	printf("请输入开始删除的字符个数:\n"); 	scanf("%d", &k); 	printf("请输入长度为%d的字符串:\n", n); 	getchar();    //读入回车 	for (i = 0; i<n; i++) 	{ 		scanf("%c", str1 + i); 	} 	str1[i] = 0;    //加结束符 	str2 = fact(n, m, k, str1, str2); 	printf("处理后的字符串为:%s\n", str2); 	return 0; } char *fact(int n, int m, int k, char *str1, char *str2) { 	int i; 	for (i = 0; i < k; i++) 	{ 		*(str2 + i) = *(str1 + i); 	} 	for (i = 0; i < n - m; i++)  //n - m 	{ 		*(str2 + k + i) = *(str1 + k + m + i); 	} 	*(str2 + k + i) = '\0'; 	return str2; }

/**************************************  *FILE    :D:\c\main.c  *PROJECT :NULL  *AUTHOR  :user-2  *CREATED :2015-5-14 下午 10:18:01  *TEXT    :对一个长度为n的字符串从其第k个字符起，删去m个字符并输出  *EMAIL   :gtsoft_wk@foxmail.com  *CODE    :https://github.com/user-2 ***************************************/  #include <stdio.h>  void strcatstr(char* str1,char *str2) { 	while(*str1)str1++; 	while(*str1++=*str2++); }  int main() { 	int start; 	int end; 	char str[100]; 	printf("请输入字符串:\n"); 	scanf("%s",str);     printf("请输入开始删除的字符位置:");     scanf("%d",&start);     printf("请输入删去字符的个数:");     scanf("%d",&end);          str[start-1]='\0'; 	strcatstr(str,str+start+end-1); 	     printf("处理后的字符串为:%s\n",str);     return 0 ; }


Question: C++的总结

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

有点长，看了前面，我觉得步长的1，2可以合在一起，指针指向的内容大小就是步长

不错，我支持楼主


楼主我最近也在研究这个问题  我遇到了个更简单的问题  初始化  包含什么静态库 和用什么初始化 想问下你是怎么写的

先定义一个列表控件的变量m_list，然后  DWORD dwStyle = m_list.GetExtendedStyle();  	dwStyle |=LVS_EX_FULLROWSELECT; 	dwStyle |= LVS_EX_GRIDLINES; 	m_list.SetExtendedStyle(dwStyle);

是ListView麽？

void InitialListView(HWND hWnd) { 	HWND hListView; 	LVCOLUMN lvc; 	LVITEM lvI; 	LVITEM lvSub; 	WCHAR Num[10]; 	RECT rect; 	int xBorder;  	hListView = GetDlgItem(hWnd, 1001);  	lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; 	lvc.fmt = LVCFMT_CENTER; 	lvc.cx = 80; 	for (int i = 0; i < 5; i++) 	{ 		wsprintf(Num, L"%d", i); 		lvc.iSubItem = i; 		lvc.pszText = Num;		  		ListView_InsertColumn(hListView, i,&lvc); 	}  	lvI.mask = LVIF_TEXT; 	lvI.iSubItem = 0; 	 	GetClientRect(hListView, &rect); 	xBorder = GetSystemMetrics(SM_CXBORDER); 	MoveWindow(hListView, 0, 0, 404, 150, FALSE); 	GetClientRect(hListView, &rect); 	// Initialize LVITEM members that are different for each item. 	for (int index = 0; index < 3; index++) 	{ 		lvI.iItem = index; 		lvI.iImage = index; 		wsprintf(Num, L"vlaue %d", index); 		lvI.pszText = Num; 		// Insert items into the list. 		ListView_InsertItem(hListView, &lvI); 		{ 			//添加子项 			lvSub.iItem = index; 			lvSub.mask = LVIF_TEXT; 			lvSub.pszText = L"subvalue";  			for (int j = 1; j <5; j++) 			{ 				lvSub.iSubItem = j; 				ListView_SetItem(hListView, &lvSub); 			} 		} 	} 	  }

请问，正确的使用方开头应该是怎样的，为什么我怎么也不能写入数据！


Question: 新手求助：关于fwrite的问题

UDP是不可靠的包交换协议。

缓冲的原因？

引用 1 楼 q3733353520 的回复:man fread  看看 fread 第二个 和第三个  参数

man fread


Question: 编写一个程序，将字符数组s2中的全部字符复制到字符数组s1中，不用strcpy函数，编译结果不一致！

引用 10 楼 mymtom 的回复:[quote=引用 5 楼 youjun610789338 的回复:]         单步调试一般用一般就用F10，F11是step in，如果遇到库函数也会进入，比较多余         单步调试可以让你明白你的每一句代码都干了什么，是否达到了你要的效果，当程序最终执行结果和预想的不一致时，就可以利用单步调试排查具体哪一行代码出问题！          看了你的代码让我想起了N年前的我自己，菜鸟一个，我试着copy一下来验证，唉，copy完我就后悔了，还不如自己重写一遍。         先指出你代码中有问题的部分：         1、main函数最好是返回int类型         2、别用vs下特有的_s函数，看着眼生貌似很牛逼，如果是跨平台的话，移植的时候有的你蛋疼         3、数组最好初始化char s1[80] = {0};         4、你用strlen(s2)来做限制，那么字符串结束符'\0'就不会被拷贝到s1中，这样打印出来的s1结尾就是乱码         5、你的变量命名是不规范的，可以百度一下匈牙利命名法则。          再看看我写的代码吧：  #include <stdio.h> #include <assert.h> #include <string>  char* STRCPY(char* dest, const char* src){     assert((src != NULL)&&(dest != NULL));          char* pDest = dest;     do{         *dest = *src;         dest++,src++;     }while(*src != '\0');          return pDest; }     int main(int argc, char** argv){     char szBuf[80] = "youdalfaoduandljfaa";     char szBuf1[80] = {0};          STRCPY(szBuf1, szBuf);          printf("%s\n%s\n", szBuf, szBuf1);     return 0; }              这是一道比较经典的C笔试题，考点全在STRCPY函数里面，考点分为：         1、STRCPY必须返回char*         2、要有断言，对入参进行判断         3、copy循环体 判断参数？有必要吗？误人子弟啊！ 自己看看strcpy的实现吧！[/quote]  也不一定是必要的，如果自己传入的参数足够安全的话，可以不用判断入参，但是传个NULL给strcpy，运行就会出错，对入参进行断言判断体现的是严谨性，哪里来的误人子弟一说！

引用 12 楼 u013409439 的回复:[quote=引用 11 楼 guicaisa 的回复:] 最后目标字符串里尾巴得加个'\0'吧。或者你这样初始化char str[80] = {0}; 断点调试就是在需要断点的地方按个F9，然后F5执行，F10单步执行，这时候自己观察监视器里每个变量的实时的数值啊，从而对是哪步出差错了可以很快的判别出来，F11进入函数，可以自己更直观的了解程序的执行流程。  哪里尾巴加个‘\0’? f11进入函数，进入函数都是看不懂的语句怎么破[/quote]  你不是用一个for循环然后s1[i] = s2[i]吗，循环结束后，目标字符串s1[i] = '\0';把尾巴填上。

问题解决了，是scanf_s后面少个参数80，修改为scanf_s("%s",s2,80);就好了！多谢各位大神~

引用 5 楼 youjun610789338 的回复:单步调试一般用一般就用F10，F11是step in，如果遇到库函数也会进入，比较多余         单步调试可以让你明白你的每一句代码都干了什么，是否达到了你要的效果，当程序最终执行结果和预想的不一致时，就可以利用单步调试排查具体哪一行代码出问题！          看了你的代码让我想起了N年前的我自己，菜鸟一个，我试着copy一下来验证，唉，copy完我就后悔了，还不如自己重写一遍。         先指出你代码中有问题的部分：         1、main函数最好是返回int类型         2、别用vs下特有的_s函数，看着眼生貌似很牛逼，如果是跨平台的话，移植的时候有的你蛋疼         3、数组最好初始化char s1[80] = {0};         4、你用strlen(s2)来做限制，那么字符串结束符'\0'就不会被拷贝到s1中，这样打印出来的s1结尾就是乱码         5、你的变量命名是不规范的，可以百度一下匈牙利命名法则。          再看看我写的代码吧：  #include <stdio.h> #include <assert.h> #include <string>  char* STRCPY(char* dest, const char* src){     assert((src != NULL)&&(dest != NULL));          char* pDest = dest;     do{         *dest = *src;         dest++,src++;     }while(*src != '\0');          return pDest; }     int main(int argc, char** argv){     char szBuf[80] = "youdalfaoduandljfaa";     char szBuf1[80] = {0};          STRCPY(szBuf1, szBuf);          printf("%s\n%s\n", szBuf, szBuf1);     return 0; }              这是一道比较经典的C笔试题，考点全在STRCPY函数里面，考点分为：         1、STRCPY必须返回char*         2、要有断言，对入参进行判断         3、copy循环体  感谢倾心回复，感觉出来前辈的用心回复！ 我现在还处于看课后题自己不会编写，看了答案还需要好久才能看懂的或者直接硬着头皮比照着敲上去，然后在编译看效果的程度。 但是我用单步调试的时候其实好多也看不明白，会出现好多“烫烫烫”好多烫字让人很不解。 这个答案确实是我比照着敲得没有发现有错误，但是编译结果却不一致。 scanf_s是万不得已使用的，因为vs2013有保护程序，如果不这样先编译错误，说是会溢出。 前辈编写的程序有点看不懂，我刚看到函数那一章，貌似有指针

恩，5楼说的很好

恩，5楼说的很好，第四点，你用<=，所以还算ok吧

scanf, fscanf, sscanf, scanf_s, fscanf_s, sscanf_s 下面有一段话：4-6) Same as (1-3), except that %c, %s, and %[ conversion specifiers each expect two arguments (the usual pointer and a value of type rsize_t indicating the size of the receiving array,…… 意思是%c, %s, 和 %[，后面对应两个参数：一个指针和指示此数组大小的值 你的scanf_s后面少个参数80

引用 13 楼 u013163178 的回复:#undef __stpcpy #undef stpcpy  #ifndef weak_alias # define __stpcpy stpcpy #endif  /* Copy SRC to DEST, returning the address of the terminating '\0' in DEST.  */ char * __stpcpy (dest, src)      char *dest;      const char *src; {   char *d = dest;   const char *s = src;  /*没有考虑内存重叠的情况*/   do     *d++ = *s;   while (*s++ != '\0');    return d - 1; }  表示看不懂  引用 13 楼 u013163178 的回复:#undef __stpcpy #undef stpcpy  #ifndef weak_alias # define __stpcpy stpcpy #endif  /* Copy SRC to DEST, returning the address of the terminating '\0' in DEST.  */ char * __stpcpy (dest, src)      char *dest;      const char *src; {   char *d = dest;   const char *s = src;  /*没有考虑内存重叠的情况*/   do     *d++ = *s;   while (*s++ != '\0');    return d - 1; }  话说看不懂

引用 11 楼 guicaisa 的回复:最后目标字符串里尾巴得加个'\0'吧。或者你这样初始化char str[80] = {0}; 断点调试就是在需要断点的地方按个F9，然后F5执行，F10单步执行，这时候自己观察监视器里每个变量的实时的数值啊，从而对是哪步出差错了可以很快的判别出来，F11进入函数，可以自己更直观的了解程序的执行流程。  哪里尾巴加个‘\0’? f11进入函数，进入函数都是看不懂的语句怎么破

引用 5 楼 youjun610789338 的回复:单步调试一般用一般就用F10，F11是step in，如果遇到库函数也会进入，比较多余         单步调试可以让你明白你的每一句代码都干了什么，是否达到了你要的效果，当程序最终执行结果和预想的不一致时，就可以利用单步调试排查具体哪一行代码出问题！          看了你的代码让我想起了N年前的我自己，菜鸟一个，我试着copy一下来验证，唉，copy完我就后悔了，还不如自己重写一遍。         先指出你代码中有问题的部分：         1、main函数最好是返回int类型         2、别用vs下特有的_s函数，看着眼生貌似很牛逼，如果是跨平台的话，移植的时候有的你蛋疼         3、数组最好初始化char s1[80] = {0};         4、你用strlen(s2)来做限制，那么字符串结束符'\0'就不会被拷贝到s1中，这样打印出来的s1结尾就是乱码         5、你的变量命名是不规范的，可以百度一下匈牙利命名法则。          再看看我写的代码吧：  #include <stdio.h> #include <assert.h> #include <string>  char* STRCPY(char* dest, const char* src){     assert((src != NULL)&&(dest != NULL));          char* pDest = dest;     do{         *dest = *src;         dest++,src++;     }while(*src != '\0');          return pDest; }     int main(int argc, char** argv){     char szBuf[80] = "youdalfaoduandljfaa";     char szBuf1[80] = {0};          STRCPY(szBuf1, szBuf);          printf("%s\n%s\n", szBuf, szBuf1);     return 0; }              这是一道比较经典的C笔试题，考点全在STRCPY函数里面，考点分为：         1、STRCPY必须返回char*         2、要有断言，对入参进行判断         3、copy循环体 判断参数？有必要吗？误人子弟啊！ 自己看看strcpy的实现吧！

VS有带文档，告诉你怎么用调试器。

引用 楼主 u013409439 的回复: 如图所示编译结果不一致？  另外问各位大神那个“单步调试”具体怎么做，按f10吗？当看不懂程序的时候，单步调试能有什么好处，有什么帮助呢？  这个代码有错误，各位看看哪里错误了，编译的结果没有复制成功。

F9下断点，F5调试运行，这个程序F10单步，鼠标移上去看变量内容

没有问题 F10       逐过程 F11       逐语句

F11 代码有bug，如果输入超过80个字符怎么办？


Question: （单片机C语言）设置wifi工作状态，外接电源则工作，仅接电池则不工作

来人呐~~~求助啊~~~


Question: 写一个程序，它从标准输入读入字符文件，输出所有字符数不超过10的行

输入时候的那个for循环就有问题了。 第一个for里面有个getchar，如果不是#号的话，那当前行的第一个字符已经被读了 所以第二个for循环中的getchar，是从当前行的第二个字符开始读的

fgets 一次读取一行.  (缓冲区大一些, 到小需要大于10,  同时注意\n等换行标记) 然后strlen计算长度是否小于10 循环前两步, 直到读取完成.

修改如下：  #include <stdio.h> #include <ctype.h> enum { maxline = 1024 }; char line[maxline][maxline]; int count[maxline]; int main() { 	int i, j, r; 	char c; 	//for (i = 0; i < maxline && (c = getchar()) != '#'; i++) 	for (i = 0; i < maxline && (c = getchar()) != '\n'; i++) 	{ 		line[i][0] = c; 		//for (j = 1; j < maxline - 2 && (c = getchar()) != '\n'; j++) 		//{ 		//	line[i][j] = c; 		//} 		for (j = 1; j < maxline - 2 && (line[i][j] = getchar()) != '\n'; j++); 	} 	r = i;   //r记录实际读入的行数 	//for (i = 0; i < maxline; i++) 	for (i = 0; i <= r; i++) 	{ 		count[i] = 0; 		for (j = 0; j < maxline - 2; j++) 		{ 			if (line[i][j] != '\n') count[i]++; 			else break; 		} 	} 	//for (i = 0; i < maxline && count[i] >= 1 && count[i] <= 10; i++) 	for (i = 0; i <= r && count[i] >= 1 && count[i] <= 10; i++) 	{ 		for (j = 0; j < count[i]; j++) 		{ 			printf("%c", line[i][j]); 		} 		printf("\n"); 	} 	return 0; }


Question: 关于字符运算有一些不懂的

1.由于头文件的存在 这里CHAR＿BIT编译时被直接替换为8 2.而且sizeof 的优先级高于 *   所以为了打字简便而sizeof不加打括号时  编译理解为先取长后乘法  而不是想象中的先数值类型转换再运算 然后对运算后的字符取长  总结如上 谢谢各位大大的帮助  vb 转c 有些地方会有vb老根 希望大大们助我一力 么么哒

printf("%d bits\n",  sizeof 2147483647*CHAR_BIT);            // 显示32 bits  printf("%d bits\n",  sizeof (-2147483647-1)*CHAR_BIT);     // 显示32 bits  printf("%d bits\n",  sizeof CHAR_BIT);                                 // 显示4 bits      printf("%d bits\n",  sizeof 1);                                                 // 显示4 bits printf("%d bits\n",  sizeof 1*CHAR_BIT);                              // 显示32 bits   首先要明明sizeof是运算符，且sizeof的运算符优先级要高于 * （乘法） 另外#define CHAR_BIT 8 以第五个为例 sizeof 1 * CHAR_BIT 实际就是(sizeof(1))*8 =32 sizeof(1) =4

理解sizeof操作符以及数据的默认类型。 sizeof Operator Yields the size of its operand with respect to the size of type char. The operand to sizeof can be one of the following: A type name. To use sizeof with a type name, the name must be enclosed in parentheses. An expression. When used with an expression, sizeof can be specified with or without the parentheses. The expression is not evaluated. 默认类型 整型->int 浮点型->double CHAR_BIT是一宏 = 8

4*8=32，小学生都懂吧

你把代码中所有的 CHAR_BIT 换成 8 就懂了 或者你可以把第三个printf 中的 sizeof 删掉


Question: C语言-结构体声明疑惑

没有问题。。

你是不是把控制台和windows程序搞混了.

C语言中变量的定义 必须在函数的开始部分，修改成如下代码就OK了 char *getMemory4(int memorySize) {     struct Teacher *pTmp = NULL;     char *cVar = NULL;        pTmp = (struct Teacher *)malloc(memorySize * sizeof(struct Teacher));                cVar = (char *)malloc(memorySize * sizeof(struct Teacher));           return cVar; }

char *cVar = NULL;  C语言能在中间定义?

char[]应该不知道你这个多大吧。

char name[]是什么意思

没有问题


Question: “统计英语字符个数”程序编译出现问题

【FROM CSDN】 调用： gets(buffer) //函数对输入长度不加以限制    //所以在vs中用gets会有警告信息This function or variable may be unsafe. gets_s(buffer,size)  //其中第二参数就是允许的输入长度     //这里的size是分配buffer-1的长度才正好，否则自动为'\0'分配空间的时候会溢出。

写错了，是gets_s(text[i], 80);

改为：gets_s(test[i], 80);


Question: 请教scanf_s("%S", ws, 10)和scanf_s("%S", ws[10]);的区别？

ws[10] = *(ws+10); 你有吗? 你有没有? 你没有吧?

Collapse AllExpand All      Code: All Code: Multiple Code: Visual Basic Code: C# Code: Visual C++ Code: J# Code: JScript   Visual Basic C# Visual C++ J# JScript Run-Time Library Reference  scanf_s, _scanf_s_l, wscanf_s, _wscanf_s_l  Example  See Also  Send Feedback     Read formatted data from the standard input stream. These are versions of scanf, _scanf_l, wscanf, _wscanf_l with security enhancements as described in Security Enhancements in the CRT.    int scanf_s(    const char *format [,       argument]...  ); int _scanf_s_l(    const char *format,    locale_t locale [,       argument]...  ); int wscanf_s(    const wchar_t *format [,       argument]...  ); int _wscanf_s_l(    const wchar_t *format,    locale_t locale [,       argument]...  );    Parameters format Format control string.  argument Optional arguments.  locale The locale to use.  Return Value Returns the number of fields successfully converted and assigned; the return value does not include fields that were read but not assigned. A return value of 0 indicates that no fields were assigned. The return value is EOF for an error or if the end-of-file character or the end-of-string character is encountered in the first attempt to read a character. If format is a NULL pointer, the invalid parameter handler is invoked, as described in Parameter Validation. If execution is allowed to continue, scanf_s and wscanf_s return EOF and set errno to EINVAL.  For information on these and other error codes, see _doserrno, errno, _sys_errlist, and _sys_nerr.  Remarks The scanf_s 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_s is a wide-character version of scanf_s; the format argument to wscanf_s is a wide-character string. wscanf_s and scanf_s behave identically identically if the stream is opened in ANSI mode. scanf_s doesn't currently support input from a UNICODE stream.  The versions of these functions with the _l suffix are identical except that they use the locale parameter passed in instead of the current thread locale.  Unlike scanf and wscanf, scanf_s and wscanf_s require the buffer size to be specified for all input parameters of type c, C, s, S, or [. The buffer size is passed as an additional parameter immediately following the pointer to the buffer or variable. For example, if reading a string, the buffer size for that string is passed as follows:  char s[10];  scanf("%9s", s, 10);  The buffer size includes the terminating null. A width specification field may be used to ensure that the token read in will fit into the buffer. If no width specification field is used, and the token read is too big to fit in the buffer, nothing will be written to that buffer.  Note:  The size parameter is of type unsigned, not size_t.    In the case of characters, one may read a single character as follows:  char c;  scanf("%c", &c, 1);  When reading multiple characters for non-null terminated strings, integers are used as the width specification and the buffer size.  char c[4];  scanf("%4c", &c, 4); // not null terminated  For more information, see scanf Width Specification.  TCHAR.H routine   _UNICODE & _MBCS not defined  _MBCS defined  _UNICODE defined   _tscanf_s  scanf_s  scanf_s  wscanf_s   _tscanf_s_l  _scanf_s_l  _scanf_s_l  _wscanf_s_l    For more information, see Format Specification Fields — scanf functions and wscanf Functions.   Requirements Routine  Required header   scanf_s, _scanf_s_l  <stdio.h>   wscanf_s, _wscanf_s_l  <stdio.h> or <wchar.h>    For additional compatibility information, see Compatibility in the Introduction.  Example   Copy Code  // crt_scanf_s.c // This program uses the scanf_s and wscanf_s functions // to read formatted input.    #include <stdio.h>  int main( void ) {    int      i,             result;    float    fp;    char     c,             s[81];    wchar_t  wc,             ws[81];     result = scanf_s( "%d %f %c %C %s %S", &i, &fp, &c, 1,                      &wc, 1, s, 80, ws, 80 );    printf( "The 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);    result = wscanf_s( L"%d %f %hc %lc %S %ls", &i, &fp, &c, 2,                       &wc, 1, s, 80, ws, 80 );    wprintf( L"The 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); }     Copy Code  71 98.6 h z Byte characters 36 92.3 y n Wide characters     Copy Code  The number of fields input is 6 The contents are: 71 98.599998 h z Byte characters The number of fields input is 6 The contents are: 36 92.300003 y n Wide characters    .NET Framework Equivalent System::Console::Read  System::Console::ReadLine  See also Parse methods, such as System::Double::Parse.  See Also Concepts Floating-Point Support Stream I/O Locale fscanf, _fscanf_l, fwscanf, _fwscanf_l printf, _printf_l, wprintf, _wprintf_l sprintf, _sprintf_l, swprintf, _swprintf_l, __swprintf_l sscanf, _sscanf_l, swscanf, _swscanf_l Send feedback on this topic to Microsoft.

char ws[10];//不行 wchar_t ws[10];//可以  %s  String, up to first white-space character (space, tab or newline). To read strings not delimited by space characters, use set of square brackets ([ ]), as discussed in scanf Width Specification.  When used with scanf functions, signifies single-byte character array; when used with wscanf functions, signifies wide-character array. In either case, character array must be large enough for input field plus terminating null character, which is automatically appended.   %S  Opposite-size character string, up to first white-space character (space, tab or newline). To read strings not delimited by space characters, use set of square brackets ([ ]), as discussed in scanf Width Specification.  When used with scanf functions, signifies wide-character array; when used with wscanf functions, signifies single-byte–character array. In either case, character array must be large enough for input field plus terminating null character, which is automatically appended.

本质区别在于： ws和ws[10]的区别：ws是char*，ws[10]是char，scanf需要传入地址，所以正确的是ws scanf_s()是vs下对scanf()的改进，scanf_s("%s", ws, 10);的意思是读入字符串到地址ws，最多读入10个字符


Question: 除了论坛，学校编程内网，我还可以在哪里找到关于c语言各式各样的问题。

数据结构，算法，学校里面有ACM网站吗？没有的话上网找一个开放的ACM刷题网页。不过这个太专业了，你可以上网找找C语言面试题做做。

仅仅懂C语法，是干不了什么的。你得接着学数据结构，网络，操作系统……


Question: 顺序查找 哨兵

第一个元素是哨兵的位置，所以20是无效元素

引用 5 楼 zhangxiangDavaid 的回复:[quote=引用 4 楼 qq_20242109 的回复:] [quote=引用 1 楼 zhangxiangDavaid 的回复:] 忽略作解释：  int main() { 	//以search_test的写法可知，第一个元素被当做哨兵处理，所以有效元素是3个，不是4个，故count=3; 	int list_data[] = { 20, 45, 77, 74 };  	//int count = 4; 	int count = 3; 	int key = 201; 	int val = seach_test(list_data, count, key); 	printf("key=%d,val=%d\n", key, val); 	key = 2; 	val = seach_test(list_data, count, key); 	printf("key=%d,val=%d\n", key, val); 	key = 77; 	val = seach_test(list_data, count, key); 	printf("key=%d,val=%d\n", key, val); 	return 0; } int seach_test(int *list_data, int count, int key) { 	int i = 0; 	list_data[0] = key;  //设置第一个元素，实质成为哨兵 	i = count; 	while (list_data[i] != key) { 		i--; 	} 	return i; } //key=201,val=2 //key=2,val=0 //key=77,val=2    假如key为20，返回值为0，跟key为201的返回值是一样的[/quote] 对，返回0就是表明查找失败[/quote] 20在数组中是存在的，返回0是20在数组中的下标，不是失败吧

引用 4 楼 qq_20242109 的回复:[quote=引用 1 楼 zhangxiangDavaid 的回复:] 忽略作解释：  int main() { 	//以search_test的写法可知，第一个元素被当做哨兵处理，所以有效元素是3个，不是4个，故count=3; 	int list_data[] = { 20, 45, 77, 74 };  	//int count = 4; 	int count = 3; 	int key = 201; 	int val = seach_test(list_data, count, key); 	printf("key=%d,val=%d\n", key, val); 	key = 2; 	val = seach_test(list_data, count, key); 	printf("key=%d,val=%d\n", key, val); 	key = 77; 	val = seach_test(list_data, count, key); 	printf("key=%d,val=%d\n", key, val); 	return 0; } int seach_test(int *list_data, int count, int key) { 	int i = 0; 	list_data[0] = key;  //设置第一个元素，实质成为哨兵 	i = count; 	while (list_data[i] != key) { 		i--; 	} 	return i; } //key=201,val=2 //key=2,val=0 //key=77,val=2    假如key为20，返回值为0，跟key为201的返回值是一样的[/quote] 对，返回0就是表明查找失败

引用 1 楼 zhangxiangDavaid 的回复:忽略作解释：  int main() { 	//以search_test的写法可知，第一个元素被当做哨兵处理，所以有效元素是3个，不是4个，故count=3; 	int list_data[] = { 20, 45, 77, 74 };  	//int count = 4; 	int count = 3; 	int key = 201; 	int val = seach_test(list_data, count, key); 	printf("key=%d,val=%d\n", key, val); 	key = 2; 	val = seach_test(list_data, count, key); 	printf("key=%d,val=%d\n", key, val); 	key = 77; 	val = seach_test(list_data, count, key); 	printf("key=%d,val=%d\n", key, val); 	return 0; } int seach_test(int *list_data, int count, int key) { 	int i = 0; 	list_data[0] = key;  //设置第一个元素，实质成为哨兵 	i = count; 	while (list_data[i] != key) { 		i--; 	} 	return i; } //key=201,val=2 //key=2,val=0 //key=77,val=2    假如key为20，返回值为0，跟key为201的返回值是一样的

略作解释


Question: c语言使用json格式替换数组合适吗

其实我的意思是只用sqlite即可，不需要额外的json。

引用 2 楼 ForestDB 的回复:嵌入式的话其实是可以用sqlite的。 不过json应该也不错。 现在使用的就是sqlite3， 从sqlite取值保存为json作为初始状态，然后和sqlite的值变化比较

嵌入式的话其实是可以用sqlite的。 不过json应该也不错。

可以用nosql的数据库，简单的leveldb，功能强大的mongodb啥的


Question: 关于linux下的malloc函数和windows下的不同

Linux是开源的。

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

你malloc分配了多少内存就用多少内存，越界肯定是错误的，至于错误的具体表现就跟C库的实现有关，各个C库会保证正确使用库函数的行为一致，但并不保证错误行为也一致。 那个free的错误是因为你越界多写了一个字节导致内存管理列表乱了造成的。

linux malloc函数的底层是brk，sbrk系统调用现的， windows是其他的系统调用、 linux下的malloc函数在该进程第一次申请内存的时候实际会像内存请求33页的大小（1页=4096字节）， 之后程序中再用到malloc的时候就可以直接在这33页中分配， 而不需要系统调用， 减少内核到用户态的切换， 提高效率。  windos也会有这样的一些底层维护， 只是不开源的话无从细说。  关于分配33页是ubuntu系统下的验证结果。


Question: 读取第一个非空白字符程序分析

第一段代码就差一个continue吗？那个continue可以不用管的，就像楼上说的，有没有都一样。  get_first函数的执行逻辑，先找到第一个空白字符，然后将该行一个字符一个字符的读完（就是读到\n） 因为只要第一个字符，所以除了第一个字符，后面的字符没用，就不需要任何操作了。

略作解释    while (isspace(ch))   //这个while就可以读到第一个非空白字符     {         ch = getchar();     }     while (getchar() != '\n')  //读完一整行，为下一次判断作准备     {         continue; //这个有没有都是一回事     }  引用 2 楼 yshj1182831071 的回复:首先，谢谢您的回答，还有一点不是很明白  while (getchar() != '\n')  //读完一整行，为下一次判断作准备     {         continue; //这个有没有都是一回事     } 这一句读取后不做任何操作吗？ 不用，读取位置已转到新的一行

@zhangxiangDavaid


Question: 关于SOCKET C语言编程

接收到的数据保存成文件打开后就正常，这说明传输是没问问题了。主要是这里有好几个问题没搞清： 1.这里不知道楼主是什么系统，用的什么编译环境。这里假设是Windows和VC吧、 2.发送端发送的是什么编码？按照你说是UTF-8，这没问题。我猜测你传输的可能是UTF-8编码的htm文件。 3.程序看到是乱码，是如何看的？是通过调试还是通过打印。如果你用的是VC，那么VC无论是调试还是打印都不支持UTF-8，只支持GBK（这么说其实不准确，可以粗浅这么认为）。如果网络数据本身是UTF-8，那么如果要在程序中输出，请转换一下编码后printf，用4楼的API就可以，也可以用开源库。 3.至于printf("中文")显示是乱码，取决于你承载这句话的源文件是什么编码。对于编译器来说只是输出的两个引号之间的东西，里面是什么就是什么。如果是VC，可能会做得多一些。如果原文件是用GB码保存的，输出一般没问题。如果源文件是用加了BOM头的UTF-8保存的，编译器其实会自动把UTF-8转码为本地码，也没问题。如果没有BOM头的UTF-8，这时候编译器无法识别UTF-8，就无法转码，那么可能就会有问题 4.你把接收到了内容保存成文件，打开又没乱码，这说明你网络编程没问题。因为只要是二进制传输，网络这里其实就是原样拷贝而已，原来是啥就是啥。打开的时候，你的记事本或者文本工具会自动识别，自认没乱码了。

引用 楼主 qq_25235869 的回复:自己学教程用SOCKET 写接受网页源码的一个程序，然后及就是recv（）函数接收的源码全都是乱码，我已经按网上说的确定了 都是UFT-8的编码  所以自认为不是编码的问题  然后就不知道哪里出问题了 求网友指点 指点，ps：只有中文的字符才出现了问题，然后接收到的字符保存为html文件 代开文字一切正常  ConvertUtf8ToGBK(CString& strUtf8)  { 	int len=MultiByteToWideChar(CP_UTF8, 0, (LPCTSTR)strUtf8, -1, NULL,0); 	unsigned short * wszGBK = new unsigned short[len+1]; 	memset(wszGBK, 0, len * 2 + 2); 	MultiByteToWideChar(CP_UTF8, 0, (LPCTSTR)strUtf8, -1, wszGBK, len); 	 	len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL); 	char *szGBK=new char[len + 1]; 	memset(szGBK, 0, len + 1); 	WideCharToMultiByte (CP_ACP, 0, wszGBK, -1, szGBK, len, NULL,NULL);	 	strUtf8 = szGBK; 	delete[] szGBK; 	delete[] wszGBK; } 中文用这个函数转换一下就可以了

socket你设置是以stream形式的吧。那么就是字节流，需要相同的编码形式

可是为什么 当我的VS输出中文的时候（中文不是来自网页就是简单的printf("中文");）显示乱码，然后当我设置了UFT-8就OK了呢？？

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

控制台输出UTF-8编码的字符串这要系统支持吧。。比如中文版Windows默认一般默认是GB系列编码 一定要输出的话转换成GBK之类的再输出吧。。或者至少转换成UCS-2编码再输出吧


Question: 【求助】关于从txt中读取数组的问题

引用 1 楼 zxhuser-5 的回复:/**************************************  *FILE    :D:\c\main.c  *PROJECT :NULL  *AUTHOR  :user-5  *CREATED :2015-5-13 下午 09:41:42  *TEXT    :NULL  *EMAIL   :gtsoft_wk@foxmail.com  *CODE    :https://github.com/user-5 ***************************************/  #include <stdio.h>  typedef struct node { 	int num[5]; }DATA;  int main() { 	int i; 	int j; 	int len; 	char ch; 	FILE* fpin; 	DATA num[100]; 	fpin=fopen("input.txt","r"); 	 	if(fpin==NULL)return 0; 	 	for(len=0;!feof(fpin);len++) 	{ 		fscanf(fpin,"%d",&num[len].num[0]); 		for(i=1;!feof(fpin);i++) 		{ 			if((ch=fgetc(fpin))=='\n')break; 			if(feof(fpin))break; 			fscanf(fpin,"%d",&num[len].num[i]); 		} 		if(i!=5)len--; 	} 	 	for(i=0;i<len;i++) 	{ 		for(j=0;j<5;j++) 			printf("%d ",num[i].num[j]); 		printf("\n"); 	} 	 	return 0; } 抱歉刚才工程建错了，运行没问题，但还是想要个注释版看看，代码有些看不懂

引用 1 楼 zxhuser-5 的回复:/**************************************  *FILE    :D:\c\main.c  *PROJECT :NULL  *AUTHOR  :user-5  *CREATED :2015-5-13 下午 09:41:42  *TEXT    :NULL  *EMAIL   :gtsoft_wk@foxmail.com  *CODE    :https://github.com/user-5 ***************************************/  #include <stdio.h>  typedef struct node { 	int num[5]; }DATA;  int main() { 	int i; 	int j; 	int len; 	char ch; 	FILE* fpin; 	DATA num[100]; 	fpin=fopen("input.txt","r"); 	 	if(fpin==NULL)return 0; 	 	for(len=0;!feof(fpin);len++) 	{ 		fscanf(fpin,"%d",&num[len].num[0]); 		for(i=1;!feof(fpin);i++) 		{ 			if((ch=fgetc(fpin))=='\n')break; 			if(feof(fpin))break; 			fscanf(fpin,"%d",&num[len].num[i]); 		} 		if(i!=5)len--; 	} 	 	for(i=0;i<len;i++) 	{ 		for(j=0;j<5;j++) 			printf("%d ",num[i].num[j]); 		printf("\n"); 	} 	 	return 0; } 看不太懂啊，能否来个注释版？而且代码运行出错了啊

只能当例子。 # include <stdio.h> # include <string.h> # include <ctype.h>  int number_in_line(char s[1000], int a[100]) {     int n = 0;     int i = 0;     while ((sscanf(s + i, "%d", a + n)) == 1 && n < 100)     {         while (isspace(s[i]))             i++;         while (!isspace(s[i]))             i++;          n++;     }     return n; }  void show(int a[100], int n) {     int i;     for (i = 0; i < 100 && i < n; i++)         printf("%d\n", a[i]); }  int main() {     char line[1000];     int a[100];     int n;      while (1)     {         strcpy(line, "");          if (!fgets(line, 1000, stdin))             break;          n = number_in_line(line, a);          if (n == 5)             show(a, 5);     }      return 0; }

引用 6 楼 qq_15683855 的回复:[quote=引用 5 楼 zhao4zhong1 的回复:] 第5行 static d[MAXN][5]; 应改为 static int d[MAXN][5]; 赵老师，我稍微明白点了，但是如果数组列数比5列多很多呢比如有128列，就不能用这种方式吧 if (5==sscanf("%d%d%d%d%d",&d[i][0],&d[i][1],&d[i][2],&d[i][3],&d[i][4])) i++; 又没有什么好的解决方法呢？[/quote] 活人永远不会被尿憋死！ 仅供参考：#include <stdio.h> char s[]="123 ab 4"; char *p; int v,n,k; void main() {     p=s;     while (1) {         k=sscanf(p,"%d%n",&v,&n);         printf("k,v,n=%d,%d,%d\n",k,v,n);         if (1==k) {             p+=n;         } else if (0==k) {             printf("skip char[%c]\n",p[0]);             p++;         } else {//EOF==k             break;         }     }     printf("End.\n"); } //k,v,n=1,123,3 //k,v,n=0,123,3 //skip char[ ] //k,v,n=0,123,3 //skip char[a] //k,v,n=0,123,3 //skip char[b] //k,v,n=1,4,2 //k,v,n=-1,4,2 //End.

一个个拆 别想那么复杂

如果有的行超过5个数据，可以这样：  #include <ctype.h> #define LINE 100 FILE *f; int data[LINE][5]; int i, j, flag, l, n; char buf[256];   //一行255个字符够吗？ int count_int()  //获取一行中的数字个数 { 	n = strlen(buf); 	if ('\n' == buf[0]) return 0;  //空行 	buf[n - 1] = '\0';   //去回车符 	j = 0; 	flag = 0; 	for (i = 0; i < n - 1; i++) 	{ 		if (isdigit(buf[i])) flag = 1; 		else 		{ 			if (1 == flag) j++; 			flag = 0; 		} 	} 	if (isdigit(buf[n - 2])) j++; 	return j; } int main(void) { 	if (NULL == (f = fopen("1.txt", "r"))) 	{ 		fprintf(stderr, "Can not open file : 1.txt\n"); 		return 2; 	} 	l = 0; 	while (1) 	{ 		if (l == LINE) break; 		if (NULL == fgets(buf, 256, f)) break; 		if (5 != (count_int())) continue; 		sscanf(buf, "%d%d%d%d%d", data[l] + 0, data[l] + 1, data[l] + 2, data[l] + 3, data[l] + 4); 		l++; 	} 	for (i = 0; i < l; i++) printf("%d %d %d %d %d\n", data[i][0], data[i][1], data[i][2], data[i][3], data[i][4]); 	return 0; } //1 3 34 4 98 //13 21 213 234 45 //1 2 3 4 5 //12 34 56 78 9 //2 3 4 5 6 //9 8 7 6 5

引用 5 楼 zhao4zhong1 的回复:第5行 static d[MAXN][5]; 应改为 static int d[MAXN][5]; 赵老师，我稍微明白点了，但是如果数组列数比5列多很多呢比如有128列，就不能用这种方式吧 if (5==sscanf("%d%d%d%d%d",&d[i][0],&d[i][1],&d[i][2],&d[i][3],&d[i][4])) i++; 又没有什么好的解决方法呢？

作为一个C程序员，对  scanf,sscanf,fscanf  printf,sprintf,fprintf 这类函数的用法，还是要做到“拳不离手，曲不离口”的。 #include <stdio.h> #define MAXN 100 int main() {     FILE* f;     static d[MAXN][5];     char ln[100];     int i,n,j;      f=fopen("input.txt","r");     if (f==NULL) return 1;      i=0;     while (1) {         if (NULL==fgets(ln,100,f)) break;         if (5==sscanf("%d%d%d%d%d",&d[i][0],&d[i][1],&d[i][2],&d[i][3],&d[i][4])) i++;         if (i>=MAXN) break;     }     fclose(f);     n=i;     for (i=0;i<n;i++) {         for(j=0;j<5;j++) {             printf("%d ",d[i][j]);         }         printf("\n");     }          return 0; }


Question: extern 声明对于DLL要输出程序变量和函数是必要的吗

如果只是dll导出函数或者类,用__declspec(dllexport) 就可以了,当然用的那边还的__declspec(dllimport) ,如果是静态库之间的调用用extern就可以,当然c++调用c的要用extern "C"

dll 导出函数名的那些事 关键字：　VC++ 　DLL  导出函数　 经常使用VC6的Dependency查看DLL导出函数的名字，会发现有DLL导出函数的名字有时大不相同，导致不同的原因大多是和编译DLL时候指定DLL导出函数的界定符有关系。 VC++支持两种语言：即C/C++，这也是造成DLL导出函数差异的根源 我们用VS2008新建个DLL工程，工程名为"TestDLL" 把默认的源文件后缀 .CPP改为.C（C文件） 输入测试代码如下： 01 int _stdcall MyFunction(int iVariant) 02 { 03 return 0; 04 } 为了导出上面这个函数，我们有以下几个方法： 1. 使用传统的模块定义文件 (.def) 新建一个 后缀为.def的文本文件(这里建一个TestDll.Def)，文件内容为： LIBRARY TestDll EXPORTS MyFunction 在 Link 时指定输入依赖文件：/DEF:"TestDll.Def" 2. Visual C++ 提供的方便方法 在01行的int 前加入 __declspec(dllexport) 关键字 通过以上两种方法，我们就可以导出MyFunction函数。 我们用Dependency查看导出的函数： 第一种方法导出的函数为： MyFunction 第二种方法导出的函数为： _MyFunction@4 __stdcall会使导出函数名字前面加一个下划线，后面加一个@再加上参数的字节数，比如_MyFunction@4的参数（int iVariant）就是4个字节 __fastcall与 __stdcall类似，不过前面没有下划线，而是一个@，比如@MyFunction@4 __cdecl则是始函数名。 小结：如果要导出C文件中的函数，并且不让编译器改动函数名，用def文件导出函数。 下面我们来看一下C++文件 我们用VS2008新建个DLL工程，工程名为"TestDLL" 默认的源文件后缀为 .CPP （即C++文件）。 输入测试代码如下： 01 int _stdcall MyFunction(int iVariant) 02 { 03 return 0; 04 } 为了导出上面这个函数，我们有以下几个方法： 3. 使用传统的模块定义文件 (.def) 新建一个 后缀为.def的文本文件(这里建一个TestDll.Def)，文件内容为： LIBRARY TestDll EXPORTS MyFunction 在 Link 时指定输入依赖文件：/DEF:"TestDll.Def" 4. Visual C++ 提供的方便方法 在01行的int 前加入 __declspec(dllexport) 关键字 通过以上两种方法，我们就可以导出MyFunction函数。 我们用Dependency查看导出的函数： 第一种方法导出的函数为： MyFunction 第二种方法导出的函数为： ?MyFunction@@YGHH@Z 可以看到 第二种方法得到的 导出函数名 并不是我们想要的，如果在exe中用显示方法（LoadLibrary、GetProcAddress）调用 MyFunction 肯定会失败。 但是用引入库(*.LIB)的方式调用，则编译器自动处理转换函数名，所以总是没有问题。 解决这个问题的方法是： 用VC 提供的预处理指示符 "#pragma" 来指定链接选项。 如下： #pragma comment(linker, "/EXPORT:MyFunction=?MyFunction@@YGHH@Z") 这时，就会发现导出的函数名字表中已经有了我们想要的MyFunction。但我们发现原来的那个 ?MyFunction@@YGHH@Z 函数还在，这时就可以把 __declspec() 修饰去掉，只需要 pragma 指令即可。 而且还可以使如下形式： #pragma comment(linker, "/EXPORT:MyFunction=_MyFunction@4,PRIVATE") PRIVATE 的作用与其在 def 文件中的作用一样。更多的#pragram请查看MSDN。 小结：如果要导出C++文件中的函数，并且不让编译器改动函数名，用def文件导出函数。 同时可以用#pragma指令（C 中也可以用）。 总结： C++编译器在生成DLL时，会对导出的函数进行名字改编，并且不同的编译器使用的改编规则不一样，因此改编后的名字也是不同的（一般涉及到C++ 中的重载等）。 如果利用不同编译器分别生成DLL和访问DLL的exe程序，后者在访问该DLL的导出函数时就会出现问题。如上例中函数MyFunction在C++编译器改编后的名字是?MyFunction@@YGHH@Z。我们希望编译后的名字不发生改变，这里有几种方法。 第一种方法是通过一个称为模块定义文件DEF来解决。 LIBRARY TestDll EXPORTS MyFunction LIBRARY 用来指定动态链接库内部名称。该名称与生成的动态链接库名一定要匹配，这句代码不是必须的。 EXPORTS说明了DLL将要导出的函数，以及为这些导出函数指定的符号名。 第二种是定义导出函数时加上限定符：extern "C" 如：#define DLLEXPORT_API extern "C" _declspec(dllexport) 但extern "C"只解决了C和C++语方之间调用的问题(extern "C" 是告诉编译器，让它按C的方式编译)，它只能用于导出全局函数这种情况 而不能导出一个类的成员函数。 同时如果导出函数的调用约定发生改变，即使使用extern "C"，编译后的函数名还是会发生改变。例如上面我们加入_stdcall关键字说明调用约定（标准调用约定，也就是WINAPI调用约定）。 #define DLLEXPORT_API extern "C" _declspec(dllexport) 01 DLLEXPORT_API int _stdcall MyFunction(int iVariant) 02 { 03 return 0; 04 } 编译后函数名MyFunction改编成了_MyFunction@4 通过第一种方法模块定义文件的方式DLL编译后导出函数名不会发生改变。 DLL(动态库)导出函数名乱码含义 C++编译时函数名修饰约定规则：   __stdcall调用约定：   1、以"?"标识函数名的开始，后跟函数名；    2、函数名后面以"@@YG"标识参数表的开始，后跟参数表；    3、参数表以代号表示：   X--void   D--char   E--unsigned char   F--short   H--int   I--unsigned int   J--long   K--unsigned long   M--float   N--double   _N--bool   ....   PA--表示指针，后面的代号表明指针类型，如果相同类型的指针连续出现，以"0"代替，一个"0"代表一次重复；   4、参数表的第一项为该函数的返回值类型，其后依次为参数的数据类型,指针标识在其所指数据类型前；    5、参数表后以"@Z"标识整个名字的结束，如果该函数无参数，则以"Z"标识结束。   其格式为"?functionname@@YG*****@Z"或"?functionname@@YG*XZ"，例如                       int Test1(char *var1, unsigned long)-----"?Test1@@YGHPADK@Z"                      void Test2()-----"?Test2@@YGXXZ"    __cdecl调用约定：   规则同上面的_stdcall调用约定，只是参数表的开始标识由上面的"@@YG"变为"@@YA"。   __fastcall调用约定：   规则同上面的_stdcall调用约定，只是参数表的开始标识由上面的"@@YG"变为"@@YI"。   如果要用DEF文件输出一个"C++"类，则把要输出的数据和成员的修饰名都写入.def模块定义文件   所以...   通过def文件来导出C++类是很麻烦的,并且这个修饰名是不可避免的


Question: sizeof （int）*p

编译器是这样做的： p = 2; apple = p << 2 （相当于p*sizeof(int)）

这个结果是计算int型所占内存数再乘以p。

引用 2 楼 user-11 的回复: 没看过 c专家编程 但如果真像你所说的 apple=sizeof (int) *p; 可以从这个表达式YY出 p 指针....这书也真是太能扯了... size(int) == 4 p  == 2 apple = 4 * 2 == 8 就特么一个 4 * 2 这能扯出个 *p 指针来。。我也醉了+1,lz该吃药了

引用 6 楼 zhao4zhong1 的回复:《牛肉干》 C语言上机课，某女同学偷偷吃起牛肉干。 有一粒牛肉干掉到了键盘上，卡在7和8键之间。 女同学就在键盘上抠啊、抠啊、抠啊…… 程序里一行代码变成这个样子： int *pa=&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&a; 后来的结局是 ————程序顺利通过编译，运行结果正确！ 赵四老师一直如此机智。

sizeof （int *） p 语法错误

不就是不规范的编码习惯造成的误解么？良好的编码习惯中，二元运算符前后要加空格的 apple=sizeof(int) * p; 如果是强制类型转换，必须用括号在sizeof后面也吧P扩上才行

sizeof(int) * p  优先级还是要管的吧. sizeof是一个编译期就要计算的东西. 肯定是括号与sizeof永远在一起的.  它类似一个函数. 那个"专家"把它分开, 也是奇葩.

首先那本书这个级别的吐槽没意思。 其次，很多时候加个括号即可。

重点不在此。  引用 4 楼 sholber 的回复:[quote=引用 3 楼 super_admi 的回复:] 从前有个人，叫曹操，生了个儿子，叫曹植，曹植被他兄弟杀了，埋在地里，长出了一根葫芦藤，结出七个葫芦，葫芦成熟后，从中蹦出七个葫芦娃，葫芦娃碰到一个蛇妖，大战之后，葫芦娃化作大山，将蛇妖镇压，但有一个叫愚公的人很不爽这座山，所以天天和家人一起在这里挖山，挖了很久，惊动了天神，天神派人将山背走了。  长葫芦藤的过程不够形象，应该是“酷哧酷哧长出一根藤来”。[/quote]

引用 3 楼 super_admi 的回复:从前有个人，叫曹操，生了个儿子，叫曹植，曹植被他兄弟杀了，埋在地里，长出了一根葫芦藤，结出七个葫芦，葫芦成熟后，从中蹦出七个葫芦娃，葫芦娃碰到一个蛇妖，大战之后，葫芦娃化作大山，将蛇妖镇压，但有一个叫愚公的人很不爽这座山，所以天天和家人一起在这里挖山，挖了很久，惊动了天神，天神派人将山背走了。  长葫芦藤的过程不够形象，应该是“酷哧酷哧长出一根藤来”。

劝你最科学的方法是愉快的使用的万能的搜索引擎了解一下sizeof的功能和语法。别的都是瞎耽误工夫。


int dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};  int check(int x,int y) { 	if(x>=0 && y>=0 && x<n && y<m) 		return 1; 	return 0; }  void dfs(int x, int y, int step) { 	int temp; 	int dx,dy;  	if(flag == true || x==atx && y==aty && step==0) 	{ 		flag = true; 		return; 	}  	temp=abs(x-atx)+abs(y-aty)+step;  	if(temp%2!=0)return; 	map[x][y] = 'X'; 	for(int i=0; i<4; i++) 	{ 		dx = x+dir[i][0]; 		dy = y+dir[i][1]; 		if(check(dx,dy) && map[dx][dy]!='X') 		{ 			dfs(dx,dy,step-1); 		} 	} 	map[x][y] = '.'; }

引用 6 楼 user-1 的回复:不仅是返回的问题 map[-1][y]这个会直接给你Runtime error的。 的确是栈溢出了，可我看网上的那些AC了的答案都是这样写的。小弟刚想了很久也试了一下 还是不知道该怎么写，希望前辈提醒一下具体该怎么做。 还有我又想到一个问题，就是我的程序刚开始在while scanf 后面不用加个getchar()吃回车么？ 小弟感激不尽！

引用 5 楼 qq_23908539 的回复:[quote=引用 4 楼 user-1 的回复:]如果当前x=0 if(map[x-1][y]!='X') map[x-1][y]不就数组越界了吗？ 对啊，所以当把x-1也就是-1作为新的参数传进数组的时候会有直接因为通不过 if(x<0||y<0||x>=n||y>=m)语句而被 return了[/quote]  不仅是返回的问题 map[-1][y]这个会直接给你Runtime error的。

引用 4 楼 user-1 的回复:如果当前x=0 if(map[x-1][y]!='X') map[x-1][y]不就数组越界了吗？ 对啊，所以当把x-1也就是-1作为新的参数传进数组的时候会有直接因为通不过 if(x<0||y<0||x>=n||y>=m)语句而被 return了

引用 2 楼 qq_23908539 的回复:也就是说奇偶剪枝的唯一作用就是在一开的时候判断下能否奇偶是否对等，而在后面的步骤中就没有用了？ 可以这么说。   引用 3 楼 qq_23908539 的回复:有判断啊，当刷新dfs参数的时候，也就是一进入dfs函数就会有个if语句来看他们是否出界。 如果当前x=0 if(map[x-1][y]!='X') map[x-1][y]不就数组越界了吗？

引用 1 楼 user-1 的回复:这里面你没有对x+1,x-1,y-1,y+1其范围是否还在[0,N),[0,m)进行判断。这个有可能造成数组越界 有判断啊，当刷新dfs参数的时候，也就是一进入dfs函数就会有个if语句来看他们是否出界。

引用 1 楼 user-1 的回复:奇偶剪枝的作用，当门在T秒开时，假设T为奇数，abs(x-atx)+abs(y-aty)的值为偶数(或者是T为偶数,另一个结果为奇数)。此时无论怎么走都不可能走出去的(因为此时到门的时间一定是偶数，具体要什么数学证明我也搞不懂)，不用再进行搜索，直接可以判断无法出去。速度不是很快吗？ 也就是说奇偶剪枝的唯一作用就是在一开的时候判断下能否奇偶是否对等，而在后面的步骤中就没有用了？

奇偶剪枝的作用，当门在T秒开时，假设T为奇数，abs(x-atx)+abs(y-aty)的值为偶数(或者是T为偶数,另一个结果为奇数)。此时无论怎么走都不可能走出去的(因为此时到门的时间一定是偶数，具体要什么数学证明我也搞不懂)，不用再进行搜索，直接可以判断无法出去。速度不是很快吗？   引用 楼主 qq_23908539 的回复:问题一：我的代码不知道哪里出错了，自己举一些例子总是过不了，更不用说AC了，请教大神们看看哪里有问题。  if(map[x+1][y]!='X'){         bfs(x+1,y,step-1);         if(flag)return;     }     if(map[x-1][y]!='X'){         bfs(x-1,y,step-1);         if(flag)return;     }     if(map[x][y+1]!='X'){         bfs(x,y+1,step-1);         if(flag)return;     }     if(map[x][y-1]!='X'){         bfs(x,y-1,step-1);         if(flag)return;     } map[x+1] [y],map[x-1][y], map[x][y-1],map[x][y+1]，这里面你没有对x+1,x-1,y-1,y+1其范围是否还在[0,N),[0,m)进行判断。这个有可能造成数组越界


Question: Union如何让成员尾部对齐?

仅供参考：#include <stdio.h> #define field_offset(s,f) (int)(&(((struct s *)(0))->f)) struct AD  { int a; char b[13]; double c;}; #pragma pack(push) #pragma pack(1) struct A1  { int a; char b[13]; double c;}; #pragma pack(2) struct A2  { int a; char b[13]; double c;}; #pragma pack(4) struct A4  { int a; char b[13]; double c;}; #pragma pack(8) struct A8  { int a; char b[13]; double c;}; #pragma pack(16) struct A16 { int a; char b[13]; double c;}; #pragma pack(pop) int main() {     printf("AD.a %d\n",field_offset(AD,a));     printf("AD.b %d\n",field_offset(AD,b));     printf("AD.c %d\n",field_offset(AD,c));     printf("\n");     printf("A1.a %d\n",field_offset(A1,a));     printf("A1.b %d\n",field_offset(A1,b));     printf("A1.c %d\n",field_offset(A1,c));     printf("\n");     printf("A2.a %d\n",field_offset(A2,a));     printf("A2.b %d\n",field_offset(A2,b));     printf("A2.c %d\n",field_offset(A2,c));     printf("\n");     printf("A4.a %d\n",field_offset(A4,a));     printf("A4.b %d\n",field_offset(A4,b));     printf("A4.c %d\n",field_offset(A4,c));     printf("\n");     printf("A8.a %d\n",field_offset(A8,a));     printf("A8.b %d\n",field_offset(A8,b));     printf("A8.c %d\n",field_offset(A8,c));     printf("\n");     printf("A16.a %d\n",field_offset(A16,a));     printf("A16.b %d\n",field_offset(A16,b));     printf("A16.c %d\n",field_offset(A16,c));     printf("\n");     return 0; } //AD.a 0 //AD.b 4 //AD.c 24 // //A1.a 0 //A1.b 4 //A1.c 17 // //A2.a 0 //A2.b 4 //A2.c 18 // //A4.a 0 //A4.b 4 //A4.c 20 // //A8.a 0 //A8.b 4 //A8.c 24 // //A16.a 0 //A16.b 4 //A16.c 24 // //

引用 10 楼 vnvlyp 的回复:尾部对齐这是个什么需求。。能不能讲一讲我倒觉得很有意思 这在大部分机器上（little-endian）岂不是高位对齐 主要是处理通信协议,  一个通信数据流,一个字节一个字节的接收的,发送方是先发头再发尾的,  可能有多个格式(struct)的数据,  所以是想把这个多个格式组成一个尾部对齐的Union, 然后每收到一个字节就向前推移动一个字节, 并检查各struct标记校验

编译器不是会自动优化的吗

typedef long int T4;        /*根据具体的环境自行定义*/ typedef long long int T8;   /*根据具体的环境自行定义*/  /*静态断言_Static_assert需要你的编译器支持C11，当然也可以不用这一行*/ _Static_assert (sizeof (T8) == 8 && sizeof (T4) == 4, "ERROR DATA TYPE.");  union u {     T8 b8;     struct {T4 t, b4;};/*匿名结构的成员直接成为联合的成员，下同*/     struct {char c [sizeof (T8) - 1]; char b1;}; } __attribute__ ((packed));/*packed来自编译器提供的特性*/  int main (void) {     union u u;     u.b8 = 0x42000000FFFFFFFF;     /* Some use of u */     u.b1 = 'x';     /* Some use of u */     u.b4 = 8;     /* Some use of u */ }

哦。。。b4 也要偏位。。。 一样  套个 struct

再套个 struct 填位   #include <stdio.h> #include <math.h>  union u1 { 	long b4; 	long long b8; 	struct { 		char _t[7]; 		char b1; 	}; }  int main(int argc, char *argv[]) { 	union u1 *p = NULL; 	printf("%x %x", p, &p->b1); // 0   7 }

# include <stdio.h>  int main (void) {     union u     {         long long b8;         struct {long c; long b4};         struct {char b [7]; char b1;};     } __attribute__ ((packed));      union u u;     u.b8 = 0x42000000FFFFFFFF;     printf ("%ld\n", u.b4);     printf ("%c", u.b1); }

因为long long和long对于不同的实现来说大小也不同，而且，如何使一个结构内部无填充，不同的实现也有不同的方法，所以，以下代码仅为示例，抛砖引玉，没有通用性： union u {      long long b8;      struct {long pad1; long b4};      struct {char pad2 [7]; char b1;};  } __attribute__ ((packed));

我能想到的workaround： union u1 {   long b4[2];   long long b8;   char b1[8]; }; b4[1] b1[7] 应该是你想要的。

引用 1 楼 sholber 的回复:不明白你在说什么。 union u {long b4; long long b8; char b1;} u; 你的意思是，假定sizeof (long long) == 8；sizeof (long) == 4，u起始的线性地址是0x00000020，那么： b4的线性地址是0x00000024；b8的线性地址是0x00000020而b1的线性地址是0x00000027吗？ 如果是这种要求，不可能办到，否则C标准就得大面积修改了。 对,我就是想这样,正常情况各成员都是0x00000020开始,但现在是想倒过来放 地址                         成员 0x00000020:        ------------------------------------------------------------------------------------------------------------------ 0x00000021:        ↑ 0x00000022:        || 0x00000023:       b8 0x00000024:        占8个字节          ------------                0x00000025:        ||                              ↑ 0x00000026:        ↓                            b4占4个字节 0x00000027:        ________________↓___________________ b1占一个字节______________________


Question: 中序遍历线索二叉树添加头结点时，头结点总是指向不对，，，，，

用递归解决问题， 再说你这个看起来就不像是中序遍历 	//树节点 	struct node 	{ 		int num; 		struct node * p_left; 		struct node * p_right; 	}; //中序遍历二叉树 void mTraverse(const struct node * tree) { 	if(tree == NULL) 		return; 	if(!tree->p_left && !tree->p_right) 	{ 		printf("%d ",tree->num); 		return; 	} 	if(tree->p_left) 	{ 		mTraverse(tree->p_left); 	} 	printf("%d ", tree->num); 	if(tree->p_right) 	{ 		mTraverse(tree->p_right); 	} }


Question: opencv编译出错，以下几个错误不知如何解决，我是新手

项目、属性、链接器、常规、附加库目录：填写附加依赖库所在目录 分号间隔多项 项目、属性、链接器、输入、附加依赖项：填写附加依赖库的名字.lib 空格或分号间隔多项

这是没配置好造成的，照着下面重新配置一遍， release版本和debug版本都要重新配置， 因为在配置 附加依赖项时候，  opencv_calib3d240d.lib  有d的表示debug版本 opencv_calib3d240.lib   release版本 http://www.cnblogs.com/freedomshe/archive/2012/04/25/2470540.html  使用静态库的原则就是， 让编译器能找到静态库放在那里， 以及包含的头文件。


Question: 这个宏的含义

结构体或类成员的偏移量

这个不一定地结构， 也可以是类 c、c++ 可以无耻的把0转换成 类/结构 指针， 再计算出成员变量的偏移量。 &得到的结果就是偏移量。

结构成员在结构中的偏移

获取结构TYPE的成员变量MEMBER在结构中的偏移量，编译时就能计算出

offsetof( type,  member-designator)  which expands to an integral constant expression that has type size_t,  the value of which is the offset in bytes, to the structure member (designated by member-designator ), from the beginning of its structure (designated by type ).


Question: 关于const字符的c语言程序疑问

const int *a,a是指针变量，*a是常量，不能赋值

第二个改成 int* const a.   原理：  const & 指针  　　类型声明中const用来修饰一个常量，有如下两种写法，那么，请问，下面分别用const限定不可变的内容是什么?  　　1)、const在前面  　　const int nValue； //nValue是const  　　const char *pContent; //*pContent是const, pContent可变  　　const (char *) pContent;//pContent是const,*pContent可变  　　char* const pContent; //pContent是const,*pContent可变  　　const char* const pContent; //pContent和*pContent都是const  　　2)、const在后面，与上面的声明对等  　　int const nValue； // nValue是const  　　char const * pContent;// *pContent是const, pContent可变  　　(char *) const pContent;//pContent是const,*pContent可变  　　char* const pContent;// pContent是const,*pContent可变  　　char const* const pContent;// pContent和*pContent都是const  　　答案与分析：  　　const和指针一起使用是C语言中一个很常见的困惑之处，在实际开发中，特别是在看别人代码的时候，常常会因为这样而不好判断作者的意图，下面讲一下我的判断原则：  　　当const所在代码段中不包含括号时，沿着*号划一条线，如果const位于*的左侧，则const就是用来修饰指针所指向的变量，即指针指向为常量；如果const位于*的右侧，const就是修饰指针本身，即指针本身是常量。你可以根据这个规则来看上面声明的实际意义，相信定会一目了然。  　　另外，需要注意：对于const (char *) ; 因为char *是一个整体，相当于一个类型(如 char)，因此，这时限定指针是const。  　　一个简单的判断方法：指针运算符*，是从右到左，那么如：char const * pContent，可以理解为char const (* pContent)，即* pContent为const，而pContent则是可变的。

constt的使用 http://blog.csdn.net/zhangxiangdavaid/article/details/38082159

const int * a    内容常量 int* const a.    指针常量

第一个 const int *a是说*a为常量，不能给*a赋值，但可给a赋值，例如：*a=4；error     a=&c；right int   * const  a；则是a不可赋值，*a可以 例如 1.#include<stdio.h> main() {  const int *a ; int c=3; a=&c;无警告//*a=4;错误 } 2. #include<stdio.h> main() { 	int b=4,c=3; 	int  *const a=&c ;//要初始化，不然会出现野指针 	*a=4;//正确a=&b; 错误 }


Question: 初学链表 就出现这

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

呵呵，书上狠多也是错的，很正常，遇见错误，就问一下周围的高手，或者查查其他相关资料就好了

引用 4 楼 zhangxiangDavaid 的回复:你用的是struct student; 可在很多地方你写成了struct Student; 改过来即可。见笑了啊

好了 我已经知道了 是课本太坑了 自己脑子又不好使 见笑了

很简单的链表入手而已

链表有什么好学的，看看故事会，快活吃酒要紧。

#include<stdio.h> #include<stdlib.h> struct student { 	char cName[20]; 	int iNumber; 	struct student *next; };  int iCount; struct Student *create() { 	struct Student *pHead=NULL; 	struct Student *pEnd,*pNew; 	iCount=0; 	pEnd=pNew=(struct Student *)malloc(sizeof(struct student)); 	scanf("%s",pNew->cName); 	scanf("%d",&pNew->iNumber); 	while (pNew->iNumber!=0) 	{  	iCount++; 	if (iCount==1) 	{ 		pNew->next=pHead; 		pEnd=pNew; 		pHead=pNew; 	} 	else 	{ 		pNew->next=NULL; 		pEnd->next=pNew; 		pEnd=pNew; 	} 	pNew=(struct Student *)malloc(sizeof(struct student)); 	scanf("%s",pNew->cName); 	scanf("%d",&pNew->iNumber); 	} 	free(pNew); 	return pHead; } void print(struct Student *pHead) { 	struct Student *pTemp; 	int iIndex=1; 	printf("************%d*************\n",iCount); 	pTemp=pHead; 	while (pTemp!=NULL) 	{ 		printf("%d:\n",iIndex); 		printf("%s",pTemp->cName); 		printf("%d",&pTemp->iNumber); 		pTemp=pTemp->next; 		iIndex++; 	} }  int main() { 	struct Student *pHead; 	pHead=create(); 	print(pHead); 	return 0; }


Question: 为什么有的打印了，有的没有打印？

引用 5 楼 zhao4zhong1 的回复:在每个不带末尾\n的fprintf(stderr,"...");后面加 fflush(stderr);  不是这个原因，我加了fflush，试了下，还是没有。

引用 2 楼 xiaohuh421 的回复:1. 打印到文件的同时打印到控制止台, 确认代码 执行到. 2. 文件是否正常关闭,或者刷新, 因为输出文件是有缓存的, 只有当一定条件, 这些数据才会真正写入到文件中.  比如缓冲区满, 主动刷新, 或者文件被关闭. 对于1，我确实是这样做的，已经确认代码执行到。 对于2，我是这样执行的， test  2>temp.txt  ，错误重定向，应该不会是文件缓冲区的问题吧，我上面已经给出了代码了。

引用 1 楼 a30037338 的回复:贴代码。。。。。。  代码太长，没法贴，贴其他地方了。请搜索一下  aaaaa  bbbbb,2个打印的地方  http://blog.sina.com.cn/s/blog_55ff379d0102vuch.html

后台的意思可能就是将所有输出重定向的意思，我猜。 FREOPEN Section: POSIX Programmer's Manual (P) Updated: 2003  --------------------------------------------------------------------------------    NAME freopen - open a stream    SYNOPSIS #include <stdio.h>    FILE *freopen(const char *restrict filename, const char *restrict mode,         FILE *restrict stream);      DESCRIPTION The freopen() function shall first attempt to flush the stream and close any file descriptor associated with stream. Failure to flush or close the file descriptor successfully shall be ignored. The error and end-of-file indicators for the stream shall be cleared.   The freopen() function shall open the file whose pathname is the string pointed to by filename and associate the stream pointed to by stream with it. The mode argument shall be used just as in fopen().   The original stream shall be closed regardless of whether the subsequent open succeeds.   If filename is a null pointer, the freopen() function shall attempt to change the mode of the stream to that specified by mode, as if the name of the file currently associated with the stream had been used. It is implementation-defined which changes of mode are permitted (if any), and under what circumstances.   After a successful call to the freopen() function, the orientation of the stream shall be cleared,  the encoding rule shall be cleared, and the associated mbstate_t object shall be set to describe an initial conversion state.   The largest value that can be represented correctly in an object of type off_t shall be established as the offset maximum in the open file description.     RETURN VALUE Upon successful completion, freopen() shall return the value of stream. Otherwise, a null pointer shall be returned,  and errno shall be set to indicate the error.     ERRORS The freopen() function shall fail if:   EACCES  Search permission is denied on a component of the path prefix, or the file exists and the permissions specified by mode are denied, or the file does not exist and write permission is denied for the parent directory of the file to be created.  EINTR  A signal was caught during freopen().  EISDIR  The named file is a directory and mode requires write access.  ELOOP  A loop exists in symbolic links encountered during resolution of the path argument.  EMFILE  {OPEN_MAX} file descriptors are currently open in the calling process.  ENAMETOOLONG  The length of the filename argument exceeds {PATH_MAX} or a pathname component is longer than {NAME_MAX}.   ENFILE  The maximum allowable number of files is currently open in the system.  ENOENT  A component of filename does not name an existing file or filename is an empty string.  ENOSPC  The directory or file system that would contain the new file cannot be expanded, the file does not exist, and it was to be created.  ENOTDIR  A component of the path prefix is not a directory.  ENXIO  The named file is a character special or block special file, and the device associated with this special file does not exist.  EOVERFLOW  The named file is a regular file and the size of the file cannot be represented correctly in an object of type off_t.  EROFS  The named file resides on a read-only file system and mode requires write access.   The freopen() function may fail if:   EINVAL  The value of the mode argument is not valid.  ELOOP  More than {SYMLOOP_MAX} symbolic links were encountered during resolution of the path argument.  ENAMETOOLONG  Pathname resolution of a symbolic link produced an intermediate result whose length exceeds {PATH_MAX}.   ENOMEM  Insufficient storage space is available.  ENXIO  A request was made of a nonexistent device, or the request was outside the capabilities of the device.  ETXTBSY  The file is a pure procedure (shared text) file that is being executed and mode requires write access.   The following sections are informative.     EXAMPLES    Directing Standard Output to a File The following example logs all standard output to the /tmp/logfile file.     #include <stdio.h> ... FILE *fp; ... fp = freopen ("/tmp/logfile", "a+", stdout); ...      APPLICATION USAGE The freopen() function is typically used to attach the preopened streams associated with stdin, stdout, and stderr to other files.     RATIONALE None.     FUTURE DIRECTIONS None.     SEE ALSO fclose() , fopen() , fdopen() , mbsinit() , the Base Definitions volume of IEEE Std 1003.1-2001, <stdio.h>     COPYRIGHT Portions of this text are reprinted and reproduced in electronic form from IEEE Std 1003.1, 2003 Edition, Standard for Information Technology -- Portable Operating System Interface (POSIX), The Open Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the Institute of Electrical and Electronics Engineers, Inc and The Open Group. In the event of any discrepancy between this version and the original IEEE and The Open Group Standard, the original IEEE and The Open Group Standard is the referee document. The original Standard can be obtained online at http://www.opengroup.org/unix/online.html .  --------------------------------------------------------------------------------  Example  /* FREOPEN.C: This program reassigns stderr to the file  * named FREOPEN.OUT and writes a line to that file.  */  #include <stdio.h> #include <stdlib.h>  FILE *stream;  void main( void ) {    /* Reassign "stderr" to "freopen.out": */    stream = freopen( "freopen.out", "w", stderr );     if( stream == NULL )       fprintf( stdout, "error on freopen\n" );    else    {       fprintf( stream, "This will go to the file 'freopen.out'\n" );       fprintf( stdout, "successfully reassigned\n" );       fclose( stream );    }    system( "type freopen.out" ); }   Output  successfully reassigned This will go to the file 'freopen.out'

[user@localhost magent]$ sudo lsof |grep magent lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs       Output information may be incomplete.  test    44058                 user    0u      CHR                1,3       0t0       5701 /dev/null test    44058                 user    1u      CHR                1,3       0t0       5701 /dev/null test    44058                 user    2u      CHR                1,3       0t0       5701 /dev/null 这是什么情况？表明重定向了？错误被扔掉了？我不想错误被扔掉，想错误打印出来，如何修改？我都没有看懂程序怎么突然被重定向了，哪位看下我上面链接的代码，告诉我下为什么会被重定向的。

引用 5 楼 zhao4zhong1 的回复:在每个不带末尾\n的fprintf(stderr,"...");后面加 fflush(stderr);  我看了下，这个进程的父进程为1，这是个后台进程，应该和这个有关系，谁能解释下么？

贴代码。。。。。。


引用 4 楼 ID870177103 的回复:vs2012里给的定义是 #define SIG_ERR (void (__cdecl *) (int))-1 其它的也是都有int 说明是你的编译器的问题吧 不过能编译通过也不会产生错误 但是不同指针也能比较，是什么编译器啊 刚刚查了下源代码，确实是有int的，上面这些我都是用手机在网上查到的，看来网上的也不能尽信，得自己验证，谢谢。

引用 3 楼 a30037338 的回复:你确定这个能正确执行， 编译就过不了，不能这样用。 我是直接百度signal函数，有的百科介绍这函数的时候引用了上面的例子。 手机上网查的，没验证。

你确定这个能正确执行， 编译就过不了，不能这样用。

/* This example installs a signal handler routine for SIGFPE, catches an integer overflow condition, makes an adjustment to AX register, and returns. This example program MAY cause your computer to crash, and will produce runtime errors depending on which memory model is used. */ #pragma inline #include <stdio.h> #include <signal.h> void Catcher(int sig, int type, int *reglist) { printf("Caught it!\n"); *(reglist + 8) = 3; /* make return AX = 3 */ } int main(void) { signal(SIGFPE, Catcher); asm mov ax,07FFFH /* AX = 32767 */ asm inc ax /* cause overflow */ asm into /* activate handler */ /* The handler set AX to 3 on return. If that hadn't happened, there would have been another exception when the next 'into' was executed after the 'dec' instruction. */ asm dec ax /* no overflow now */ asm into /* doesn't activate */ return 0; } 还有这里Catcher函数有3个参数，signal也能执行？ 是不是void(*handle)(int)只看成指针，传地址就行？形参并不进行检查？

这才是c语言， 可以很无耻的这样转。这样转换就是把0，-1,1看做了地址。 signal的返回值本意是返回上次设置的signal处理函数，用于备份和恢复。


Question: 请教C语言一个小问题

引用 4 楼 cainiao_2015 的回复:[quote=引用 2 楼 zhangxiangDavaid 的回复:] 使用scanf(); 空白字符(空格、回车、制表符)可区分数据 使用gets(); 一般回车才可区分数据 gets() The gets function reads a line from the standard input stream stdin and stores it in buffer. The line consists of all characters up to and including the first newline character ('\n'). gets then replaces the newline character with a null character ('\0') before returning the line. In contrast, the fgets function retains the newline character.  你好，可我是分开用gets读入三人的名字的啊，我还是不理解你的意思，麻烦再解释一下，谢谢[/quote]  明白了，题目没看清啊。。。谢谢了

引用 2 楼 zhangxiangDavaid 的回复:使用scanf(); 空白字符(空格、回车、制表符)可区分数据 使用gets(); 一般回车才可区分数据 gets() The gets function reads a line from the standard input stream stdin and stores it in buffer. The line consists of all characters up to and including the first newline character ('\n'). gets then replaces the newline character with a null character ('\0') before returning the line. In contrast, the fgets function retains the newline character.  你好，可我是分开用gets读入三人的名字的啊，我还是不理解你的意思，麻烦再解释一下，谢谢

引用 1 楼 user-2 的回复:scanf的%s是读取到空格、回车、制表符，而gets只会读取到回车。 你用gets的话，三个人的名字会存成一个名字。  你好，可我是分开用gets读入三人的名字的啊，我还是不理解你的意思，麻烦再解释一下，谢谢


Question: 请教一下C语言什么样的代码会比较耗内存和时间？相对于OJ平台来说的，谢谢

循环、递归，以上


Question: 数据结构树：只知道中序后序求树

引用 5 楼 wangzuxi 的回复:[quote=引用 3 楼 pjw694438869c 的回复:] 其实我知道右边，我是分析不出左边 左边也是一个道理啊。 后序I L K J G D B E H F C A，分析完A的右子树（E H F C A）之后，接下来后序最后一个就是B，那B自然就是A的左孩子节点了，B之前是D，所以D肯定是B的孩子，在中序中D在B左边，所以D是B的左孩子节点，后序中D前面是G，中序G又在D右边，所以G是D的右孩子节点，后序中G前面是J，中序中J在G右边，所以J是G的右孩子，中序中I在G左边，所以I是G的左孩子节点，后序中J前面是K，中序中K在J右边，所以K是J的右孩子节点，后序中K前面是L，中序中L在K左边，所以L是K的左孩子节点。[/quote] 看了 终于会了

引用 4 楼 fly_dragon_fly 的回复:struct btree{     btree * left, *right;     char c; };  btree *build(const char *post,const char *lastpost,              const char *in,  const char *lastin) {     assert(lastpost-post==lastin-in);     if(post==lastpost) return NULL;     btree *rt =(btree *)malloc(sizeof(*rt));     rt->c =lastpost[-1];     const char *p=strchr(in,rt->c);     const char *mid =p-in+post;     rt->left =build(post,mid,in,p);     rt->right=build(mid,lastpost-1,p+1,lastin);     return rt; }  int main() {     const char *in    ="DIGJLKBAECHF";     const char *post  ="ILKJGDBEHFCA";     int len=strlen(post);     btree *root =build(post,post+len,in,in+len);      return 0; } 谢谢

其实我知道右边，我是分析不出左边

引用 3 楼 pjw694438869c 的回复:其实我知道右边，我是分析不出左边 左边也是一个道理啊。 后序I L K J G D B E H F C A，分析完A的右子树（E H F C A）之后，接下来后序最后一个就是B，那B自然就是A的左孩子节点了，B之前是D，所以D肯定是B的孩子，在中序中D在B左边，所以D是B的左孩子节点，后序中D前面是G，中序G又在D右边，所以G是D的右孩子节点，后序中G前面是J，中序中J在G右边，所以J是G的右孩子，中序中I在G左边，所以I是G的左孩子节点，后序中J前面是K，中序中K在J右边，所以K是J的右孩子节点，后序中K前面是L，中序中L在K左边，所以L是K的左孩子节点。

后序最后是A，所以A是根，在中序中以A为界分成两半，后半部分是ECHF，在后序中A之前是C，所以A的右子树以C为根，而中序是ECHF，所以C的左子树只有一个节点E，后序中C前面是F，所以C的右子树以F为根，中序为HF，所以H是F的左孩子节点。中序中A的前半部分也是同样道理分析即可。


Question: 关于Huffman压缩中的编码与写入读取二进制文件的问题

如何将字符串转化为二进制的0x99呢，是要先将串"10011001"转化为整型对应的153然后写入文件？还是说有什么办法能够将串直接转变为int的0x形式？  引用 1 楼 xiaohuh421 的回复:但是字符串每个0与1都必须要一个8位ASCII码(二进制)存储  需要把你的字符串转换为二进制数据, 再保存到文件中. 比如 "10011001"要转换成 0x99保存到文件中.  如何找到编码表与正文的分界线。 保存数据的时候, 就写入一个标识符作为分界.  比如0x123456 0x123456

仅供参考：//有一个二进制文件，要求每隔50bits，删除后面的12bits。 #include <stdio.h> #include <stdlib.h> #include <string.h> FILE *fi,*fo; char buf[31]; char obf[31]; int bn,n; void filter() {//对buf中前n个字节中的位，每隔50bits，忽略12bits，结果放在obf中,且将bn设置为obf中的字节数。     char bit[249];     char obt[249];     char b8[33];     char b88[33];     int i,j;     char *e;      for (i=0;i<n;i++) {         _itoa(buf[i],b8,2);         sprintf(b88,"%032s",b8);         sprintf(bit+i*8,"%s",b88+24);     }      j=0;     for (i=0;i<n*8;i++) {         if (i%62<50) {             obt[j]=bit[i];             j++;         }     }     if (j%8) {         bn=(j/8+1)*8;     } else {         bn=j;     }     for (i=j;i<bn;i++) obt[i]='0';     obt[bn]=0;     bn=bn/8;     for (i=0;i<bn;i++) {         strncpy(b8,obt+i*8,8);b8[8]=0;         obf[i]=(char)strtol(b8,&e,2);     } } int main() {     fi=fopen("in.bin","rb");     if (NULL==fi) {         printf("Can not open file in.bin!\n");         return 1;     }     fo=fopen("out.bin","wb");     if (NULL==fo) {         fclose(fi);         printf("Can not open file out.bin!\n");         return 2;     }     while (1) {         n=fread(buf,1,31,fi);         if (0==n) break;         filter();         fwrite(obf,1,bn,fo);     }     fclose(fo);     fclose(fi);     return 0; }

按bit置位啊. 每次取你的二进制串中的8位. 比如"10011001" 然后使用一个BYTE来保存其数据. char buf[9] = "10011001"; BYTE data = 0; if(buf[0] == '1') {     data |= 0x80;  //0x80  == 10000000B } if(buf[1] == '0') {     data |= 0x40;  //0x40 == 01000000B } ..... 经过8次后, data == 0x99 == 10011001B   .....后面你自己发挥了. 可把前面的过程写成循环, 也可以每8位直接写成上面的代码.


Question: 关键路径问题：图的各种信息输入后，关键活动不能输出是哪里错了

自己调吧。。你这叫人怎么看。


Question: 如何将16进制的字符串“0x21”转换成字符型 char a=(cahr )0x21。

引用 8 楼 zhangxiangDavaid 的回复:6楼的%i用的好 scanf Type Field Characters The type character is the only required format field; it appears after any optional format fields. The type character determines whether the associated argument is interpreted as a character, string, or number.  Table R.8   Type Characters for scanf functions  Character  Type of Input Expected Type of Argument  c When used with scanf functions, specifies single-byte character; when used with wscanf functions, specifies wide character. White-space characters that are ordinarily skipped are read when c is specified. To read next non–white-space single-byte character, use %1s; to read next non–white-space wide character, use %1ws. Pointer to char when used with scanf functions, pointer to wchar_t when used with wscanf functions.  C When used with scanf functions, specifies wide character; when used with wscanf functions, specifies single-byte character. White-space characters that are ordinarily skipped are read when C is specified. To read next non–white-space single-byte character, use %1s; to read next non–white-space wide character, use %1ws. Pointer to wchar_t when used with scanf functions, pointer to char when used with wscanf functions.  d Decimal integer. Pointer to int.  i Decimal, hexadecimal, or octal integer. Pointer to int.  o Octal integer. Pointer to int.  u Unsigned decimal integer. Pointer to unsigned int.  x Hexadecimal integer. Pointer to int.  e, E, f, g, G Floating-point value consisting of optional sign (+ or –), series of one or more decimal digits containing decimal point, and optional exponent (“e” or “E”) followed by an optionally signed integer value. Pointer to float.  n No input read from stream or buffer. Pointer to int, into which is stored number of characters successfully read from stream or buffer up to that point in current call to scanf functions or wscanf functions.  s String, up to first white-space character (space, tab or newline). To read strings not delimited by space characters, use set of square brackets ([ ]), as discussed following Table R.7. When used with scanf functions, signifies single-byte character array; when used with wscanf functions, signifies wide-character array. In either case, character array must be large enough for input field plus terminating null character, which is automatically appended.  S String, up to first white-space character (space, tab or newline). To read strings not delimited by space characters, use set of square brackets ([ ]), as discussed preceding this table. When used with scanf functions, signifies wide-character array; when used with wscanf functions, signifies single-byte–character array. In either case, character array must be large enough for input field plus terminating null character, which is automatically appended.    The types c, C, s, and S are Microsoft extensions and are not ANSI-compatible.   Thus, to read single-byte or wide characters with scanf functions and wscanf functions, use format specifiers as follows.  To Read Character As Use This Function With These Format Specifiers  single byte scanf functions c, hc, or hC  single byte wscanf functions C, hc, or hC  wide wscanf functions c, lc, or lC  wide scanf functions C, lc, or lC    To scan strings with scanf functions, and wscanf functions, use the prefixes h and l analogously with format type-specifiers s and S.

char *s1="0x21";  int val = strtol(s1, NULL, 16); //16进制字符串,转换成整型.  printf("%d", val);

sscanf(str,"0x%x",&z);  感觉应该是这样，不过没试过。

6楼的%i用的好

应该有一个关于转成ASC码的函数吧

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

char *s1="0x21"; int i; char a; sscanf(s1,"%i",&i); a=(char)(i&0xffu) printf("%d\n",a);

引用 4 楼 user-6 的回复:[quote=引用 3 楼 zhangxiangDavaid 的回复:]  int main() { 	char *s1 = "0x21"; 	unsigned char c;     //为了防止溢出，使用unsigned 	sscanf(s1, "%x", &c); 	printf("c=%c,%d\n", c, c);  //!,33 	return 0; }  这个sscanf的用法是错误的 sscanf(s1, "%hhx", &c);[/quote] 多谢指正！

引用 3 楼 zhangxiangDavaid 的回复: int main() { 	char *s1 = "0x21"; 	unsigned char c;     //为了防止溢出，使用unsigned 	sscanf(s1, "%x", &c); 	printf("c=%c,%d\n", c, c);  //!,33 	return 0; }  这个sscanf的用法是错误的 sscanf(s1, "%hhx", &c);


Question: fread函数怎么用，想读取一个BIN文件

电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

1.bin  0 1

如下测试：  int main(void) { 	FILE *fp; 	fp = fopen("1.bin", "rb"); 	unsigned char buf[20]; 	fread(buf, sizeof(unsigned char), 20, fp); 	fclose(fp); 	int n1, n2; 	sscanf(buf, "%d%d", &n1, &n2); 	printf("n1=%d,n2=%d\n", n1, n2); 	return 0; } //n1=0,n2=2


Question: 读取把bin文件，显示为矩阵然后显示出一个灰度值图像

是bin文件，fp=("c:\\001.bin","rb");,这应该没什么问题，但是用fream读出来不对

fopen("test.txt", "r+b");  有没有加这个"b"， 表示以二进制方式读取文件。


Question: C语言求助

PlaySound The PlaySound function plays a sound specified by the given filename, resource, or system event. (A system event may be associated with a sound in the registry or in the WIN.INI file.)   BOOL PlaySound(   LPCSTR pszSound,     HMODULE hmod,        DWORD fdwSound     );   Parameters pszSound  A string that specifies the sound to play. If this parameter is NULL, any currently playing waveform sound is stopped. To stop a non-waveform sound, specify SND_PURGE in the fdwSound parameter.  Three flags in fdwSound (SND_ALIAS, SND_FILENAME, and SND_RESOURCE) determine whether the name is interpreted as an alias for a system event, a filename, or a resource identifier. If none of these flags are specified, PlaySound searches the registry or the WIN.INI file for an association with the specified sound name. If an association is found, the sound event is played. If no association is found in the registry, the name is interpreted as a filename.   hmod  Handle of the executable file that contains the resource to be loaded. This parameter must be NULL unless SND_RESOURCE is specified in fdwSound.  fdwSound  Flags for playing the sound. The following values are defined:  SND_APPLICATION  The sound is played using an application-specific association.  SND_ALIAS  The pszSound parameter is a system-event alias in the registry or the WIN.INI file. Do not use with either SND_FILENAME or SND_RESOURCE.  SND_ALIAS_ID  The pszSound parameter is a predefined sound identifier.  SND_ASYNC  The sound is played asynchronously and PlaySound returns immediately after beginning the sound. To terminate an asynchronously played waveform sound, call PlaySound with pszSound set to NULL.  SND_FILENAME  The pszSound parameter is a filename.  SND_LOOP  The sound plays repeatedly until PlaySound is called again with the pszSound parameter set to NULL. You must also specify the SND_ASYNC flag to indicate an asynchronous sound event.  SND_MEMORY  A sound event's file is loaded in RAM. The parameter specified by pszSound must point to an image of a sound in memory.  SND_NODEFAULT  No default sound event is used. If the sound cannot be found, PlaySound returns silently without playing the default sound.  SND_NOSTOP  The specified sound event will yield to another sound event that is already playing. If a sound cannot be played because the resource needed to generate that sound is busy playing another sound, the function immediately returns FALSE without playing the requested sound.  If this flag is not specified, PlaySound attempts to stop the currently playing sound so that the device can be used to play the new sound.   SND_NOWAIT  If the driver is busy, return immediately without playing the sound.  SND_PURGE  Sounds are to be stopped for the calling task. If pszSound is not NULL, all instances of the specified sound are stopped. If pszSound is NULL, all sounds that are playing on behalf of the calling task are stopped.  You must also specify the instance handle to stop SND_RESOURCE events.   SND_RESOURCE  The pszSound parameter is a resource identifier; hmod must identify the instance that contains the resource.  SND_SYNC  Synchronous playback of a sound event. PlaySound returns after the sound event completes.  Return Values Returns TRUE if successful or FALSE otherwise.  Remarks The sound specified by pszSound must fit into available physical memory and be playable by an installed waveform-audio device driver. PlaySound searches the following directories for sound files: the current directory; the Windows directory; the Windows system directory; directories listed in the PATH environment variable; and the list of directories mapped in a network. For more information about the directory search order, see the documentation for the OpenFile function.  If it cannot find the specified sound, PlaySound uses the default system event sound entry instead. If the function can find neither the system default entry nor the default sound, it makes no sound and returns FALSE.  QuickInfo   Windows NT: Requires version 3.1 or later.   Windows: Requires Windows 95 or later.   Windows CE: Unsupported.   Header: Declared in mmsystem.h.   Import Library: Use winmm.lib.   Unicode: Implemented as Unicode and ANSI versions on Windows NT.  See Also Waveform Audio Overview, Waveform Functions

播放音频 C源码 http://www.baidu.com/s?wd=播放音频%20C源码&ie=utf-8

windows 平台可以用 mediaplayer 控件

百度  mciSendString


Question: 超时了，求大神指点更好的解题思路

我又看了看题目…原来那个样例只要输出最后的中位数呀！那你就按照指令模拟，最后再按我第一个回复的找一次中位数就好了

引用 8 楼 jensenjiang 的回复:我错了，我以为只是求中位数，那这样N*K肯定超时。 那就应该要用线段数区间修改了  本人菜鸟，求指教什么是线段区间修改？谢谢

1、偷懒，用C++ STL 自带的nthelement 效率是O(N)的 2、自己实现nthelement，方法类似于快速排序，快速排序每次都找一个正确位置的元素，因此每一次找到那个正确位置的元素后，判断中点在它的左区间还是右区间，递归解决即可

引用 4 楼 zhangxiangDavaid 的回复:偷个懒，试下快速排序：  int T, N, K, A, B; int i, j; int straw[1000000]; int cmp(int *a, int *b) { 	return *a < *b; } int main() { 	scanf("%d", &T); 	while (T--) 	{ 		scanf("%d%d", &N, &K); 		memset(straw, 0, sizeof(int) * 1000000); 		while (K--) 		{ 			scanf("%d%d", &A, &B); 			for (i = A; i <= B; i++) straw[i]++; 		} 		qsort(straw, N, sizeof(int), cmp); 		printf("%d\n", straw[N / 2]); 	} 	return 0; }   用了快排结果还是超时，还有改进的方法吗？ #include<stdio.h> #include<stdlib.h>  int a[1000000];  int cmp(const void*a,const void*b) { return *(int*)a-*(int*)b; }  int main() {     int T,n,k,i,t,x,y,temp;      scanf("%d",&T);      while(T--)     {         scanf("%d%d",&n,&k);          for(i=0; i<n; i++)             a[i]=0;          for(i=1; i<=k; i++)         {             scanf("%d%d",&x,&y);             for(t=x-1; t<=y-1; t++)                 a[t]++;         }          qsort(a,n,sizeof(int),cmp);          printf("%d\n",a[n/2]);      }      return 0; }

这个题目用循环，排序肯定都会超时。K个指令，每条指令都是区间更新，这个很明显使用线段树会比较合适。但不知道怎么在线段树中找到中位数。

寻找中位数，堆排序？

从一个数组中寻找第K大的数，是不需要排序的，这题考的就是快速寻找中位数。

运行正常。 我用的是Dev-C++，超时可能和你的编译工具有关。 把while的条件改成T-->0，应该就可以了。


Question: realloc()函数没有保留原指针的内容是怎么回事？

测试成功，应该指明sizeof（）。 谢谢！

if(!(psTemp=(char**)realloc(pS,capacity)))           应改为 if(!(psTemp=(char**)realloc(pS,capacity*sizeof(char *))))

引用 3 楼 shangxiaa 的回复:老湿，你就说我写的那一段程序中问题出在哪？ 如果不出现调用remalloc函数的情况，没有任何问题。 一旦使用realloc函数就出错，这和函数的定义不符合啊。 参考我代码中是如何使用realloc的。

引用 4 楼 zhangxiangDavaid 的回复:至少： if(str_count==capacity)   //改为 if(str_count + 1 == capacity) 和这个没关系…… 测试了一下，只要使用指针的指针这种类型就出问题。

没看懂，编译一下也是出错……  引用 1 楼 zhao4zhong1 的回复:仅供参考：//文件1中的内容排序并去重,结果保存到文件2中 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXCHARS 128      //能处理的最大行宽,包括行尾的\n和字符串尾的\0 int MAXLINES=10000,MAXLINES2; char *buf,*buf2; int c,n,hh,i,L; FILE *f; char ln[MAXCHARS]; int ignore_case=0; int icompare(const void *arg1,const void *arg2) {    return stricmp((char *)arg1,(char *)arg2); } int compare(const void *arg1,const void *arg2) {    return strcmp((char *)arg1,(char *)arg2); } int main(int argc,char **argv) {     if (argc<3) {         printf("Unique line. Designed by zhao4zhong1@163.com. 2012-08-20\n");         printf("Usage: %s src.txt uniqued.txt [-i]\n",argv[0]);         return 1;     }     if (argc>3) ignore_case=1;//若存在命令行参数3，忽略大小写     f=fopen(argv[1],"r");     if (NULL==f) {         printf("Can not find file %s!\n",argv[1]);         return 1;     }     buf=(char *)malloc(MAXLINES*MAXCHARS);     if (NULL==buf) {         fclose(f);         printf("Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES,MAXCHARS);         return 2;     }     n=0;     hh=0;     i=0;     while (1) {         if (NULL==fgets(ln,MAXCHARS,f)) break;//         hh++;         L=strlen(ln)-1;         if ('\n'!=ln[L]) {//超长行忽略后面内容             printf("%s Line %d too long(>%d),spilth ignored.\n",argv[1],hh,MAXCHARS);             while (1) {                 c=fgetc(f);                 if ('\n'==c || EOF==c) break;//             }         }         while (1) {//去掉行尾的'\n'和空格             if ('\n'==ln[L] || ' '==ln[L]) {                 ln[L]=0;                 L--;                 if (L<0) break;//             } else break;//         }         if (L>=0) {             strcpy(buf+i,ln);i+=MAXCHARS;             n++;             if (n>=MAXLINES) {                 MAXLINES2=MAXLINES*2;                 if (MAXLINES2==1280000) MAXLINES2=2500000;                 buf2=(char *)realloc(buf,MAXLINES2*MAXCHARS);                 if (NULL==buf2) {                     printf("Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES2,MAXCHARS);                     printf("WARNING: Lines >%d ignored.\n",MAXLINES);                     break;//                 }                 buf=buf2;                 MAXLINES=MAXLINES2;             }         }     }     fclose(f);     if (n>1) {         if (ignore_case) qsort(buf,n,MAXCHARS,icompare);         else qsort(buf,n,MAXCHARS,compare);     }     f=fopen(argv[2],"w");     if (NULL==f) {         free(buf);         printf("Can not create file %s!\n",argv[2]);         return 2;     }     fprintf(f,"%s\n",buf);     if (n>1) {         if (ignore_case) {             hh=0;             L=MAXCHARS;             for (i=1;i<n;i++) {                 if (stricmp((const char *)buf+hh,(const char *)buf+L)) {                     fprintf(f,"%s\n",buf+L);                 }                 hh=L;                 L+=MAXCHARS;             }         } else {             hh=0;             L=MAXCHARS;             for (i=1;i<n;i++) {                 if ( strcmp((const char *)buf+hh,(const char *)buf+L)) {                     fprintf(f,"%s\n",buf+L);                 }                 hh=L;                 L+=MAXCHARS;             }         }     }     fclose(f);     free(buf);     return 0; }


Question: 关于printf的奇怪问题

fflush(stdout);

console屏幕处理例子程序。终端窗口屏幕处理相关API使用例子。来自MSVC20\SAMPLES\win32\console\ http://download.csdn.net/detail/zhao4zhong1/3461309


Question: 关于huffman树如何压缩的问题

如要压缩的字符串为abc，a的编码为0,b为10,c为11。 char c = 0; char tmp = 0; c = c|(tmp<<7); tmp = 2; c = c|(tmp<<5); tmp = 3; c = c|(tmp<<3); 这时c的二进制就是01011000，fwrite把c写到文件中。 解析时还有问题，如上面原来是abc，解析后就会解析成abcaaa。

引用 1 楼 user-1 的回复:肯定是要按位进行写和读取比对。否则的话，怎么能到达压缩的目的呢。比如字符'A'原来是一个字节，编码后为101不按位进行写操作。就用了三个字节。看GNUZip的源码。 那按位写又如何操作..fwrite不是一次至少要写入1一个字节8位吗，我怎么才能一次一位一位往里面写


Question: 求教一个verilog读写文件的问题 虽然不是c但是不知道去哪里问好


Question: Google了一个晚上没找到C11，谁提供一下，谢谢～～

谢谢楼上各位。。 如果有朋友能提供C11正式版更好～～～

手里也就一个 “C语言标准1x草案 n1494” 已经足够用了。如果不是做编译器，根本没必要强求正式版。基本上没有实质差异的。

其实C11的正式版本和N1570差不太多，修正了N1570的一些错误，编号也有所改变。即使是修正了N1570的错误（比如_Alignof的语法，这个运算符不适用于表达式，正式版已修正），但仍有很多错误和遗露的地方。可以上网查相关的DR。

引用 2 楼 sholber 的回复:[quote=引用 1 楼 user-3 的回复:] https://www.iso.org/obp/ui/#iso:std:57853:en 你自己都没看过，就急急忙忙推荐。那是要买的，你以为ISO会免费公布（即使是以网页的形式）。[/quote]  好吧...........我就是随便搜了下 还以为能用～～

引用 1 楼 user-3 的回复:https://www.iso.org/obp/ui/#iso:std:57853:en 你自己都没看过，就急急忙忙推荐。那是要买的，你以为ISO会免费公布（即使是以网页的形式）。


Question: 请问windows中的HANDLE和PVOID是怎么维护数据的

HBITMAP bm; PVOID data; bm=(HBITMAP) data; 这样可以么，数据会否在后边的操作被修改？

这个属于你不应该关心的实现细节。你不应该用官方API之外的方式操纵这些内核对象。这种操作的结果可以是任何事件，包括格式化你的硬盘。

哦，原来HANDLE 和 PVOID是一样的，都是void*