Mxode/CSDN-C_Language-2013_2023 huggingface dataset:
user-0 提问: 怎样改变指针数组指向的字符串的值？

回复:
user: user-1
content: 引用 8 楼 qq423399099 的回复:[quote=引用 7楼qq_16774199 的回复:][quote=引用 6 楼 qq423399099 的回复:] 你要改的话直接让指针指向另一个常量字符串"222"是可以的  #include<stdio.h> int main() { 	char *aaa[] = { "111" }; 	aaa[0] = "222"; 	printf("%s\n", aaa[0]); }  请教，指针变量不是只能用来储存地址吗？为什么能储存字符串了？[/quote]它存储的是常量字符串"111"的首地址[/quote]  那么这个常量字符串只能用指针读取，没办法用正常的字符类似数组变量读取？

user: user-2
content: 跟前面一样的看法，你定义了字符指针数组，但初始化后，就不能改变其大小 char *p="111" ,p指向的内容是在常量区，无法改变 如果，你想要定义一个可以改变大小的数组，可以用C++的vector模板 http://blog.csdn.net/zycxnanwang/article/details/51934397

user: user-3
content: 改变不了，"111"存放在常量区，无法修改。

user: user-4
content: 引用 7楼qq_16774199 的回复:[quote=引用 6 楼 qq423399099 的回复:] 你要改的话直接让指针指向另一个常量字符串"222"是可以的  #include<stdio.h> int main() { 	char *aaa[] = { "111" }; 	aaa[0] = "222"; 	printf("%s\n", aaa[0]); }   请教，指针变量不是只能用来储存地址吗？为什么能储存字符串了？[/quote]它存储的是常量字符串"111"的首地址

user: user-1
content: 引用 6 楼 qq423399099 的回复:你要改的话直接让指针指向另一个常量字符串"222"是可以的  #include<stdio.h> int main() { 	char *aaa[] = { "111" }; 	aaa[0] = "222"; 	printf("%s\n", aaa[0]); }   请教，指针变量不是只能用来储存地址吗？为什么能储存字符串了？

user: user-4
content: 你要改的话直接让指针指向另一个常量字符串"222"是可以的  #include<stdio.h> int main() { 	char *aaa[] = { "111" }; 	aaa[0] = "222"; 	printf("%s\n", aaa[0]); }

user: user-5
content: char *p1 = "111"; 	char *p2 = "222";  	char *aaa[] = { p1, p2, "333" };

user: user-4
content: 引用 9 楼 qq_16774199 的回复:[quote=引用 8 楼 qq423399099 的回复:] [quote=引用 7楼qq_16774199 的回复:][quote=引用 6 楼 qq423399099 的回复:] 你要改的话直接让指针指向另一个常量字符串"222"是可以的  #include<stdio.h> int main() { 	char *aaa[] = { "111" }; 	aaa[0] = "222"; 	printf("%s\n", aaa[0]); }  请教，指针变量不是只能用来储存地址吗？为什么能储存字符串了？[/quote]它存储的是常量字符串"111"的首地址[/quote]  那么这个常量字符串只能用指针读取，没办法用正常的字符类似数组变量读取？[/quote] 这样？  #include<stdio.h> int main() { 	char *aaa[] = { "111" }; 	aaa[0] = "242"; 	printf("%c\n", aaa[0][1]); }

user: user-0
content: 引用 1 楼 q932104843 的回复:*aaa[0]="222"; 你这里初始化都定义了数组大小了，貌似不能再添加了，貌似也不能删除吧  error C2440: '=' : cannot convert from 'const char [4]' to 'char'

user: user-6
content: *aaa[0]="222"; 你这里初始化都定义了数组大小了，貌似不能再添加了，貌似也不能删除吧
user-0 提问: C语言初学者提问 IF语句

回复:
user: user-1
content: 建议你看一下 C语言的 运算符优先级

user: user-1
content: 关键在于 k=i*j==6; 先  进行i*j 之后表达式就成了 k=6==6; 6==6 成立 故 k=1; 所以就是1了

user: user-2
content: 运算符优先级  参看：http://en.cppreference.com/w/cpp/language/operator_precedence

user: user-3
content: 运算符优先级

user: user-4
content: if在哪里？ 并且：C语言没有IF，只有if，大小写严格区分！

user: user-5
content: 运算符优先级的问题：逻辑运算符大于赋值运算符 k=i*j==6; 这个先算逻辑运算符：i*j=6，即k=6==6; k=6==6又是关系运算符(==)优先级高，6==6恒等，所以k=1(判断)

user: user-6
content: 这里三个运算符*最大，最先运算。然后是==，最后是=

user: user-7
content: ==的优先级高于=的优先级 http://www.jb51.net/article/37282.htm

user: user-8
content: 1为真，0为假
user-0 提问: 恶心的strtok函数，太不人性化了。

回复:
user: user-0
content: 引用 12 楼 cfjtaishan 的回复:建议不用strtok而改用strtok_r；在多线程中,建议使用strtok_r,而不要使用strtok； strtok_r可以不会很晦涩；使用方法稍微查一下；  strtok_r是linux平台下的strtok函数的线程安全版。windows的string.h中并不包含它。 但是我发现这句话，而我用windows学习。

user: user-1
content: 建议不用strtok而改用strtok_r；在多线程中,建议使用strtok_r,而不要使用strtok； strtok_r可以不会很晦涩；使用方法稍微查一下；

user: user-2
content: 从来不用这个函数，这个的实现太简单，修改了原始内容。 自己去写一个比这个好用的，直接传常量字符串都行。

user: user-3
content: 引用 6 楼 qq_16774199 的回复:[quote=引用 3 楼 paschen 的回复:] 也没你说那么难用,自己写一个函数封装strtok不就行了 请问自己写的函数，运行速度会不会比自带的慢些？ 我还没到关心速度的层次，只是想了解一下自制函数的速度是不是比自带的慢。[/quote]  效率影响不会太大  可以简单封装这个函数，也可以完全自己去实现这个功能

user: user-3
content: http://www.jb51.net/article/55954.htm  另外MFC的CString也自己封装了分割字符串的方法

user: user-3
content: 也没你说那么难用,自己写一个函数封装strtok不就行了

user: user-4
content: 自己写，很快的啊

user: user-5
content: 根据需求自己写一个就行了，逻辑不是很复杂

user: user-6
content: 这个函数非线程安全，慎用

user: user-7
content: 这个函数修改了源数据，确实是非常糟糕的设计。

user: user-0
content: 引用 3 楼 paschen 的回复:也没你说那么难用,自己写一个函数封装strtok不就行了 请问自己写的函数，运行速度会不会比自带的慢些？ 我还没到关心速度的层次，只是想了解一下自制函数的速度是不是比自带的慢。

user: user-8
content: 引用 楼主 qq_16774199 的回复:函数非常晦涩，理解了也很容易搞错。欲分割的字符串，第二次调用居然要设置为NULL。总之不好用。  请问c有没有什么人性化的函数，第三方的也行，用#include方式加进去也好？  这个函数设计的确实非常恶心，自己写函数分割吧。

user: user-9
content: 不会用不用就是了啊, 像C这么自由的语言, 这是个事么...
user-0 提问: 重新复习C语言遇到的一个神奇的问题

回复:
user: user-1
content: 3L说得很对啊, 有溢出的.是该复习一下了.

user: user-2
content: strlen是字符串的大小（字符串大小，C中字符串是以\0结尾）  sizeof是字符数组的大小（数组大小）

user: user-3
content: 楼主还没有明白sizeof和strlen的区别吧 sizeof是用来计算某个类型的变量的长度的，它一定是对应一种类型的，你这里的类型就是char[15]，虽然C语言里没把这个东西看做一种类型，但理解上可以这么理解，即st是一个类型为char[15]的变量，所占的内存空间大小就是15个字节，以后你遇到sizeof直接去找对应的类型就可以了 strlen是一个函数，是专门用来求字符数组（只能是字符数组）长度的，它的原理也很简单，就是遇到'\0'，就会停止计数（不包括'\0'），它不会管你是什么类型的，它只知道去找\0' 你的输入显然是超出了预先分配的空间大小，发生了缓冲器溢出错误，但并没有造成严重后果，你可以试试再多输入一些，肯定是有问题的，这也是gets这类函数的最大缺点

user: user-4
content: 引用定义的字符数组st是15长度的，但实际输入的字符串明显超过了15 未定义行为  未定义行为可能产生任何结果，包括但不限于：产生期望的结果，产生未期望的结果，产生随机的结果，产生无法解释的结果，运行错误，随机的运行时错误，编译错误，等等

user: user-5
content: strlen只能用char*做参数，且必须是以''\0''结尾的，strlen的结果要在运行的时候才能计算出来字符串的长度。   大部分编译程序 在编译的时候就把sizeof计算过了 是类型或是变量的长度这就是sizeof(x)可以用来计算字符数组长度的原因  有的编译器把内存的大小放在了数组首地址前的空间里。
user-0 提问: 一个C语言的语法问题求解释

回复:
user: user-1
content: 我觉的内存没有释放。

user: user-2
content: 1）如果 udp_new是调用 malloc.calloc,realloc,new 分配的 得看这三个函数如何处理 upcb udp_bind udp_echoserver_receive_callback  udp_recv 如果没释放，可能会有内存泄漏  2）如果不是， 要看是不是 调用 alloca 分配的 alloca 分配的不用释放 。。。 具体情况，具体分析，不一定就会有内存泄露 3）其他，。。。还是看看 udp_new的实现吧

user: user-3
content: 要看 udp_new 怎么写的， 如果是分配在栈内， 函数结束后就没有了， 如果是在堆上 需要单独释放
user-0 提问: 初学者求助

回复:
user: user-1
content: 楼上正解。但是不知道原作者为什么加*呢？是出于什么考虑，是有这个语法么？

user: user-2
content: 去掉%s中间的* printf里面的*的用法C89二十多年前就规定好了. ===================    A field width or precision, or both, may be indicated by an asterisk * instead of a digit string.  In this case, an int argument supplies the field width or precision.  The arguments specifying field width or precision, or both, shall appear (in that order) before the argument (if any) to be converted.  A negative field width argument is taken as a - flag followed by a positive field width.  A negative precision argument is taken as if it were missing. ===================  #include<stdio.h>  int main(void) { 	char name[40], name1[40]; 	printf("Please tell me your name,\n"); 	scanf("%s %s", name, name1); 	printf("Oh!You are \"%s %s\"\n", name, name1); 	getchar(); getchar(); 	return(0); }

user: user-3
content: http://en.cppreference.com/w/c/io/fprintf

user: user-4
content: %*s什么意思啊……
user-0 提问: 谁有rc522关于stc89s52的程序

回复:
user: user-0
content: 引用 2 楼 赵4老师的回复:https://www.baidu.com/s?wd=stc89s52%20源代码  什么意思，我没有看到，直接给我源代码可以吗？

user: user-1
content: https://www.baidu.com/s?wd=stc89s52%20源代码

user: user-0
content: 有人吗在吗帮帮忙求求你们了
user-0 提问: 关于一个指针的小问题

回复:
user: user-1
content: 你的s4是在my_replace函数的栈上分配的内存，函数返回时栈内存被回收，所以结果是不正确的 要想正确返回有两个方法： 1）定义一个全局栈数组，这样函数返回以后数组内存不会被释放，但定义全局数组不是什么好方法 2）在主函数里定义一个数组，这样从my_replace函数返回以后还可以在主函数里使用 以上两种方法因为不能提前知道数组长度，所以只能分配大数组 3）用malloc在堆上分配内存，这样可以先用strlen确定一下s1的长度，因为s4的长度肯定不好超过s1 最后这种方法可以在main函数里分配，也可以在my_replace里分配，无论在哪儿分配，一定要记得释放，为了保持一致性，最好是在main函数里分配 如果只是一个小例子，上面的方法都能实现，如果是真的系统开发，还是建议第3种方法

user: user-2
content: strstr

user: user-1
content: 引用 5 楼 baidu_35631329 的回复:[quote=引用 4 楼 cyfcsd 的回复:] 你的s4是在my_replace函数的栈上分配的内存，函数返回时栈内存被回收，所以结果是不正确的 要想正确返回有两个方法： 1）定义一个全局栈数组，这样函数返回以后数组内存不会被释放，但定义全局数组不是什么好方法 2）在主函数里定义一个数组，这样从my_replace函数返回以后还可以在主函数里使用 以上两种方法因为不能提前知道数组长度，所以只能分配大数组 3）用malloc在堆上分配内存，这样可以先用strlen确定一下s1的长度，因为s4的长度肯定不好超过s1 最后这种方法可以在main函数里分配，也可以在my_replace里分配，无论在哪儿分配，一定要记得释放，为了保持一致性，最好是在main函数里分配 如果只是一个小例子，上面的方法都能实现，如果是真的系统开发，还是建议第3种方法 那我假如在main中为s4申请了内存，可我函数的输入只有三个常量字符串，咋在里面使用他呢？ 还有就是假如我位s4malloc了100位char的大小，那他和s4[100]有区别吗？ [/quote] 如果函数的参数和返回值都定了，那就只能在my_replace函数里malloc内存了，因为外面的内存地址没法传递到函数里面去了，malloc内存和s4[100]的区别就是malloc的内存是分配在堆上的，它不会以为函数结束而被系统回收，还可以继续用

user: user-0
content: 引用 4 楼 cyfcsd 的回复:你的s4是在my_replace函数的栈上分配的内存，函数返回时栈内存被回收，所以结果是不正确的 要想正确返回有两个方法： 1）定义一个全局栈数组，这样函数返回以后数组内存不会被释放，但定义全局数组不是什么好方法 2）在主函数里定义一个数组，这样从my_replace函数返回以后还可以在主函数里使用 以上两种方法因为不能提前知道数组长度，所以只能分配大数组 3）用malloc在堆上分配内存，这样可以先用strlen确定一下s1的长度，因为s4的长度肯定不好超过s1 最后这种方法可以在main函数里分配，也可以在my_replace里分配，无论在哪儿分配，一定要记得释放，为了保持一致性，最好是在main函数里分配 如果只是一个小例子，上面的方法都能实现，如果是真的系统开发，还是建议第3种方法 还有就是题目里要求返回一个*s，那么是不是2）的方法就不能用了？ 感谢大神！求解答

user: user-0
content: 引用 4 楼 cyfcsd 的回复:你的s4是在my_replace函数的栈上分配的内存，函数返回时栈内存被回收，所以结果是不正确的 要想正确返回有两个方法： 1）定义一个全局栈数组，这样函数返回以后数组内存不会被释放，但定义全局数组不是什么好方法 2）在主函数里定义一个数组，这样从my_replace函数返回以后还可以在主函数里使用 以上两种方法因为不能提前知道数组长度，所以只能分配大数组 3）用malloc在堆上分配内存，这样可以先用strlen确定一下s1的长度，因为s4的长度肯定不好超过s1 最后这种方法可以在main函数里分配，也可以在my_replace里分配，无论在哪儿分配，一定要记得释放，为了保持一致性，最好是在main函数里分配 如果只是一个小例子，上面的方法都能实现，如果是真的系统开发，还是建议第3种方法 那我假如在main中为s4申请了内存，可我函数的输入只有三个常量字符串，咋在里面使用他呢？ 还有就是假如我位s4malloc了100位char的大小，那他和s4[100]有区别吗？

user: user-3
content: 1.使用malloc在堆上分配内存 2.可以考虑把字符串长度作为参数传进函数，或者换一门语言比如C++并使用vector 3.如果有关于2.)的更好的解决方案能提醒我感激不尽

user: user-0
content: #include <stdio.h> #include <stdlib.h> #include <stdbool.h>  struct node{ 	int data; 	struct node * next; };   struct node *  init(int data){ 	struct node * head = (struct node *)malloc(sizeof(struct node *)); 	struct node *  n = (struct node *)malloc(sizeof(struct node)); 	n->data = data; 	n->next = NULL; 	head = n; 	return head; }  void add2tail(struct node *  list, int data){ 	struct node *  n = list; 	while (n->next != NULL){ 		n = n->next; 	} 	struct node *  newnode = (struct node *)malloc(sizeof(struct node)); 	n->next = newnode; 	newnode->data = data; 	newnode->next = NULL; 	return; }  void print(struct node *  list){ 	struct node *  n = list; 	while (n != NULL){ 		printf("%d ", n->data); 		n = n->next; 	} 	printf("\n"); 	return; }  int main(void){ 	struct node *  head = init(123); 	print(head); 	add2tail(head, 7); 	print(head); 	system("pause"); 	return 0; }
user-0 提问: 小车发生反转，该左转往右转

回复:
user: user-1
content: 小车发生反转，该左转

user: user-2
content: 什么小车，什么程序？

user: user-3
content: 楼主，你这问题描述的太笼统了，看不懂啊。。。

user: user-4
content: 这是个什么问题，能说的清楚鞋吗？？
user-0 提问: 这个正则表达是怎么匹配？

回复:
user: user-1
content: [0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}
user-0 提问: c重定向

回复:
user: user-1
content: 比如在cmd下输入 > 可以将输出重定向到某个文件

user: user-2
content: 重定向不是C语言的功能，而是操作系统的功能，windows,Linux操作系统都支持重定向

user: user-3
content: 百度一下重定向就可以了，比如在控制台输入echo hello >c:\test.txt并回车，会把hello写到c盘根目录下的test.txt文件下
user-0 提问: 一个简单链表的改错，改了之后依然错，请指正

回复:
user: user-1
content: 谢谢，我调试了很多次，我看到p的值为要删除的值了，p=p->next，我以为连接上后面的结点了。原来是没有连接上。。

user: user-2
content: 用一个pre指针记录当前结点的前一个结点的地址，然后找到要删除的结点后，让pre->pNext指向p的后一个结点就行了（这里要考虑如果删除的是第一个结点，需要执行的应该是p_gHead = p->pNext）  #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> typedef int DATA; struct SNode { 	DATA data;//数据 	SNode*pNext;//指针区域 }; SNode*p_gHead = NULL; void AddHead(DATA data)//头曾 { 	SNode*p = (SNode*)malloc(sizeof(SNode)); 	p->data = data; 	p->pNext = p_gHead; 	p_gHead = p; } void Print()//大印 { 	SNode* p = p_gHead; 	while (p) 	{ 		printf("%d ", p->data); 		p = p->pNext; 	} } void AddList(DATA data)//尾曾 { 	SNode *p = p_gHead; 	while (p->pNext != NULL) 		p = p->pNext; 	SNode*pNew = (SNode*)malloc(sizeof(SNode));  	pNew->data = data; 	pNew->pNext = NULL; 	p->pNext = pNew; } void modif(DATA data, DATA dat)//链表修改 { 	SNode*p = p_gHead; 	while (p) 	{  		if (p->data == data) 		{ 			p->data = dat; 			break; 		} 		p = p->pNext;  	} } /*---------------------------------------------------------------------------------------*/ int  Delete(DATA data)//需要改错的地方 { 	SNode *p = p_gHead, *deltemp, *pre = p_gHead; 	while (p) 	{ 		if (p->data == data) 		{ 			deltemp = p; 			if (deltemp == p_gHead)//删除的是第一个结点 				p_gHead = p->pNext; 			else 				pre->pNext = p->pNext; 			free(deltemp); 			return 1; 		} 		pre = p; 		p = p->pNext; 	} 	return 0; } /*------------------------------------------------------------------------------------------------*/ int main() { 	AddHead(3); 	AddHead(2); 	AddHead(1); 	Print(); 	printf("\n"); 	modif(2, -888); 	Print(); 	printf("\n"); 	int i = Delete(-888); 	Print(); 	return 0; }
user-0 提问: 关于宏定义的非常重要的问题。。。

回复:
user: user-0
content: 用的宏定义,已经解决问题了，下面作为保留。  #define DEF_ADD_ZERO(ID,VALUE) memset (ID, 0x30, sizeof(ID) - 1 );ID[sizeof(ID) - 1] = 0x00; strncpy(ID + sizeof(ID) - strlen(VALUE) - 1, VALUE, strlen(VALUE));  调用时： 	char a2[8]; 	char a3[9];  	DEF_ADD_ZERO(a2,"1234"); 	DEF_ADD_ZERO(a3,"14");  结果：a2="0001234" , a3="00000014"

user: user-1
content: std::snprintf需要传递缓存长度, std::sprintf不用，所以我才说是“不安全”的嘛

user: user-2
content: 引用 5 楼 dustpg 的回复:[quote=引用 4 楼 adusuccessfully 的回复:] [quote=引用 3 楼 dustpg 的回复:] #include <iostream>  template<size_t T, class U> void def_add_zero(int d, U call) {     char buffer[T+1];     std::snprintf(buffer, T + 1, "%0*d", int(T), d);     call(buffer); }   int main() {     def_add_zero<5>(2, [](const char* buf) {         std::printf(buf);     });     return 0; }  请教下：你的程序我在VC上是会提示snprintf不是std的成员[/quote]  换编译器或者用稍微不安全的std::sprintf[/quote]  会报另一个错误：错误	1	error C2664: “sprintf”: 不能将参数 2 从“const size_t”转换为“const char *”

user: user-1
content: 引用 4 楼 adusuccessfully 的回复:[quote=引用 3 楼 dustpg 的回复:] #include <iostream>  template<size_t T, class U> void def_add_zero(int d, U call) {     char buffer[T+1];     std::snprintf(buffer, T + 1, "%0*d", int(T), d);     call(buffer); }   int main() {     def_add_zero<5>(2, [](const char* buf) {         std::printf(buf);     });     return 0; }  请教下：你的程序我在VC上是会提示snprintf不是std的成员[/quote]  换编译器或者用稍微不安全的std::sprintf

user: user-2
content: 引用 3 楼 dustpg 的回复:#include <iostream>  template<size_t T, class U> void def_add_zero(int d, U call) {     char buffer[T+1];     std::snprintf(buffer, T + 1, "%0*d", int(T), d);     call(buffer); }   int main() {     def_add_zero<5>(2, [](const char* buf) {         std::printf(buf);     });     return 0; }  请教下：你的程序我在VC上是会提示snprintf不是std的成员

user: user-1
content: #include <iostream>  template<size_t T, class U> void def_add_zero(int d, U call) {     char buffer[T+1];     std::snprintf(buffer, T + 1, "%0*d", int(T), d);     call(buffer); }   int main() {     def_add_zero<5>(2, [](const char* buf) {         std::printf(buf);     });     return 0; }

user: user-3
content: 这个长度和 sizeof 有什么关系？

user: user-1
content: c++自从出现了匿名表达式, 这些涉及到临时数组的东西简直易如反掌了.....
user-0 提问: fprintf运行问题

回复:
user: user-1
content: scanf_s在读取%c和%s的时候必须多指定一个参数用来指定读取的长度，否则必定无法读取成功

user: user-2
content: scanf_s函数的用法不对，应该加一个长度scanf_s("%d%s%lf", &account, name, 30, &balance);

user: user-3
content: 不会用_s函数就不要用啊，不要鸟微软，加个宏定义
user-0 提问: C语言返回地址的问题

回复:
user: user-1
content: 看了楼上的回答， 我总结下自己的看法不知道对不对 1、返回局部变量的指针（除静态变量），一般会出错，因为它在栈中，函数结束后空间会被回收利用。 2、返回动态内存指针（比如malloc），可正常使用。 因为它在堆中，不会因函数结束而回收。 3、返回常数及静态指针，比如楼主这里的字串常量。可正常使用。因为它在静态存储区。

user: user-2
content: return_2中的"2222"是个常量字符串，这个字符串被当作常量而且被放置在此程序的内存静态区，不会因为return_2调用结束就被销毁  而你的return_1返回的是局部变量的地址，所以发生什么都不要觉得奇怪。
user-0 提问: 谁能解释下多级指针（有点蒙了）！

回复:
user: user-1
content: 非得用三级指针这种东西吗，一般二级就够用了。 http://sysuor.blog.163.com/blog/static/8620131200832051039568/

user: user-2
content: 三]====>三

user: user-2
content: 所谓的级，其实就是间接引用的次数。 二级 整型指针，不能直接指向 整型对象。 三]级 整型指针，不能直接指向一级 整型指针。 只有一级 整型指针可以直接指向 整型对象。

user: user-2
content: 这个可以先从数组来理解，然后在改为动态分配的内存  int a[2][3][4]={ {{1,2,3,4},{5,6,7,8},{9,10,11,12}}, {{13,14,15,16},{17,18,19,20},{21,22,23,24}}, };  int *p =&a[0][0][0];//一级整型指针，直接指向整型对象 a[0][0][0];这样 *p 就是 a[0][0][0]; int **pp=&p;//二级整型指针，直接指向整型指针p, *pp就是 p; **pp 就是  a[0][0][0]; int ***ppp =&p;//三级指针指向二级指针pp， *ppp就是 pp,**ppp 就是p,***ppp 就是 a[0][0][0];  再看动态分配 int ***ppp= (int ***) malloc(sizeof(int **)* 2);//3级指针，分配一个二级指针数组，储存 2个二级指针 for(int i=0;i<2;i++){           *(ppp+i) = (int **) malloc(sizeof(int *)*3); //每个二级指针，分配3个一级指针，储存 3个一级指针 }  for(int i=0;i<2;i++){          for(int j=0;j<4;j++)         {                 *( *(ppp+i)+j) = (int **) malloc(sizeof(int)*4);//每个一级指针，分配4个整形对象，储存 4个整型数据。         }  }  ***ppp 就是 *(*(*ppp))) 也就是ppp指向 *ppp ,*ppp 指向 **ppp ,**ppp 指向***ppp; 通过三次间接引用，才能找到对应的整型对象 读取 ***ppp 要先读取 **ppp 读取 **ppp 又要 先读取 *ppp 这样 才能去去读 ***ppp 这个 对象。

user: user-3
content: 指针也是一种变量，只是其中保存的是地址。  如果x是指针，则*x表示该地址中的内容。  所谓二级、三级指针，只是这个内容本身还是地址而已

user: user-0
content: 引用 1 楼 user-3 的回复:除了***ppp外，p,*p,**p都是指针 这我知道  我不明白的是对于一个三级指针 **ppp 和*ppp 分别是什么意思  ，

user: user-3
content: 除了***ppp外，p,*p,**p都是指针
user-0 提问: 新手看不懂书，为什么最小的整数是0，为什么整数没有下溢？

回复:
user: user-1
content: 单说整数是可笑的，需要区分有符号和无符号

user: user-1
content: 讲一大堆没有用的  其实简单介绍以后，给一个完整的表格就完了

user: user-2
content: 引用 5 楼 lm_whales 的回复:类似的，浮点数溢出的定义为 非0 相乘，相除，结果为0 下溢（太小，精度丢失） 结果为正负 无穷， 上溢。（太大无法表示）； 参与运算的数，不是nan,inf 结果变成只能用inf 表示 相加减，结果为正负 无穷 ，上溢（太大无法表示）；参与运算的数，不是nan,inf 结果变成只能用inf 表示  浮点数，可以表示  无穷大（正负无穷大+inf,-inf），Nan 不是一个数（应该不止一个编码） 0 以及一定范围内的非0实数（其实是有理数）  PS： 用最大最小数值，定义溢出，就没有办法定义浮点数下溢了 ，，，，，，， 当然，用绝对值定义溢出，也没有法子表示无符号数之差为负数的情况。

user: user-1
content: 谭书或类似的书！最可恨了  自己胡乱总结或定义概念，关健还很多不对

user: user-2
content: 类似的，浮点数溢出的定义为 非0 相乘，相除，结果为0 下溢（太小，精度丢失） 结果为正负 无穷 上溢。（太大无法表示） 相加减，结果为正负 无穷 上溢（太大无法表示）

user: user-2
content: 这里说的应该是绝对值的溢出。 因此整数没有下溢。 不是数据类型的溢出。 小于绝对值最大的负数和大于最大值正数都为 上溢

user: user-3
content: 对整数，溢出指代数值：小于最小值为下溢，大于最大值为上溢 上溢：超出所能表示的最大正数 下溢：超出所能表示的最小负数 如16位整数范围为：-32768 ~ +32767，则当32767再加1时，发生上溢；当-32768再减1时，发生下溢。  对浮点数，溢出指绝对值：绝对值小于浮点数所能表示的最小值，为下溢，当作 0；绝对值大于浮点数所能表示的最大范围，为上溢，当作 INF。 根据具体符号的不同，又分为：正上溢、正下溢、负上溢、负下溢  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！

user: user-4
content: 这里说的没有错吧,  0 是最小的,所以没有下溢. 要是float 你要想用来表示0.0000000000000000000000000000000000000000000000001,那是表示了的,那就下溢,因为达不到那个精度.

user: user-5
content: 楼主这是什么书啊，可以扔了，我还没听过有最小的整数一说呢，计算机中的整数和浮点数表示的范围都是有限的，都会产生上溢和下溢，还有下面一段说的int表示范围较小，然后整数上溢在小型计算机中很常见，这也是扯淡，溢出是会发生，也应该注意，但真的在编程过程中溢出的情况肯定比得癌症的几率还低，哪儿有那么多大的数字要处理啊
user-0 提问: 学习C语言准备、执行过程、变量的定义与使用、常量的定义与使用、枚举的定义与使用、数组的定义与使用

回复:
user: user-1
content: 引用 1 楼 zhanghow 的回复：没人看，自己的日记我看我看

user: user-2
content: 日记写在博客里

user: user-0
content: 没人看，自己的日记
user-0 提问: PAT的段错误和格式错误问题   求救QAQ

回复:
user: user-0
content: 好像跟这个没关系，我把10改成100，还是这两个错误。。。而且如果是因为长度不够的话 应该是答案错误把。。。

user: user-1
content: struct jie {     char  ch[10]; }T[50000];  如果一个单词大于10个字节呢？
user-0 提问: HDU 5655 DZY loves playing balls 求答疑

回复:
user: user-0
content: 好的，谢谢！

user: user-1
content: 按照LZ的思路，需如下修改可AC： #include<stdio.h> #include<algorithm>  using namespace std;  int main() {   int t;   int a[1000];   scanf("%d",&t);   while(t>0)   {     int n,i;     scanf("%d",&n);     for(i=0;i<n;i++)     {       scanf("%d",&a[i]);     }     sort(a,a+n);     double k=0,d=0;     double p,q;     for(i=1;i<n;i++) //改 for(i=n-1;i>=1;i--)     {       if(a[i]>a[i-1])       {         p= static_cast<double>(i);         q= static_cast<double>(n);         d=p/(q*(q-1));       }       /*       当i为n-1时，a[i+1]超界，因此不能用a[i]==a[i+1]，要改为if(a[i]==a[i-1])。       但此时不能是d=d+d，而是沿用上次d的值。因此要删除以下代码       if(a[i]==a[i+1])       {         d=d+d;       }*/       k=k+d;     }     t--;     printf("%.6f\n",k);   }   return 0; }

user: user-0
content: 有人没？顶一下
user-0 提问: windows程序设计 [菜单-困扰很久的问题]

回复:
user: user-0
content: 已解决，多谢您的关注~！

user: user-0
content: 菜单用着用着就没了， 一般可能是什么原因？

user: user-0
content: 没有鼠标的响应事件，只是关于菜单的一个程序

user: user-1
content: 在你的程序中是否存在对鼠标事件的响应？
user-0 提问: 条件关系符的问题

回复:
user: user-1
content: 用scanf_s读%c和%s的时候，必须多传一个参数用来指定需要读入的长度  #include<stdio.h> #include<math.h> void main() { 	char ch; 	scanf_s("%c", &ch, 1); 	ch = (ch >= 'A'&& ch <= 'Z') ? (ch + 32) : ch; 	printf("%c\n", ch); }

user: user-2
content: 不会用_s函数就用原版的函数，这里_s函数需要在传递一个参数  既然用VS2015不看提示么:  1>c:\users\dust\documents\visual studio 2015\projects\project2\test\main.c(5): warning C4473: “scanf_s”: 没有为格式字符串传递足够的参数 1>  c:\users\dust\documents\visual studio 2015\projects\project2\test\main.c(5): note: 占位符和其参数预计 2 可变参数，但提供的却是 1 参数 1>  c:\users\dust\documents\visual studio 2015\projects\project2\test\main.c(5): note: 缺失的可变参数 2 为格式字符串“%c”所需 1>  c:\users\dust\documents\visual studio 2015\projects\project2\test\main.c(5): note: 此参数用作缓冲区大小

user: user-3
content: int main(void) { 	char ch; 	ch = getchar(); 	ch = ((ch >= 'A') && (ch <= 'Z')) ? (ch - 'A' + 'a' ) : ch; 	printf("%c\n", ch); 	return 0; }
user-0 提问: 请问调用函数时，实参类型可以不和形参类型一样吗？

回复:
user: user-1
content: 看一下数据类型隐式转化规则你就知道能不能转换了。

user: user-2
content: 指针的话，最好一致 注意 const形参通常可以用非const 反之一般不可以

user: user-3
content: 如果可以隐式转化，那就是可以，int和long是可以隐式转换的，但int*和long*是不可以的，所以编译器会报错 如果机器上int和long占的内存大小相同（一般是相同的），那可以采用类型转换（int*）来完成
user-0 提问: 关于vc++6.0连接多个文件问题？

回复:
user: user-0
content: 问题已经解决，我觉得@user-1讲解的挺好，是的注意

user: user-0
content: 怎么没人看啊！！！！！

user: user-1
content: Delete_Node 再修改下，   void Delete_Node(Node **head) {   Node *t, *p;    if(head)   {     t = *head;     while( t !=NULL)     {       p = t->next;       free(t);       t = p;     }     *head = 0;   } }

user: user-1
content: 我在XP VC6 下测试的正常， 可能是 VC6 与操作系统的兼容性问题？  按你的测试用例没有问题， 但是有即点可能要注意下   1 变量和指针尽量初始化， 这样不会导致Release 和 Debug的条件差异 2 如果 Input_Node  输入空元素的话， 可能会有访问冲突， Input_Node(0, 0, 0) 3 释放链表完了 指针应该清零， 避免 被再次使用到时误认为是有效的   //Node *pa = 0, *pb = 0;  // pa = Input_Node(0, a, 5); //初始化 // pa = Input_Node(pa, b, 6); //追加  //追加元素  Node * Input_Node(Node *head, DataType *a, int n) {   Node *p, *t;   int i;    p = head;   while(p && p->next) p = p->next; //找到尾端    //追加节点   for(i=0; a && i < n; i++)   {     t = (Node *)malloc(sizeof(Node));      t->data = a[i];     t->next = 0;     if(p)       p->next = t;     else       head = t; //head     p = t;   }    return head; }  //Delete_Node(&pa); void Delete_Node(Node **head) {   Node *t = *head, *p;    if(head)   {     t = *head;     while( t !=NULL)     {       p = t->next;       free(t);       t = p;     }     *head = 0;   } }

user: user-0
content: 再次通过使用dev c++编译器把<Node.h>这类包含改成"Node"，能完美运行的，但是VC++6.0还是不行的，问题是没有运行Node.cpp类的函数，不知道哪位大神解释下出现这种情况的原因！！！！！不要沉下去啊！！！！！！

user: user-0
content: 我测试的结果是，链表已经生成好的，但是在调用Print_Node()函数时，不管在函数里加入什么输出，没反应，感觉好像主函数没运行到似的，但是为什么运行了Input_Node()函数，，并且在主函数重写个Print_Node_2()函数,复制一样的代码，是能显示的，还有后面的Delete_Node()函数，会出现运行错误。放在主函数没问题。这就让人匪夷所思了？
user-0 提问: C语言课程设计：学生成绩系统

回复:
user: user-1
content: /*    return 0  :    return 1  : repeat    return -1 : illeage address */ int IfRepeat(struct Student *head,struct Student *stu) {                 int iFlag=0;        if( NULL==head ) 		return -1;        if( NULL==stu ) 		return -1;        for( ; (NULL!=head)&&( 1!=iFlag ); head=head->next )     	{                   if(head->num==stu->num)                   {                       iFlag=1;                  }         }                  return iFlag; }

user: user-2
content: int flag=0; 		while(head!=null) 		{ 			if(head->num==stu->num) 			{ 				flag=1; 				break; 			} 			else 			{ 				head=head->next; 			} 		} 		if (flag==0)  		{ 			printf("the num is unique!"); 		} 		else if (flag==1)  		{ 			printf("sorry,num is repeat") 		}
user-0 提问: C语言 字符读取问题

回复:
user: user-1
content: _kbhit()

user: user-2
content: 用select或者polling或者epoll，检查stdin的可读缓存

user: user-0
content: 或者并行计算，可以实现吗

user: user-0
content: 导致我的letime（）函数就不会输出当前剩余时间。

user: user-3
content: 把 c = getch()移动到另一个线程中去  具体办法： 1 写一个线程函数，开辟一个全局变量用于存放输入的字符 2 主线程中检查线程是否输入了字符

user: user-0
content: windows系统下，怎么处理呢
user-0 提问: free修改过的malloc指针会怎么样？

回复:
user: user-0
content: 引用 6 楼 max_min_ 的回复:可以写一个简单程序测试一下的 malloc出来的地址是要比你填进去的size要大，里面有一些需要管理的标志位 其一就是你说的free结束的标志位。 你好，我理解你的意思，用户让calloc分配40，暗地里它分配更多，多出的空间储存着大小等信息，free从中得知空间大小。 请问什么代码可获取calloc真正分配了多少内存？sizeof（指针）没用。

user: user-0
content: 引用 5 楼 yang004 的回复:直接会死机 *** glibc detected *** ./a.out: free(): invalid pointer: 0x00000000023af014 ***  从free()的源代码看，ptr只能指向可用空间的首地址，不然，减去结构体大小之后一定不是指向管理信息空间的首地 址。所以，要确保指针指向可用空间的首地址！  你好，我理解你的意思，让calloc分配40字节，其实它分配得更多，多出来的空间储存着大小等信息，free则从中得知空间大小。 但是以上代码在我pellesC没出错，不知为什么。

user: user-1
content: 据说 是放在返回给你 的 地址 之前 的 4个字节,但这是由系统决定的不同系统可能不一佯 转一个别人的文章 http://blog.csdn.net/a10615/article/details/41063063

user: user-2
content: 你敢随便释放malloc的返回的位置。 明确告诉你，结果是未知的。

user: user-3
content: void free(void *ptr) {    struct mem_control_block *free;              free = ptr - sizeof(struct mem_control_block);         free->is_available = 1;         return;     } 请参考源码

user: user-3
content: free释放malloc内存必须整体释放。

user: user-4
content: 可以写一个简单程序测试一下的  malloc出来的地址是要比你填进去的size要大，里面有一些需要管理的标志位  其一就是你说的free结束的标志位。

user: user-5
content: 直接会死机 *** glibc detected *** ./a.out: free(): invalid pointer: 0x00000000023af014 ***  从free()的源代码看，ptr只能指向可用空间的首地址，不然，减去结构体大小之后一定不是指向管理信息空间的首地 址。所以，要确保指针指向可用空间的首地址！

user: user-6
content: 引用 7 楼 c_s_d_n_l_a_m 的回复:请问free()的源代码从哪里来的？我还想看看其它库函数的源代码。 c 语言手册中好像有函数源码

user: user-7
content: 请问free()的源代码从哪里来的？我还想看看其它库函数的源代码。

user: user-8
content: p1只移动4个字节，是因为它是int * malloc实际占用的空间一定是大于你申请的字节数，因为在申请的空间周围需要存放内存管理信息以及调试信息 如果只有申请的空间，那么编译器free时又怎么可能知道该释放多少字节呢？

user: user-0
content: 这也引出我另一个疑问。malloc返回是指针只能说明malloc开始位置，malloc多大指针并不知道。free一个指针，C语言如何保证刚刚好把malloc的内存块释放？
user-0 提问: 求修改c语言 多线程server 代码！！

回复:
user: user-1
content: 另外楼主你的While(1)，你想过没有，他里面有跳出循环的条件没有？

user: user-1
content: int main (int argc, char *argv[])   {      int client;         /* client socket descriptor */      int addr_len;       /* used to store length (size) of sockaddr_in */      pthread_t thread;   /* thread variable */    //............... } 试着把client放到你Accept接受客户端连接监听的While循环里头去
user-0 提问: c数组输入/出问题

回复:
user: user-0
content: 引用 1 楼 qq423399099 的回复:你第一种形式，只给name和num各1个字节的空间，这怎么够？ 因为字符串还需要放入'\0',所以至少各需要2个字节  谢谢qq423399099 ，刚才试了一下2个字节的，能输出正确结果，看来还是我的基本工不到家啊

user: user-1
content: 你第一种形式，只给name和num各1个字节的空间，这怎么够？ 因为字符串还需要放入'\0',所以至少各需要2个字节
user-0 提问: 用C语言编写聊天程序，

回复:
user: user-0
content: 引用 4 楼 cyfcsd 的回复:[quote=引用 3 楼 qq_23152513 的回复:] [quote=引用 1 楼 cyfcsd 的回复:] 这个跟你的程序有关系吧，我记得上次做为了实现两边可以自由收发，用了两个线程分别监视两个端口 我只用了一个端口，这种情况下，可以实现自由收发吗？可不可以推荐一下合适的代码呢？[/quote] 以前用java写的，你要可以发给你[/quote] 好的，谢谢你了

user: user-1
content: 引用 5 楼 qq_23152513 的回复:[quote=引用 4 楼 cyfcsd 的回复:] [quote=引用 3 楼 qq_23152513 的回复:] [quote=引用 1 楼 cyfcsd 的回复:] 这个跟你的程序有关系吧，我记得上次做为了实现两边可以自由收发，用了两个线程分别监视两个端口 我只用了一个端口，这种情况下，可以实现自由收发吗？可不可以推荐一下合适的代码呢？[/quote] 以前用java写的，你要可以发给你[/quote] 好的，谢谢你了[/quote] qq邮箱？23152513是吗？

user: user-2
content: 聊天室就是一次一次广播的啊，你一次可以只发一句话，也可以两句，三句。。。你这个问法好搞笑

user: user-1
content: 引用 3 楼 qq_23152513 的回复:[quote=引用 1 楼 cyfcsd 的回复:] 这个跟你的程序有关系吧，我记得上次做为了实现两边可以自由收发，用了两个线程分别监视两个端口 我只用了一个端口，这种情况下，可以实现自由收发吗？可不可以推荐一下合适的代码呢？[/quote] 以前用java写的，你要可以发给你

user: user-0
content: 引用 1 楼 cyfcsd 的回复:这个跟你的程序有关系吧，我记得上次做为了实现两边可以自由收发，用了两个线程分别监视两个端口 我只用了一个端口，这种情况下，可以实现自由收发吗？可不可以推荐一下合适的代码呢？

user: user-0

user: user-1
content: 这个跟你的程序有关系吧，我记得上次做为了实现两边可以自由收发，用了两个线程分别监视两个端口
user-0 提问: xcode中用c语言部分函数报隐式声明错误（非警告）

回复:
user: user-0
content: 是Header search Path没有设置对的问题么？也不对，函数的定义是可以找到的，有没有大神啊拉一把

user: user-0
content: 这些函数写在这里又有什么意义？
user-0 提问: C语言头插入链表问题

回复:
user: user-1
content: 引用 2 楼 fivezero50的回复:[quote=引用 1 楼 zycxnanwang 的回复:] 我来解释一波！ 首先你是用head指针作为形参，函数调用的时候 将会生成一个指针，把head地址上的内容赋给 生成指针，最后的时候你只是将insert的地址赋 给函数生成的指针，函数调用完，指针就delete 所以你的主函数里面的head指针还是指向原来的 地址，你调试可以验证一下！ 所以，我觉得你要想改变函数参数内容，最好用引用！  我所学的知识里，只要传指针给函数，然后就可以改变该指针所指的值，比如： int x =2; void change(int *var) { *var = 3; } int main() { change(&x) printf("%d",x); } 同理，我穿进去的是指针head，为什么就不能改变head的值[/quote] *var=3 你只是将3赋值给指针var指向的内容，var 指向的内容坑定就变了！指针的改变和指针指向内容的改变是不同的！

user: user-2
content: 你要改变指针的指向，必须传二级指针或者一级指针的引用。 单单传一级指针只能改变指针所指向的内存区域的值。

user: user-3
content: 改为 void add_node_to_head_2(NODE **head, NODE *insert) {     NODE *tmp = *head;     insert->next = tmp;     *head = insert;  调用 add_node_to_head_2(&head, insert); }  因为你是想改变指针指向的地址，单单只传指针是没用的，这样做最多只能改变指针内容，只有传入指针的指针，才能改变指针的指向。

user: user-0
content: 我改变如下： void add_node_to_head_2(NODE *head,NODE *insert)//this function is NG { 	NODE *tmp = head; 	insert->next = tmp; 	*head = *insert; } 结果还是不行，打印结果成了死循环。 最后我请教了大神，改成这样就行了: void add_node_to_head_2(NODE **head,NODE *insert)//this function is NG { 	NODE *tmp = *head; 	insert->next = tmp; 	*head = insert; }

user: user-0
content: 引用 1 楼 zycxnanwang 的回复:我来解释一波！ 首先你是用head指针作为形参，函数调用的时候 将会生成一个指针，把head地址上的内容赋给 生成指针，最后的时候你只是将insert的地址赋 给函数生成的指针，函数调用完，指针就delete 所以你的主函数里面的head指针还是指向原来的 地址，你调试可以验证一下！ 所以，我觉得你要想改变函数参数内容，最好用引用！  我所学的知识里，只要传指针给函数，然后就可以改变该指针所指的值，比如： int x =2; void change(int *var) { *var = 3; } int main() { change(&x) printf("%d",x); } 同理，我穿进去的是指针head，为什么就不能改变head的值

user: user-1
content: 我来解释一波！ 首先你是用head指针作为形参，函数调用的时候 将会生成一个指针，把head地址上的内容赋给 生成指针，最后的时候你只是将insert的地址赋 给函数生成的指针，函数调用完，指针就delete 所以你的主函数里面的head指针还是指向原来的 地址，你调试可以验证一下！ 所以，我觉得你要想改变函数参数内容，最好用引用！
user-0 提问: Ds1302控制字在C语言中怎样生成的

回复:
user: user-1
content: 函数在哪里调用 addr就在哪里给了值

user: user-2
content: void Ds1302Write(uchar addr, uchar dat) //函数声明 Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);//函数调用	  addr<===> WRITE_RTC_ADDR[n] dat<===>TIME[n]  函数调用时候，会用实参表达式，初始化形参变量
user-0 提问: 不理解指针的问题

回复:
user: user-1
content: 大部分编译器对于常量区的字符串都是禁止进行写操作的。 只有堆栈上申请的字符串才能修改。

user: user-2
content: char *num="0"  num指向的内容是常量，不能改 式子等同于 const char *p="0";
user-0 提问: C语言怎么直接预览U盘根目录文件内的特定文件

回复:
user: user-1
content: 先遍历，取出所有文件名，输出。

user: user-2
content: C语言遍历文件和目录 ： http://www.2cto.com/kf/201302/187924.html  遍历过程中记录你需要的文件
user-0 提问: 初学C程序一直过不去，求debug

回复:
user: user-1
content: char *p[50], *s[50], temp[50], x = '\o';  /*用一个数组来接收缓存区里的字符*/ 	int i = 0, type;  	printf("Direction: \nEnter a string of secret words that include numbers and words, \nwhich both less than 50. \nAnd end with Enter:\n");  	while ((temp[i] = getchar()) != '\n') 	{  		if ('0' <= temp[i]&&temp[i] <= '9') 		{ 			p[f] = &temp[i];  /*指针需要对应到具体字符的地址才行，不能全都指向temp的地址*/ 			cnp[f] = i + 1; 			f++; 		} 		else 		{ 			s[e]=&temp[i]; 			ctp[e] = i + 1; 			e++; 		} 		i++; 	} 你声明的指针数组p和s，里面的每一个数组元素都是指针，按照你的代码，这些指针全都指向的是temp的地址，当然输入会有问题了

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

user: user-3
content: 哪儿过不去啊，注释的那部分吗，没注释的那些没问题啊

user: user-0
content: 引用 4楼user-4 的回复:这个程序要实现什么功能呢对输入的数字和字母进行加密

user: user-4
content: 这个程序要实现什么功能呢

user: user-0
content: 引用 1楼flying_music 的回复:哪儿过不去啊，注释的那部分吗，没注释的那些没问题啊就是输入的部分，输入的数和字母进不到数组里
user-0 提问: 运行出错

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

user: user-2
content: printf 里的 %n 改成 %d

user: user-0
content: 引用 1 楼 user-2 的回复:p_line_num没有初始化就使用了  int ch_num=0,line_num=0,p_line_num=0,ph_num=0; 改了之后也会运行报错

user: user-2
content: p_line_num没有初始化就使用了  int ch_num=0,line_num=0,p_line_num=0,ph_num=0;
user-0 提问: 怎么用纯c做图像程序

回复:
user: user-1
content: 有人推荐SDL

user: user-2
content: 最简单的EasyX，兼容Turbo C绘图函数，用于VC。

user: user-3
content: 仅供参考：#pragma comment(lib,"user32") #pragma comment(lib,"gdi32") #include <stdio.h> #include <stdlib.h> #include <windows.h> HWND WINAPI GetConsoleWindow(); void HideTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);      if(GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = FALSE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } void ShowTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);      if(GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = TRUE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } int main() {     HWND  hwnd;     HDC   hdc;     HFONT hfont;      system("color F0");     system("cls");     HideTheCursor();     hwnd  = GetConsoleWindow();     hdc   = GetDC(hwnd);     hfont = CreateFont(48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "华文楷体");     SelectObject(hdc,hfont);     TextOut(hdc,10,10,"地球人都知道！",14);     MoveToEx(hdc,5,5,NULL);     LineTo(hdc,300,  5);     LineTo(hdc,300, 60);     LineTo(hdc,  5, 60);     LineTo(hdc,  5,  5);     DeleteObject(hfont);     ReleaseDC(hwnd,hdc);     getchar();     system("color 07");     system("cls");     ShowTheCursor();     return 0; }
user-0 提问: 关于字符串的问题求大神解答

回复:
user: user-1
content: for(int j=0;j<2;j++)             {                 a[j]=itoa(b[j],str, 10);                 d[i][j]=a[j];                          }         d[i][0]=q[i];  d[i][0]重复赋值 15被覆盖掉了

user: user-0
content: 话是没错，但是我弄了挺长时间，搞不清楚问题在哪，还请赐教了

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

回复:
user: user-1
content: realloc()的源码哪儿来的？看注释明显不是官方版本啊

user: user-2
content: 看一下realloc的实现源码就明白了： void *realloc(void *ptr, size_t size) { 	struct free_arena_header *ah; 	void *newptr; 	size_t oldsize;  	if (!ptr) 		return malloc(size);  	if (size == 0) { 		free(ptr); 		return NULL; 	}  	/* Add the obligatory arena header, and round up */ 	size = (size + 2 * sizeof(struct arena_header) - 1) & ARENA_SIZE_MASK;  	ah = (struct free_arena_header *) 	    ((struct arena_header *)ptr - 1);  	if (ah->a.size >= size && size >= (ah->a.size >> 2)) { 		/* This field is a good size already. */ 		return ptr; 	} else { 		/* Make me a new block.  This is kind of bogus; we should 		   be checking the following block to see if we can do an 		   in-place adjustment... fix that later. */  		oldsize = ah->a.size - sizeof(struct arena_header);  		newptr = malloc(size); 		memcpy(newptr, ptr, (size < oldsize) ? size : oldsize); 		free(ptr);  		return newptr; 	} } 从代码看，如果新分配的newsize小于之前的oldsize，那么也只拷贝newsize这么多，拷贝完之后就释放掉原来的ptr，返回新的newptr。这样，就会造成数据的截断，但并不会所谓“自由区域”或“野指针”。

user: user-2
content: 看一下realloc的实现源码就明白了： void *realloc(void *ptr, size_t size) { 	struct free_arena_header *ah; 	void *newptr; 	size_t oldsize;  	if (!ptr) 		return malloc(size);  	if (size == 0) { 		free(ptr); 		return NULL; 	}  	/* Add the obligatory arena header, and round up */ 	size = (size + 2 * sizeof(struct arena_header) - 1) & ARENA_SIZE_MASK;  	ah = (struct free_arena_header *) 	    ((struct arena_header *)ptr - 1);  	if (ah->a.size >= size && size >= (ah->a.size >> 2)) { 		/* This field is a good size already. */ 		return ptr; 	} else { 		/* Make me a new block.  This is kind of bogus; we should 		   be checking the following block to see if we can do an 		   in-place adjustment... fix that later. */  		oldsize = ah->a.size - sizeof(struct arena_header);  		newptr = malloc(size); 		memcpy(newptr, ptr, (size < oldsize) ? size : oldsize); 		free(ptr);  		return newptr; 	} } 从代码看，如果新分配的newsize小于之前的oldsize，那么也只拷贝newsize这么多，拷贝完之后就释放掉原来的ptr，返回新的newptr。这样，就会造成数据的截断，但并不会所谓“自由区域”或“野指针”。

user: user-3
content: realloc函数，如果原来的内存后面还有足够多剩余内存，或者，重新分配小于原来的大小，realloc还是返回原来内存的地址; 因此地址不会变化，但后面的区域成为自由区域，也就是常说的“野指针”。野指针地址在没有被重新使用和占用的情况下，值是不变的，你按照野指针强制访问，会得到原有的值。 但野指针地址内的值无法保障，如果你在realloc之后malloc一堆指针，那么无法保障这个野指针的值不变，可能会被重新占用。

user: user-4
content: 这种问题 看源码是最好的方案 对提升c功底很有好处

user: user-5
content: 有可能导致数据丢失。。

user: user-6
content: 后果就是可能造成数据丢失，假如用calloc分配20个字节，写入20个字节的数据， 然后用realloc重新分配为10个字节，则之前写入的20个字节数据可能丢失后10个字节的数据。
user-0 提问: 杭电ACM1718，为什么不能AC？

回复:
user: user-0
content: 调整了一下可以通过了，没有初始化

user: user-0
content: #include <stdio.h> #include <string.h>  struct stu  {  char num[9];  int score;  };   void main()  {  int n=0,k,rand;  struct stu st[1001],s;  while(scanf("%s",s.num)!=EOF)  {  while (1)  {   scanf("%s %d",st[n].num,&st[n].score);  if(strcmp(st[n].num,s.num)==0)  {  s.score=st[n].score;k=n;  }  if(strcmp(st[n].num,"0")==0&&st[n].score==0)  break;  n++;  }  n--; rand=n;  while(n>=0)  {  if(n!=k&&st[n].score<=s.score)  {  rand--;  }  n--;  }  printf("%d\n",rand+1);  }  } 改了，但是还是不对，我的思路是，找到比该人的成绩低的减一，不是加一

user: user-1
content: 抱歉~打错字符了，应该是scanf("%s",s.num);不是scanf("%d",s.num);

user: user-1
content: 你的字符数组scanf("%s",&s.num);都写错了，s.num本来就是地址，还需要取地址吗？应该是scanf("%d",s.num); 同时注意题目要求是“多组数据” ！！这个题目比较简单，我就不上代码了，来分析一下你的问题！       你的思路是:找出成绩比该人成绩高的人的个数然后再加1。       代码的具体实现可以通过排序(直接sort()最简单)，然后再循环遍历找到目标学号所对应的人，根据其下标就可以得出结果！还可以在读入数据的时候，将目标学号对应的分数记下来，然后再循环遍历记录比该人成绩高的学生的个数，然后都出结果！
user-0 提问: 数据结构 线性表

回复:
user: user-1
content: #include<stdio.h> #include<stdlib.h>  typedef int datatype; #define MAXLEN 20  typedef struct { 	datatype data[MAXLEN]; 	int last; }SeqList;  SeqList* CreatSeqList() { 	int x, i = 0; 	SeqList *P = (SeqList *)malloc(sizeof(SeqList)); 	P->last = 0; 	scanf("%d", &x); 	while (x != -1) 	{ 		P->data[i] = x; 		i++; 		P->last++; 		scanf("%d", &x); 	} 	return P; }  void ShowSeqList(SeqList* L) { 	int i; 	for (i = 0; i<L->last; i++) 		printf("%d ", L->data[i]); }  int main() { 	SeqList *L; 	L = CreatSeqList(); 	ShowSeqList(L); 	return 1; }
user-0 提问: c语言简易英文文本编辑器的程序，运行有错误

回复:
user: user-0
content: 这是主函数的调佣情况 	case 2:system("cls"); 			Welcome(); 			printf("\t\t\t请输入您需要删除的字符或字符串："); 			getchar(); 			gets(str2); 			Searchtext(str2,temp); 			Deletetext(str2); 			Displaytext(); 			printf("按回车键继续……"); 			getchar(); 			getchar(); 			system("cls"); 			break;

user: user-0
content: 怎么调试我知道的。可是我就想知道是这个函数错了还是怎么，其它的函数调用显示文本函数时显示出来的文本也是不正确的， void Displaytext() {    	int i,j; 	 	Linklist *p; 	p=head->next; 	system("cls"); 	Welcome(); 	printf("当前文本的内容是：\n");     FILE *fp; 	if((fp=fopen("bcd.txt","w"))==NULL) 	{ 		printf("No open!\n"); 		exit(0); 	}  	for(j=0;p!=NULL;j++)//控制行 	{ 		for(i=0;(i<80)&&(p->data[i])!='#';i++)//控制列 		{ 			printf("%c",p->data[i]); 			fprintf(fp,"%c",p->data[i]);	 		} 		p=p->next; } 	fclose(fp); }

user: user-1
content: Windows： 崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。 Linux： 进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’ 使用命令 gdb 运行程序名 core或core.数字 进入gdb然后使用bt命令 可以查看进程意外退出前函数调用的堆栈，内容为从上到下列出对应从里层到外层的函数调用历史。 如果进程意外退出不产生core文件，参考“ulimit -c core文件最大块大小”命令  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

user: user-0
content: 删除we之后的结果如下，出现了不知道为什么的错误，

user: user-0
user-0 提问: c语言中非正数就是代表假吗

回复:
user: user-1
content: 早期的C语言标准中并没有规定bool类型以及true和false的值，这些值都是程序员自己用#define或者enum自己定义的，一般定义true为1，false为0。而如果着眼于C语言标准，总结一下其中的“假”有以下几种形式： 1. 通过逻辑运算符得到的结果，可以是真或者假。例如 (a < 3) && ( a > 0) 2. 通过关系运算符得到的结果，可以是真或者假。例如 a < 3 3. 还有一种就是更自由的形式。例如 char *p = (char *) malloc(10); if (fp) {} 这里fp直接就被用来作为逻辑值了。其实这里的fp等价于fp != NULL。 也就是这种情况下一般是“零值”（整数0，逻辑表达式或者关系表达式的“假”，或者是空指针，这些都可以看做C语言中的零值）被当做假，非零值就是真。  如果需要确切知道真或者假对应的整型值是0，整数还是负数，可以自己编个程序打印出来测试一下就可以了，例如： int a = 4; printf("%d\n", a < 3);  不同编译器的结果可能不同。

user: user-2
content: c语言中除了0其他都是真…

user: user-3
content: 0为假，其余为真。

user: user-4
content: 非0为真，0为假。 记住这句话就好了 还有 !8  !5是假。 因为8 和5 是真，他们的非就是假啦。

user: user-5
content: 0才是假，而不是负数

user: user-6
content: 是的，是假  但 ~运算符 则不一定

user: user-7
content: C 中 !(-1),!(-2),!(1),!(2) 都是 假 ，也就是 0 !0 为真 -1,-2,1,2 都是真（作条件时，相当于转换为 1）,0 为假   浮点数，也跟整数相似

user: user-7
content: C中，非0 代表真，0 代表假
user-0 提问: 关于自动退栈

回复:
user: user-1
content: 我现在还不知道 hello 的长度等于多少，我把它交给 1 + mystrlen(ello) 我现在还不知道 ello 的长度等于多少，我把它交给 1 + mystrlen(llo) 我现在还不知道 llo 的长度等于多少，我把它交给 1 + mystrlen(lo) 我现在还不知道 lo 的长度等于多少，我把它交给 1 + mystrlen(o) 我现在还不知道 o 的长度等于多少，我把它交给 1 + mystrlen() 递归到了"\0"串了，返回空串的长度等于0，这个出口很重要，避免了函数的死循环 现在我知道 o 的长度等于 1 现在我知道 lo 的长度等于 2 现在我知道 llo 的长度等于 3 现在我知道 ello 的长度等于 4 现在我知道 hello 的长度等于 5

user: user-1
content: // Note:Your choice is C++ IDE #include <iostream> using namespace std;  int mystrlen(const char *s) { 	if(*s=='\0') 	{ 		printf("递归到了\"\\0\"串了，返回空串的长度等于0，这个出口很重要，避免了函数的死循环\n"); 		return 0; 	} 	printf("我现在还不知道 %s 的长度等于多少，我把它交给 1 + mystrlen(%s)\n",s,s+1); 	int len=mystrlen(s+1)+1; 	printf("现在我知道 %s 的长度等于 %d\n",s,len); 	return len; } int main() { 	mystrlen("hello");          return 0; }

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

user: user-3
content: 单步跟踪程序运行是最好判断你理解正确与否的方法

user: user-1
content: 你要理解strlen(s+1)是什么？ 第一次调用：strlen("ello") 第五次返回：3+1=4 第二次调用：strlen("llo") 第四次返回：2+1=3 第三次调用：strlen("lo") 第三次返回：1+1=2 第四次调用：strlen("o")  第二次返回：0+1=1 第五次调用：strlen("\0") 第一次返回：0 最后return (*s ? strlen(s+1) +1 :0) ;// *s='H'，所以返回4+1=5
user-0 提问: 大家好，请问C语言怎么判断浏览器打开的网址？

回复:
user: user-1
content: 引用 11 楼 yyxgs 的回复:[quote=引用 10 楼 u010165006 的回复:] [quote=引用 3 楼 yyxgs 的回复:] [quote=引用 1 楼 u010165006 的回复:] 绿坝不是有类似的功能吗？应该是Hook钩子技术吧。  获取窗口句柄然后判断标题行不行呢?[/quote]  如果网址还没有打开，是没有标题的吧[/quote]  这个我已经解决了，但是我想自己打开本地的网页还得自己做相似的网页，所以算了。。[/quote]  做个最简单的测试网页。

user: user-0
content: 引用 10 楼 u010165006 的回复:[quote=引用 3 楼 yyxgs 的回复:] [quote=引用 1 楼 u010165006 的回复:] 绿坝不是有类似的功能吗？应该是Hook钩子技术吧。  获取窗口句柄然后判断标题行不行呢?[/quote]  如果网址还没有打开，是没有标题的吧[/quote]  这个我已经解决了，但是我想自己打开本地的网页还得自己做相似的网页，所以算了。。

user: user-1
content: 引用 3 楼 yyxgs 的回复:[quote=引用 1 楼 u010165006 的回复:] 绿坝不是有类似的功能吗？应该是Hook钩子技术吧。  获取窗口句柄然后判断标题行不行呢?[/quote]  如果网址还没有打开，是没有标题的吧

user: user-1
content: 明天等老师、高手教你方法，应该不是很简单。

user: user-0
content: 引用 6 楼 u010165006 的回复:[quote=引用 5 楼 yyxgs 的回复:] [quote=引用 4 楼 u010165006 的回复:] 你不会自己想做这个吧？应该不容易吧，改Windows的hosts配置文件不知能否达到目的。 你的Java学到哪里了？  接口，我现在急需要这个判断浏览器打开的网址，然后转到我本地的网页的程序。 请问你知道怎么编程获取浏览器的窗口句柄吗?[/quote]  查找窗口（FindWindow、FindWindowEx）？ [/quote]   知道了，非常感谢！

user: user-0
content: 引用 6 楼 u010165006 的回复:[quote=引用 5 楼 yyxgs 的回复:] [quote=引用 4 楼 u010165006 的回复:] 你不会自己想做这个吧？应该不容易吧，改Windows的hosts配置文件不知能否达到目的。 你的Java学到哪里了？  接口，我现在急需要这个判断浏览器打开的网址，然后转到我本地的网页的程序。 请问你知道怎么编程获取浏览器的窗口句柄吗?[/quote]  查找窗口（FindWindow、FindWindowEx）？ [/quote]  关键是我也不知道类名这些的，参数不知道怎么给。。

user: user-1
content: 引用 5 楼 yyxgs 的回复:[quote=引用 4 楼 u010165006 的回复:] 你不会自己想做这个吧？应该不容易吧，改Windows的hosts配置文件不知能否达到目的。 你的Java学到哪里了？  接口，我现在急需要这个判断浏览器打开的网址，然后转到我本地的网页的程序。 请问你知道怎么编程获取浏览器的窗口句柄吗?[/quote]  查找窗口（FindWindow、FindWindowEx）？

user: user-0
content: 引用 4 楼 u010165006 的回复:你不会自己想做这个吧？应该不容易吧，改Windows的hosts配置文件不知能否达到目的。 你的Java学到哪里了？  接口，我现在急需要这个判断浏览器打开的网址，然后转到我本地的网页的程序。 请问你知道怎么编程获取浏览器的窗口句柄吗?

user: user-1
content: 你不会自己想做这个吧？应该不容易吧，改Windows的hosts配置文件不知能否达到目的。 你的Java学到哪里了？

user: user-0
content: 引用 1 楼 u010165006 的回复:绿坝不是有类似的功能吗？应该是Hook钩子技术吧。  获取窗口句柄然后判断标题行不行呢?

user: user-0
content: 引用 1 楼 u010165006 的回复:绿坝不是有类似的功能吗？应该是Hook钩子技术吧。  好吧，看来挺麻烦。

user: user-1
content: 绿坝不是有类似的功能吗？应该是Hook钩子技术吧。
user-0 提问: 关于函数指针的理解

回复:
user: user-0
content: 谢谢各位的回复

user: user-1
content: p();  调用函数，函数指针调用函数是不需要解引用， 但不是：不可以解引用  所以有了(*p)()的出现。。。  解引用还是函数指针，有点特殊  (**p)() 如何解释？？、  解引用两次， *p是函数指针，* *p 还是函数指针  ***p依然是函数指针

user: user-2
content: 没什么奇怪啊，函数指针解引了还是函数指针  上面式子还等于 ***************p

user: user-3
content: 引用 2 楼 Happy_BC 的回复:试了下，int * q;         q=(int *)p;     然后发现*q有一个值,  这就是指令数据吗？ 对，就是那么个意思，但不一定是max函数的代码，跟编译器的实现有关，可能放一条跳转语句，跳转到max函数入口

user: user-0
content: 试了下，int * q;         q=(int *)p;     然后发现*q有一个值,  这就是指令数据吗？

user: user-3
content: 指针是一种特殊的数据类型，你可以理解它有很多“子类型”，也就是int*和double*是不一样的，指向函数的指针也是不一样的，这里说的不一样不是值不一样，而是类型不一样，类型不一样就体现在运算符作用在它身上时效果不一样，你对一个int型指针解引用，也就是*p得到的就是指向的那个int变量，但你对一个指向函数的指针解引用得到的还是那个入口地址 就本例来说，你定义了一个函数，这个函数的入口地址假如是0x0001，那p作为一种指针，指向这个函数，也就是说p里面放的是0x0001，但p的地址（&p）不是，p是一个指针变量，它的地址是编译器分配的，比如是0x0011，也就是说0x0011的地址内存里放着一个0x0001，而*p该是什么呢？对应int型指针，那是里面放的int变量，但函数指针不是，函数入口放的是代码，怎么能把代码给你呢，所以编译器仍然把*p当做p来使用，那个max也是一样，不过max不是一个变量，只有变量才可以取地址&，但编译器也没有报错，仍然把它当做max来处理 总之，&p，p，*p的关系是由p的类型决定的，至于为什么不让&max这种东西报错，那就是编译器实现的人考虑的问题了，还有，理解指针必须和内存联系起来，没有内存的概念，很难理解透彻的
user-0 提问: 问一个C下面scanf的问题……

回复:
user: user-1
content: 缓冲区中没内容才会等待输入，有内容就直接取了

user: user-2
content: 引用 1 楼 qq423399099 的回复:如果输入缓冲区内有数据，scanf是不会等待输入的。  新知识get。

user: user-3
content: 如果输入缓冲区内有数据，scanf是不会等待输入的。
user-0 提问: 保留小数问题

回复:
user: user-1
content: 不用整数或浮点数来读, 用字符串来读然后输出就是原样了

user: user-2
content: scanf("%c",&a[i][j]);

user: user-3
content: 定义一个字符串数组，先将数赋值给数组元素 然后输出字符串数组

user: user-0
content: #include<stdio.h> int main() { 	int i,j,N; 	scanf("%d",&N);  	char a[10][40]={'0'}; 	 	for(i=0;i<N;i++){ 		for(j=0;j<10;j++){ 			scanf("%s",&a[i][j]); 		} 	//	getchar(); 	} 	for(i=0;i<N;i++){ 		for(j=40;j>0;j--){ 			if(a[i][j]!=' ' && a[i][j]!='0' && (a[i][j]>'9' || a[i][j]<'0')) 				printf("%s",a[i][j]); 			printf("\n"); 		} 	}  	return 0; } 这是我的程序，但是一直在输入状态
user-0 提问: 请问别人用C语言写了一个小工具，可是每次都要输入他生成的验证码，还是图片里面那种很杂乱的，很难看清楚，请问汇编可以反汇编这个程序，跳过这个输入验证码的步骤吗？

回复:
user: user-1
content: 去看雪论坛逛逛。

user: user-2
content: 理论上用跳转指令可以绕过这个过程，或者改变验证过程的结果，结果为不通过时继续。

user: user-3
content: IDA, OD分析去吧．

user: user-4
content: 理论上可以，实践中要看它加密的复杂度了，可能很简单，分分钟搞定，也可能很复杂，比如把关键部分代码转换为虚拟机程序，这种就比较难搞。一般来说，如果没用加密狗，或者联网验证，都可以搞定。
user-0 提问: 请问大家，Windows上我用C语言分配一段内存空间，输出的这些地址都是虚拟地址吗？那我要找到真实地址怎么找呢？

回复:
user: user-1
content: 使用WinIO.sys

user: user-2
content: 已知一个虚拟地址0x01AF5518, 则转换的过程如下:  注意: *这里讨论的以Windows下普通模式分页的情况, 也就是2级页表的情况*  1.首先把虚拟地址拆分成3个部分(低12位, 中10位, 高10位), 换成2进制如下: 　　-> 0000 0001 1010 1111 0101 0101 0001 1000   　　按照10, 10, 12的位数重新排列后 　　-> (页目录索引)00 000 00110, (页表项索引)10 1111 0101, (偏移)0101 0001 1000  　　换算成十六进制后可以得到如下结果 　　页目录索引 = 6, 页表项索引 = 0x2f5 , 偏移 = 0x518  2.	根据当前的CR3寄存器中的物理地址定位页目录表基址 　　Cr3中存放的是物理地址, 这个物理地址指向进程的页目录表基址, 由此可以得到 　　页目录表基址(PDE) = Cr3 = 0xAA0E5000  3. 计算页表项的地址 　　页表地址存放在页目录表(PDE)中的第6个项目中, 也就是 　　[0xAA0E5000 + 4 * 6] = [0xAA0E5018] = 0x3D955867, 其中0x00000867为该页表属性值, PTE = 0x3D955000	  3.	计算页面物理地址 　　我们要找的页面在这个页表中的第0x2f5项, 所以虚拟地址所在的页的物理地址为 　　[0x3D955000 + 0x2f5 * 4] = [0x3D955BD4] =  　　假设[0x3D955BD4] = 0x7095e847, 页面的物理地址 x0x7095e000, 0x00000847表示的是页面属性  4.	计算最终的物理地址 　　由虚拟地址分离的偏移可以计算出最终的物理地址为  　　0x7095E000 + 0x00000518 = 0x7095E518.
user-0 提问: c语言与与hmi的串口通信（232）不能正确实现功能，求助

回复:
user: user-1
content: 仅供参考：void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             printf("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         printf("%s\n",binstr);     } }
user-0 提问: 二叉树的遍历

回复:
user: user-0
content: 看来c语言真该好好的复习复习了，谢谢！

user: user-1
content: 1.CreateBiTree函数应该传二级指针或者一级指针的引用才行 2.第23行T == NULL;应该是*T = NULL;   #include<stdio.h> #include<stdlib.h> typedef struct BiTNode{ 	char data; 	struct BiTNode *lchild, *rchild; }BiTNode, *BiTree;  void CreateBiTree(BiTNode **T); int  PreOrderTraverse(BiTNode *T);  int main(){ 	BiTNode *T; 	CreateBiTree(&T); 	PreOrderTraverse(T); }  void CreateBiTree(BiTNode **T){ 	char value; 	printf("请输入结点的值"); 	scanf("%c", &value); 	getchar(); 	if (value == '0'){ 		*T = NULL; 	} 	else{ 		*T = (BiTNode*)malloc(sizeof(BiTNode)); 		(*T)->data = value; 		CreateBiTree(&(*T)->lchild); 		CreateBiTree(&(*T)->rchild); 	}  }  int  PreOrderTraverse(BiTNode *T){ 	if (T == NULL){ 		return 0; 	} 	else{ 		printf("%c", T->data); 		PreOrderTraverse(T->lchild); 		PreOrderTraverse(T->rchild); 	} }
user-0 提问: C语言遍历结构体

回复:
user: user-0
content: 引用 4 楼 qq423399099 的回复:你是要遍历结构体还是要遍历放了很多结构体变量的一个容器？我就是想给结构体中的每一个变量赋值，但是想用循环来遍历结构体，不然依次赋值感觉代码很冗余

user: user-0
content: 引用 6 楼 jianyuezhimei 的回复:应该说对于结构体内部进行循环遍历不易做到，使用一些变通的方法或许能够做到，但最主要的是这样做毫无意义。因为结构体很多，而且每个结构体里面的数据也比较多，我列举的只是一个小的例子，所以想通过遍历来取结构体中的值，不知道你有没有什么好的方法能实现一个通用的方法。

user: user-0
content: 引用 5 楼 amoyman 的回复:我猜，楼主是要这样遍历结构体内的每个字节吧  InsertProgramQueryCondition ST char *p = (char*)(&St); for (int i =0; i < sizeof(InsertProgramQueryCondition); i++) { //这里 *p 就是要的内容 p++; } 其实这个结构体里面还有其他类型的变量，如果还有int型变量，能遍历吗？

user: user-1
content: C,C++ 没有直接的方法 按照 成员变量的类型，通过循环访问他。 你不是要做调试程序吧 那是对每个类型的类型信息，做了记录和封装 所以，才能一一看到。

user: user-2
content: 应该说对于结构体内部进行循环遍历不易做到，使用一些变通的方法或许能够做到，但最主要的是这样做毫无意义。

user: user-3
content: 我猜，楼主是要这样遍历结构体内的每个字节吧  InsertProgramQueryCondition ST char *p = (char*)(&St); for (int i =0; i < sizeof(InsertProgramQueryCondition); i++) { //这里 *p 就是要的内容 p++; }

user: user-4
content: 你是要遍历结构体还是要遍历放了很多结构体变量的一个容器？

user: user-0
content: 引用 2 楼 user-5 的回复:请把题目说清楚，光给个struct怎么遍历就是要遍历结构体啊，没其他的要求

user: user-0
content: 引用 11 楼 user-5 的回复:引用 10 楼 u012947254 的回复:[quote=引用 4 楼 qq423399099 的回复:] 你是要遍历结构体还是要遍历放了很多结构体变量的一个容器？我就是想给结构体中的每一个变量赋值，但是想用循环来遍历结构体，不然依次赋值感觉代码很冗余 你有不止一种类型的变量，如何用循环赋值呢？ 再说了，即使可以做到，一个结构体又能有多少变量。何必把简单的问题复杂化。。。[/quote]分给错了，抱歉

user: user-5
content: 引用 10 楼 u012947254 的回复:引用 4 楼 qq423399099 的回复:你是要遍历结构体还是要遍历放了很多结构体变量的一个容器？我就是想给结构体中的每一个变量赋值，但是想用循环来遍历结构体，不然依次赋值感觉代码很冗余 你有不止一种类型的变量，如何用循环赋值呢？ 再说了，即使可以做到，一个结构体又能有多少变量。何必把简单的问题复杂化。。。

user: user-5
content: 请把题目说清楚，光给个struct怎么遍历

user: user-0
content: 没人吗？？？？求大神解答一下啊
user-0 提问: gcc下release与debug版本的程序大小一样吗？

回复:
user: user-1
content: 不一样，否则 release 和 debug 就没区别了。 release 一般 -O2 和 -DNDEBUG，debug 用默认的就行了，我看你刚好搞反了。

user: user-2
content: 一般来说，你的debug版本由于添加了调试信息，一般会大一些。但是也有可能你生成的可执行文件本身就比较小，所以这种差别不明显，看起来二者几乎一样大。还有一种可能就是你的makefile某处可能利用strip将生成的可执行文件中的调试信息去掉了，这样对于debug和release来说都不含调试信息了，所以都一样大（你看看makefile里面有没有什么线索）。

user: user-3
content: 理论上release应该更小一些，但实际你也看到了。。。。 可能是你的软件比较小，所以优化减少的那些东西很少，所以不能体现在文件大小上，具体的原因，你看一下汇编代码应该能搞懂，因为汇编代码和机器码是一一对应的

user: user-4
content: 他怀疑非linux系统都是辣鸡

user: user-5
content: 理论上来讲release要比debug小，release版少了很多调试信息

user: user-6
content: debug版本肯定要大一些。

user: user-7
content: 一样或不一样都行，和哪个版本无关。