Mxode/CSDN-C_Language-2013_2023 huggingface dataset:
user-0 提问: 求大佬帮我看看这段代码的思路

回复:
user: user-1
content: 这是最基本的入栈出栈算法，算括号的匹配 假设先不计算得分，单纯让你判断括号是不是匹配（也就是是不是所谓的平衡括号），你会怎么做？ 比如判断S="((())"的括号是否匹配？ 最常见的方法就是用栈，扫描S字符串，遇到 "(" 就入栈， 遇到 ")" 就出栈一个"(" （如果出栈前栈为空则说明括号不匹配），如果扫描S结束，栈里还存存在多余的元素，则说明括号不匹配。 来看下具体操作，挨个扫描S， S[0]="("，所以S[0]="("入栈，即stack={"("} S[1]="("，所以S[1]="("继续入栈，即stack={"(", "("} S[2]="("，所以S[2]="("继续入栈，即stack={"(", "(", "("} S[3]=")"，所以出栈一个"("，即stack={"(", "("} S[4]=")"，所以又出栈一个"("，即stack={"("} 到此扫面S结束，最后stack还剩一个元素"("，说明S的括号不匹配  你这道题的算法就是上面判断S是不是平衡括号的变相，只是不是把"("入栈，而是入栈一个得分，其中这个得分依赖于里层的得分 所以这个for循环就相当于扫描S字符串 如果S[i]="("，则入栈一个值（这个值因为依赖于里层的得分，由于里层的得分未知，所以先保留入栈的初始值0） 如果S[i]=")"，则出栈（上面知道出栈就相当于匹配一个括号），然后判断本次出栈括号的值，如果本次出栈括号的值为0（说明本次括号的里层的没有括号，即本次括号里层的得分为0），则修改栈的邻接层的值为+1分，否则修改栈的邻接层的值为+2*本次出栈括号的得分 由于stack是个数组，并非真的出栈，所以要把出栈后的数组元素清0（否则就会对新入栈的元素造成影响），即stack[top + 1] = 0; 最后获取栈顶的数值int ret = stack[0];即为总得分
user-0 提问: 大神帮忙解释一下这道题

回复:
user: user-1
content: 引用 3 楼 weixin_45434440的回复:[quote=引用 2 楼 ysy_blog的回复:] 可以在脑海里构思出这个程序执行流程 第一步：i=1,x=1,i=2,y=2,i=3 第二步：i=2,i=3,y=5,i=4 第三步：i=5,x=6,i=6,y=11,i=7 第四步：i=8,i=9,y=20,i=9 输出： 8   11    20 x+=i,后面是逗号[/quote] 嗯，看到了，这书写代码的方式容易让人看错

user: user-2
content: 这个题目需要一个注意点就是那个逗号，一条语句是以分号结束的，因此逗号分割的前面的不算一条语句，因此if (i%2)之后的语句是以分号结束的。

user: user-0
content: 答案是9 1 20

user: user-3
content: 注意 x += i, i++;

user: user-0
content: 引用 2 楼 ysy_blog的回复: 可以在脑海里构思出这个程序执行流程 第一步：i=1,x=1,i=2,y=2,i=3 第二步：i=2,i=3,y=5,i=4 第三步：i=5,x=6,i=6,y=11,i=7 第四步：i=8,i=9,y=20,i=9 输出： 8   11    20 x+=i,后面是逗号

user: user-1
content: 可以在脑海里构思出这个程序执行流程 第一步：i=1,x=1,i=2,y=2,i=3 第二步：i=2,i=3,y=5,i=4 第三步：i=5,x=6,i=6,y=11,i=7 第四步：i=8,i=9,y=20,i=9 输出： 8   11    20
user-0 提问: 关于数组指针的取值问题

回复:
user: user-1
content: 一本C语言教材，如果不以类型的观点进行讲解，基本可以扔掉。  [1]，如果操作数的类型是T，则一元&运算符的结果是指向T的指针。 [2]，如果操作数的类型是指向T的指针，则一元*运算符的结果类型是T。 [3]，除非是作为一元&、sizeof运算符的操作数，数组类型的表达式会自动转换为指向其元素类型的指针，并指向它的第一个元素。  来看表达式 * * * p：  step 1：p的类型是指向数组（类型）int [3][4]的指针，即：int (*) [3][4]。 step 2：依据规则[2]，* p的结果是数组（类型） int [3][4]。但是依据规则[3]，int [3][4]自动转换为指向其元素类型的指针。元素类型是int [4]，故转换为指向int [4]的指针，即int (*) [4]； step 3：依据规则[2]，* * p的结果是数组类型int [4]。但是依据规则[3],* * p的类型int [4]自动转换为指向元素类型的指针，即，int *； step 4：依据规则[2]，* * * p的类型是int。

user: user-2
content: 从定义int(*p)[3][4] 看，p、p+1是个指针，指向int[3][4]二维数组，所以*p、*(p+1)是二维数组int[3][4]本身，也可以看成是指向一维数组int[4]的指针，所以**p、*(*p+1)、*(*p+2)、**(p+1)、*(*(p+1)+1)、*(*(p+1)+2)是一维数组int[4]本身，所以  test[0][0][0]=***p、test[0][0][1]=*(**p+1) test[0][1][0]=**(*p+1)、test[0][1][1]=*(*(*p+1)+1) test[0][2][0]=**(*p+2)、test[0][2][1]=*(*(*p+2)+1)  test[1][0][0]=***(p+1)、test[1][0][1]=*(**(p+1)+1) test[1][1][0]=**(*(p+1)+1)、test[1][1][1]=*(*(*(p+1)+1)+1) test[1][2][0]=**(*(p+1)+2)、test[1][2][1]=*(*(*(p+1)+2)+1)

user: user-3
content: 下面3句多看几遍，好好理解一下 3维数组元素test[0][0][0]的地址&test[0][0][0]=test[0][0]=2维数组的元素，所以*test[0][0]=test[0][0][0]  2维数组的元素test[0][0]的地址&test[0][0]=test[0]=1维数组的元素，所以*test[0]=test[0][0]，两边再取*，即**test[0]=*test[0][0]，把上面*test[0][0]=test[0][0][0]，得到 **test[0]=*test[0][0]=test[0][0][0]  1维数组的元素test[0]的地址&test[0]=指针p，所以*p=test[0]，两边再取*，即**p=*test[0]，再两边取*，即***p=**test[0]，把上面**test[0]=*test[0][0]=test[0][0][0]代入，得到 ***p=**test[0]=*test[0][0]=test[0][0][0]   这里需要注意的是 int(*p)[3][4] = &test[0]; //p是个数组指针，p+1 会移动 3*4*sizeof(int) 个字符

user: user-4
content: 这是三维的数组，如果能够理解到二维数组，那么三维是一个道理。 所以，举例子建议用二维数组～

user: user-0
content: p指向&test[0]，*p指向test[0]，**p指向test[0][0]，***p指向test[0][0][0]

user: user-0
content: 贴一个别人的答案，只有p是指针，通过sizeof（p）测试可知，*p和**p都是数组名，只是printf *p和**p都退化为指针了，所以看起来都是地址，***p才是取到实际的数据。
user-0 提问: 求大佬帮我看个小问题

回复:
user: user-1
content: 编译能出错？编译能够预测到top < 0？先不论编译器能不能提示错误，本身就应该把top > -1放在前面

user: user-2
content: &&有“断路”作用，即前面不为true，就不会执行后面，所以top>-1放在stack[top]>num[i]的前面和后面，意义不一样。 具体lz可以自己谷歌百度一下&&“断路”和||“短路”的说明

user: user-3
content: 把错误提示也写出来

user: user-4
content: 在使用数组stack时，先保证序号不能为负数。(k>0 && top>-1 && stack[top]>num[i]) 先判断了top，保证非负数；而(stack[top]>num[i] && top>-1 && k>0)在第一次判断时，top = -1.
user-0 提问: 为什么M/2=2？

回复:
user: user-1
content: 宏定义就是等价替换；加括号和不加括号有很大区别～因为括号会影响运算的优先级～

user: user-1
content: 等价替换之后是：(N+1+1) * N +1/2，把2带进去看一下等于：(2+1+1) * 2 + 1 /2 = 4 * 2 + 0  = 8

user: user-2
content: 宏定义只是简单的替换，NUM= (M+1)*M/2------------------->NUM=(N+1+1)*N+1/2      使用除法运算符“/”对两个整数进行运算的时候，得到的结果也是一个整数。1/2得到的结果去掉小数部分得到的整数为 0。

user: user-3
content: 把宏展开再计算（宏不会判断优先级，只是套代码），所以 NUM=(N+1+1)*N+1/2=4*2+0=8
user-0 提问: 编译libpcap  遇到 portability.h 通不过？

回复:
user: user-0
content: pcap_findalldevs函数报未定义引用, 加参数-Ipcap也无用。 当前目录libpcap源码目录 gcc -o jpcap myjpcap.c -I./pcap -I./ -Ipcap 这样也是提示未定义引用，这是怎么回事？

user: user-1
content: 贴出对应错误的代码，这样方便给你定位问题。
user-0 提问: 加括号和不加括号有什么区别呢？

回复:
user: user-1
content: #define 替换字符串，  替换后不加括号有可能计算的不是你想要的结果。

user: user-2
content: 优先级不一样，加了括号，你看到的就是你想到的，不加，你看到的，不一定是你想到的

user: user-3
content: 加不加括号，楼主可以把出现宏的地方等价替换一下，然后再按照加减乘除的优先级比较一下加和不加括号的区别。

user: user-4
content: 宏定义你展开自然知道区别了，别个可能传递1+2, 2+3,这种，没括号会有运算顺序的差别

user: user-5
content: 所有用宏定义的函数，最开始都用纸笔写下来 MULT1(3 + 2, 5 + 8) -> 3 + 2 * 5 + 8 -> 21 MULT2(3 + 2, 5 + 8) -> (3 + 2) * (5 + 8) -> 65
user-0 提问: 关于C语言中的全局变量与局部变量的区别

回复:
user: user-1
content: 学习了学习了学习了

user: user-2
content: 楼主可以把动态申请的空间加入进来，比如malloc/free, new/delete

user: user-3
content: 静态局部变量只是在第一次调用的时候开辟空间进行赋值  有问题

user: user-4
content: 为了说明自己的想法，发明和生造了额外的术语。这是结合了标识符的作用域和变量的生存期而发明的新术语，有才。在下不胜钦服！
user-0 提问: 调试后直接进入main函数，跳过了Pow这个函数，如何进入pow？

回复:
user: user-1
content: double Pow(double x,int y) {    double P = 1;   //返回的是double类型，因此返回的应该是大P    int i,p;    for(i =1;i<=y;i++)    P *= x;    //这儿应该用P    return P; }

user: user-2
content: main是入口函数，当然是从main开始，在main中调用相关函数，才会进入，或者通过中断函数方式。

user: user-3
content: 注意大小写，pow函数名，还有p变量

user: user-0
content: 说白了，就是如何进入这个代码进行F10或F11 double Pow(double x,int y) {    double P = 1;    int i,p;    for(i =1;i<=y;i++)    p *= x;    return p; }
user-0 提问: while(scanf("%d",&a)!=EOF)

回复:
user: user-0
content: 引用 7 楼 自信男孩 的回复:[quote=引用 5 楼 Enteral 的回复:][quote=引用 3 楼 自信男孩 的回复:][quote=引用 2 楼 Enteral 的回复:][quote=引用 1 楼 qybao 的回复:]改成scanf(“%d”, &x) == 1  scanf成功则返回读入数据的个数，不成功则返回-1 所以想退出循环，输入任意非数字的字符就可以了 我想了解这个EOF的原因，解决办法我也了解不少啦，谢谢啊[/quote] 你用ctrl+d试试了吗？[/quote] 我的是Windows下，所以使用ctrl+z，linux使用的是ctrl+d，我的问题已经解决，只是不明白原理而已[/quote] 原理就是ctr+z是输入EOF，至于为什么可以在网上搜一下。[/quote] 给你看一下图片

user: user-0
content: 引用 7 楼 自信男孩 的回复:[quote=引用 5 楼 Enteral 的回复:][quote=引用 3 楼 自信男孩 的回复:][quote=引用 2 楼 Enteral 的回复:][quote=引用 1 楼 qybao 的回复:]改成scanf(“%d”, &x) == 1  scanf成功则返回读入数据的个数，不成功则返回-1 所以想退出循环，输入任意非数字的字符就可以了 我想了解这个EOF的原因，解决办法我也了解不少啦，谢谢啊[/quote] 你用ctrl+d试试了吗？[/quote] 我的是Windows下，所以使用ctrl+z，linux使用的是ctrl+d，我的问题已经解决，只是不明白原理而已[/quote] 原理就是ctr+z是输入EOF，至于为什么可以在网上搜一下。[/quote]可是为什么要进行三次ctrl+z输入，才会真正跳出循环啊

user: user-1
content: 引用 5 楼 Enteral 的回复:[quote=引用 3 楼 自信男孩 的回复:][quote=引用 2 楼 Enteral 的回复:][quote=引用 1 楼 qybao 的回复:]改成scanf(“%d”, &x) == 1  scanf成功则返回读入数据的个数，不成功则返回-1 所以想退出循环，输入任意非数字的字符就可以了 我想了解这个EOF的原因，解决办法我也了解不少啦，谢谢啊[/quote] 你用ctrl+d试试了吗？[/quote] 我的是Windows下，所以使用ctrl+z，linux使用的是ctrl+d，我的问题已经解决，只是不明白原理而已[/quote] 原理就是ctr+z是输入EOF，至于为什么可以在网上搜一下。

user: user-0
content: 引用 4 楼 poetryTang 的回复:按回车键了吗问题已经通过啦，只是想了解原因

user: user-0
content: 引用 3 楼 自信男孩 的回复:[quote=引用 2 楼 Enteral 的回复:][quote=引用 1 楼 qybao 的回复:]改成scanf(“%d”, &x) == 1  scanf成功则返回读入数据的个数，不成功则返回-1 所以想退出循环，输入任意非数字的字符就可以了 我想了解这个EOF的原因，解决办法我也了解不少啦，谢谢啊[/quote] 你用ctrl+d试试了吗？[/quote] 我的是Windows下，所以使用ctrl+z，linux使用的是ctrl+d，我的问题已经解决，只是不明白原理而已

user: user-0
content: 引用 1 楼 qybao 的回复:改成scanf(“%d”, &x) == 1  scanf成功则返回读入数据的个数，不成功则返回-1 所以想退出循环，输入任意非数字的字符就可以了 我想了解这个EOF的原因，解决办法我也了解不少啦，谢谢啊

user: user-2
content: 改成scanf(“%d”, &x) == 1  scanf成功则返回读入数据的个数，不成功则返回-1 所以想退出循环，输入任意非数字的字符就可以了

user: user-3
content: 按回车键了吗

user: user-1
content: 引用 2 楼 Enteral 的回复:[quote=引用 1 楼 qybao 的回复:]改成scanf(“%d”, &x) == 1  scanf成功则返回读入数据的个数，不成功则返回-1 所以想退出循环，输入任意非数字的字符就可以了 我想了解这个EOF的原因，解决办法我也了解不少啦，谢谢啊[/quote] 你用ctrl+d试试了吗？
user-0 提问: leetcode上的题，我没搞懂自己的代码错在哪

回复:
user: user-1
content: if (nums==NULL || numsSize<3) return false;    改成numsSize < 2？

user: user-2
content: 你这个for循环里的if组合太有局限性了，只能查看3个连续的子序列（i-2, i-1, i)，而题目要求的ijk不一定是连续的，只要求符合大小关系，所以你的输入里存在的[3,5,4]子序列就不能找到（因为4和3，5没有挨着，不连续，所以不能满足你的if）
user-0 提问: C语言中不是说指针变量是存放某个变量地址不能存放常量吗？

回复:
user: user-1
content: 第一题题目都说了要选的是指针变量，那你还给他赋个常量干嘛，不是不能赋常量，而是题目要求不能放。

user: user-2
content: 典型的胡吣。 D不合适的原因不在于常量，而在于类型不匹配。 实际上，D也是可以的。这要看是在什么情况下。在需要用绝对地址的时候，没办法的时候，1024也可以的，它可以自动转换为指针类型。

user: user-3
content: 可以赋值常量，但是类型不对。0其实是(void *)0。即NULL

user: user-4
content: 不过这也能看出来，0 不代表具体的地址，只是表示一个空指针。

user: user-4
content: 只能说 0 是个例外，万事总有个例外，C 语言也不例外，知道就行了，没什么好理解的

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

user: user-6
content: 第一题中D选项  指针存放值的地址 不直接存放值。你可以这样理解 给你举个通俗的例子。 一个柜子，暂且就叫做一号柜子，里面可以有100块钱  柜子就是指针  钱就是值。 你可以拿走或者增加柜子里面的钱 但是你不能改柜子的编号。 你可以给柜子里面再放1000块钱  但是你不能说给1000号柜子里面放钱，因为不存在这样的柜子。   第二题，就很显然了。 我就把1号，2号，3号柜子改名叫0号柜子了。
user-0 提问: 线性表和链表一样吗？？这个题应该怎样处理？

回复:
user: user-1
content: 线性表分顺序表和链表，所以链表是线性表的一种 顺序表就是动态数组，一个head指针指向数组首地址，一个length属性记录当前数组用到了多少元素，一个size属性记录整个顺序表的空间大小。

user: user-2
content: 线性表可以是数组，也可以是链表。如果要实现Q5，可以考虑用链表

user: user-0
content: 引用 2 楼 qybao的回复:线性表分顺序表和链表，所以链表是线性表的一种 顺序表就是动态数组，一个head指针指向数组首地址，一个length属性记录当前数组用到了多少元素，一个size属性记录整个顺序表的空间大小。 有没有具体c代码，实现Q1，Q2的功能就行，感觉还是不是很清楚
user-0 提问: while(scanf("%d",&x)!=EOF)死循环

回复:
user: user-0
content: 引用 2 楼 自信男孩 的回复:LINUX下键盘敲击ctrl+d，windows下敲击ctrl+z。这样是输入EOF的， 也可以百度一下如何输入EOF.我是在windows下输入ctrl+z之后，无法继续输入，单步调试跟踪发现，依然在循环之内

user: user-0
content: 引用 1 楼 真相重于对错 的回复:用ctrl+Z结束输入尝试过啦，还是无法跳出死循环

user: user-1
content: <Enter> <Ctrl+Z> <Enter>

user: user-2
content: 为啥要两个enter啊

user: user-3
content: ctrl+z  ctrl+F6这两个 你分别试试

user: user-4
content: scanf("%d %d",&a,&b); 函数返回值为int型。如果a和b都被成功读入，那么scanf的返回值就是2； 如果只有a被成功读入，返回值为1； 如果a和b都未被成功读入，返回值为0； 如果遇到错误或遇到end of file，返回值为EOF。

user: user-5
content: https://blog.csdn.net/zyj_nust_tech/article/details/47981509

user: user-5
content: LINUX下键盘敲击ctrl+d，windows下敲击ctrl+z。这样是输入EOF的， 也可以百度一下如何输入EOF.

user: user-6
content: 用ctrl+Z结束输入
user-0 提问: 这个毫无头绪！！！

回复:
user: user-1
content: lz所说的每列的类型不同，是指比如第一列和第二列的类型不同，而不是同一列的不同行的类型不同，是这样吧？ 处理思路和步骤如下，lz先自己写代码吧 1 首先，按行读入文件，行再按\t分割，得出总列数 2 定义一个数组记录每列的类型，默认为string 3 把之前按\t分割的每个字符串分别判断，如果该字符串不含数字，且对应的列类型为string，则不做处理；如果该字符串含有数字且调用atoi成功，则修改列类型为int，不成功则改为string类型；如果该字符串含有数字和小数点且调用atof成功，则修改列类型为float，不成功则为string类型 4 文件eof为止继续按行读入文件，行再按\t分割，分割后的字符串按步骤3的方法修正列类型，并得出总行数 5 最后打印结果

user: user-2
content: 大致思路 读入第一行，以\t为分分割符，形成字符串数组 对每个字符串数组，进行识别，如果都是0-9，则是整数，如果有'A'-'Z'||'a'-'z'，则是string ，如果由0-9和一个'.'组成，则是浮点。

user: user-3
content: 题目感觉怪怪的   每列的数值类型并不相同 但每行的格式是固定的。 为啥输出的时候每列的数值类型又是相同的了？
user-0 提问: 求大佬帮我看看这个小问题

回复:
user: user-1
content: 引用 6 楼 weixin_45906870 的回复：所以如果函数返回malloc的地址的话，函数内部是不能free这个malloc地址的吗？是的，free的话函数外拿到的就是野指针了

user: user-0
content: 所以如果函数返回malloc的地址的话，函数内部是不能free这个malloc地址的吗？

user: user-1
content: 返回指针（地址）和返回一个值是不一样的 返回一个值就是把这个值拷贝给函数外的返回值，所以函数外的返回值能使用这个值 返回指针（地址）就是把指针（地址）拷贝给函数外的返回值，函数外的返回值能不能用这个指针（地址）取决于这个指针（地址）是否有效，如果是返回函数栈局部变量的地址，因为函数结束后栈就释放被回收了，所以局部变量的地址也就无效了，这就是为何你用stack[len+1]不行的原因；而如果返回new或malloc的地址，因为该地址在堆上，即使函数栈被回收了，但只要堆没有被delete回free，该地址就一直有效，这也是为何你用malloc就可以的原因。

user: user-2
content: 这里返回的是指针，和值不一样，你可以把return stack 改为return s试试，估计就不会报错了 关于数组长度是变量这个问题，我记得以前讨论过，你的编译器是支持变量定义数组长度的

user: user-0
content: 我之前常常返回整型的局部变量也没问题

user: user-3
content: 需要明确一个问题：数组名不能做左值。但是楼主的不是数组，而是指针，这也是和数组的一点区别。 不能用char stack[len+1]；的原因是len不确定长度。C语言要求数组定义长度，这是其一。 其二是返回局部变量的数组名没有意义呢。

user: user-2
content: 局部变量，不能返回
user-0 提问: （C Primer Plus第六版第6章编程题5）请问这两段代码哪里不同呢？为什么我修改后运行会出错？

回复:
user: user-1
content: 关键在于19行，如果满足19行的for进入循环，那么两种方法打印的ch是一样的；但如果不满足19行的for而跳过了循环，那么第二种的ch就多减了1，导致下一次 i 大循环（外层循环）的ch的开始值不对。

user: user-2
content: 你需要理解的是 1、for(int i=1;i<=5;i++) 2、{ 3、} 4、printf("%d",i)  第四行的时候i等于几？

user: user-0
content: 引用 3 楼 poetryTang 的回复:不仅仅是两次-1和直接-2的区别， 上面虽然相当于-2,但ch本身只减了1，因为printf("%c", ch-1)不会影响ch的值， 而ch -= 2，ch本身减了2  明白啦！我忽略了printf()不改变变量值这个问题，终于想通了哈哈，谢谢各位！！

user: user-0
content: 引用 2 楼 真相重于对错 的回复:你需要理解的是 1、for(int i=1;i<=5;i++) 2、{ 3、} 4、printf("%d",i)  第四行的时候i等于几？  明白啦，感谢各位！

user: user-0
content: 引用 1 楼 qybao 的回复:关键在于19行，如果满足19行的for进入循环，那么两种方法打印的ch是一样的；但如果不满足19行的for而跳过了循环，那么第二种的ch就多减了1，导致下一次 i 大循环（外层循环）的ch的开始值不对。  明白了，谢谢谢谢！

user: user-3
content: 不仅仅是两次-1和直接-2的区别， 上面虽然相当于-2,但ch本身只减了1，因为printf("%c", ch-1)不会影响ch的值， 而ch -= 2，ch本身减了2
user-0 提问: “textcolor”未定义；假设外部返回 int

回复:
user: user-1
content: https://zhidao.baidu.com/question/552992302.html 楼主用的函数都是TC的，而楼主的编译器是VS吧，所以都不支持呀。 建议楼主引入MFC库吧

user: user-2
content: https://blog.csdn.net/hou09tian/article/details/82991361
user-0 提问: gcc libpcap portability.h 

回复:
user: user-1
content: restrict编译器没有识别，所以编译认为是char *restrict，把restrict当成变量名，而没有认为其是关键字，所以才提示错误在restrict后加逗号，隔开和后面的变量；  原因就是楼主的编译器不支持C99标准，可能是楼主的编译器不够新，可以考虑更新一下编译器的版本，或者去掉restrict，不过这样不保证去掉后会出现程序异常（其实这个关键字是告诉编译优化成对应汇编的，去掉似乎也没关系）。

user: user-2
content: size_t pcap_strlcpy原型是啥  代码能贴完整的吗？
user-0 提问: c语言初学者的小问题

回复:
user: user-1
content: 建议贴出你的代码，并说明一下你的编译器； vs不支持scanf函数而是支持更安全的scanf_s函数，因为对于%s，比scanf多一个参数，即a数组的长度；

user: user-2
content: 错有可能不是这个原因，贴上具体错误信息看看
user-0 提问: c语言的头文件有没有ide或者插件能自动生成？

回复:
user: user-1
content: 你说自动引入吧。。。

user: user-2
content: 似乎脚本可以自动生成头文件，不过目前遇到的头文件都是手动写的（当然也有复制粘贴，但没有完全自动生成的）。
user-0 提问: c语言小问题

回复:
user: user-1
content: 你这个是值传递，形参的改变不会影响实参的值，所以它还是3

user: user-2
content: 用C++吧。直接用引用即可。。其他不要动。。。  void free(int &m) {   if(m!=0)   m=0; }

user: user-3
content: void free(int i) {   if(i!=0)   i=0; }函数调用完，变量i声明周期也就结束了，因为i是栈内存的变量，所以使用完之后也就是未知啦，

user: user-3
content: https://blog.csdn.net/yinzewen123/article/details/80532886?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159920883319725222423450%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=159920883319725222423450&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v3~pc_rank_v3-3-80532886.pc_ecpm_v3_pc_rank_v3&utm_term=%E5%87%BD%E6%95%B0%E4%B8%8D%E8%83%BD%E8%BF%94%E5%9B%9E%E6%A0%88%E5%8F%98%E9%87%8F%E7%9A%84%E6%8C%87%E9%92%88&spm=1018.2118.3001.4187 你可以看一下这个链接，最根本的应该是栈内存的原因

user: user-4
content: 因为i是free函数里的局部变量，而非全局或main函数里的变量。局部变量不能把i=0的值传到main函数里。

user: user-5
content: 也可以说是形参实参的知识（形参只是实参的拷贝），还涉及传值和传地址的知识

user: user-4
content: 引用 4 楼 Hans-123 的回复:[quote=引用 2 楼 自信男孩的回复:]因为i是free函数里的局部变量，而非全局或main函数里的变量。局部变量不能把i=0的值传到main函数里。 那如果是这样呢？ #include<stdio.h>  void free(int m) {   if(m!=0)   m=0; }  int main() { int i,a[5]={1,2,3,4,5}; free(a[2]); i=a[2]; printf("%d\n",i); }[/quote] 一样的，free里的m已经不是main里的m了，free里的形参m是free函数里的局部变量，但是可以这样做：  void free(int *m) {   if(*m!=0)   *m=0; } 这样定义free就可以了，即传实参的地址到free里。

user: user-0
content: 引用 2 楼 自信男孩的回复:因为i是free函数里的局部变量，而非全局或main函数里的变量。局部变量不能把i=0的值传到main函数里。 那如果是这样呢？ #include<stdio.h>  void free(int m) {   if(m!=0)   m=0; }  int main() { int i,a[5]={1,2,3,4,5}; free(a[2]); i=a[2]; printf("%d\n",i); }

user: user-6
content: 1楼说的有道理，这是值传递还是地址传递的问题，可以改成 void free(int *p) {   if (*p != 0) {     *p = 0;   } }
user-0 提问: 关于链表，为什么无法正确输出，输出只有第一个，个人感觉课呢鞥没有正确链上

回复:
user: user-1
content: if(last->p){ while(last->p) last=last->p; }else head->p=all;//遍历last是否为0，当为0时，使之链到前面创立的all项  上面的程序有问题，改为 if(last) {   while(last->p) last = last->p;   last->p = all; }else head = all;

user: user-2
content: 数据结构对单链表进行数据排序 http://bbs.csdn.net/topics/392201633

user: user-3
content: node* linked_line_input(node* head, int value) {      //不能用数组，不能长大     // node* all=NULL;  //全局指针     //创立一个单独node     node* all=(node*)malloc(sizeof(node));     all->number=value;     all->p=NULL;      node* last=head;//定义最后一个      if (!last) {    //第一个节点,第一个节点head为NULL，因此不能判断last->p         head = all;         return head;     }      if(last->p) {         while(last->p)             last=last->p;     }     last->p = all;     /*     else         head->p=all;//遍历last是否为0，当为0时，使之链到前面创立的all项         */     // printf("%d",all->number);      return head; }  链表插入有问题，对于第一个节点处理的不对，供参考～  int main(int argc, char *argv[]) {     printf("请输入,结束输入请输入-1\n");     int temp=-1;     node* head=NULL;//一个叫head的node型变量     // node** phead=&head;     do{         scanf("%d",&temp);         if (temp < 0)             break;         head=linked_line_input(head, temp);//正常往后加，插入额外做     }while(1);     // printf("%d",head->number);     node* temp1;     for(temp1=head;temp1;temp1=temp1->p){         printf("%d ",temp1->number);     }      linked_line_printall(head);      return 0; } 供参考  main函数里对于temp的值为1处理不合理，改一下～
user-0 提问: 递归求解

回复:
user: user-1
content: 都给你公式了，套着公式递归就可以了  double fx(double x, double a) {     double x1;     if (x==0) return 0; //理论上不存在，为了排除异常（除0）情况     x1 = (x + a/x)/2; //公式     if (abs(x1-x) < 0.00001) return x1; //达到题目要求的精度就返回     return fx(x1, a); //否则继续递归（把x1代入公式继续求xn） }  int main(void) {     double a;     scanf("%lf", &a);     double x = fx(1, a); //x0=1     printf("%.0lf\n", x); //题目要求取整数部分     return 0; }

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

user: user-0
user-0 提问: 当键入while语句结束的指令时总是闪退，尝试在各个地方加gechar()都不行

回复:
user: user-0
content: 问题已解决，需要再加两个getchar()

user: user-1
content: 闪退的原因是楼主最后一次输入之后还有一个换行符留在输入缓存里，因此getchar();正好接收到了'\n'，因此就返回了，即闪退了。 可以考虑按照楼上的方法，再加一个getchar();或这用system("pause");试试～

user: user-2
content: 再多追加一个getchar 或者getchar改成system(“pause”);
user-0 提问: 数组名和指针有区别吗？

回复:
user: user-1
content: 数组是一段连续的内存，首元素存放着首地址，这点类似于指针，但是二者的类型不一样

user: user-2
content: 数组作为参数时会退化为指针，其它情况都是有区别的 数组名一旦指向了地址，就不能再改变，相当于指针常量 数组的内存空间大小是确定的（因为事先声明好内存大小，也就是数组是一片连续的内存空间，而不光是个地址），而指针是指向一个地址，不是一片内存空间，该地址的大小是固定的4个字节（64位系统是8个字节），所以用sizeof计算的大小是不一样的。

user: user-3
content: 数组名不是指针，但是某些语法情况下和指针的作用相同（主要就是a[i] a+i 这两种情况），C语言中基本上没有两个东西是“完全一样的”，除了是unsigned和 unsigned int这种省略写法，因为既然完全一样，就没必要都存在，扯的有点儿远了，说回数组名和指针，他们在某些情况下的行为并不同，你给的例子就是其中最关键的一种，而且数组名不能像指针一样移动。总之，它们有些情况下一样，有些情况下不一样，所以说它们一样是肯定不对的。
user-0 提问: 求杨辉三角，大佬帮忙看下哪里错了，十分感谢！！

回复:
user: user-1
content: 仅供参考：#include <stdio.h> #define MAXN 10 unsigned __int64 y[MAXN][MAXN]; int i,j; char s[60]; void main() {     printf("%30s\n","1  ");     printf("%33s\n","1     1  ");     y[1][0]=1ui64;y[1][1]=1ui64;     for (i=2;i<MAXN;i++) {         y[i][0]=1ui64;sprintf(s,"1  ");         for (j=1;j<=i-1;j++) {             y[i][j]=y[i-1][j-1]+y[i-1][j];             sprintf(s,"%s   %-3I64u",s,y[i][j]);         }         y[i][i]=1ui64;sprintf(s,"%s   1  ",s);         printf("%*s\n",30+i*3,s);     } } //                           1 //                        1     1 //                     1     2     1 //                  1     3     3     1 //               1     4     6     4     1 //            1     5     10    10    5     1 //         1     6     15    20    15    6     1 //      1     7     21    35    35    21    7     1 //   1     8     28    56    70    56    28    8     1 //1     9     36    84    126   126   84    36    9     1  再供参考：//按如下格式打印杨辉三角形的前MAXN行。 //  1 //  1 1 //  1 2 1 //  1 3 3 1 //  1 4 6 4 1 //  1 5 10 10 5 1 #include <stdio.h> #define MAXN 68 unsigned __int64 y[MAXN][MAXN]; int i,j; void main() {     printf("1\n");     printf("1 1\n");     y[1][0]=1ui64;y[1][1]=1ui64;     for (i=2;i<MAXN;i++) {         y[i][0]=1ui64;printf("1 ");         for (j=1;j<=i-1;j++) {             y[i][j]=y[i-1][j-1]+y[i-1][j];             printf("%I64u ",y[i][j]);         }         y[i][i]=1ui64;printf("1\n");     } } //1 //1 1 //1 2 1 //1 3 3 1 //1 4 6 4 1 //1 5 10 10 5 1 //1 6 15 20 15 6 1 //1 7 21 35 35 21 7 1 //1 8 28 56 70 56 28 8 1 //1 9 36 84 126 126 84 36 9 1 //... //1 67 2211 47905 766480 9657648 99795696 869648208 6522361560 42757703560 247994680648 1285063345176 5996962277488 25371763481680 97862516286480 345780890878896 1123787895356412 3371363686069236 9364899127970100 24151581961607100 57963796707857040 129728497393775280 271250494550621040 530707489338171600 972963730453314600 1673497616379701112 2703342303382594104 4105075349580976232 5864393356544251760 7886597962249166160 9989690752182277136 11923179284862717872 13413576695470557606 14226520737620288370 14226520737620288370 13413576695470557606 11923179284862717872 9989690752182277136 7886597962249166160 5864393356544251760 4105075349580976232 2703342303382594104 1673497616379701112 972963730453314600 530707489338171600 271250494550621040 129728497393775280 57963796707857040 24151581961607100 9364899127970100 3371363686069236 1123787895356412 345780890878896 97862516286480 25371763481680 5996962277488 1285063345176 247994680648 42757703560 6522361560 869648208 99795696 9657648 766480 47905 2211 67 1

user: user-0
content: 引用 1 楼 user-2的回复:你这是没有换行和补空格 a[1][1]=1; printf("%d\n",t); //这里要换行  printf("%5d\n",t);}} //这里要换行  至于补空格，LZ自己去调整吧 感谢感谢，还有a【】【】那个声明得放在上面那个整形定义里去，就这些小问题，找不出时很难受，😂

user: user-2
content: 你这是没有换行和补空格 a[1][1]=1; printf("%d\n",t); //这里要换行  printf("%5d\n",t);}} //这里要换行  至于补空格，LZ自己去调整吧
user-0 提问: # define HGE '0.25'用printf % d 输出结果是808333887

回复:
user: user-1
content: 内存里整型数据和浮点数的表示方法不一样，因此用%d输出是以整型数据去解析浮点数，所以出现这样的结果～

user: user-2
content: 引用 2 楼 mzhan017 的回复:编译器把这个宏定义定义成了一个指针，指向这个临时字符串，打出来的是个指针地址  c:\MinGW\test>gcc printf.c printf.c: In function 'main': printf.c:16:17: warning: multi-character character constant [-Wmultichar]    16 |  printf("%d-%d",leg,'0.26');       |                 ^~~ printf.c:16:21: warning: multi-character character constant [-Wmultichar]    16 |  printf("%d-%d",leg,'0.26');       |                     ^~~~~~

user: user-2
content: 编译器把这个宏定义定义成了一个指针，指向这个临时字符串，打出来的是个指针地址

user: user-3
content: printf("%x\n", HGE); 你就明白了

user: user-3
content: 我前面说错了一点，这个应该跟大小端架构没关系，'0.25'是字面值，最左边是最高位，最右边是最低位，所以它总是0x302e3235（808333877）

user: user-3
content: '0.25'不是指针，也不是字符串，而是int，在小端架构上，内存布局是35 32 2e 30，就是0x302e3235，即808333877(808333887 应该是楼主写错了)
user-0 提问: 运行时出现0x00000000 该内存不能为written

回复:
user: user-1
content: 这个地址确实不能写，读也不可以。建议贴代码吧～

user: user-2
content: 贴代码。不然说了你又不信

user: user-3
content: 楼主可以尝试调试运行你的程序 在*p的这一条语句下断点 就可以在运行过程中实时查看它的值 这时候就发现它的值是0了

user: user-4
content: 代码贴上来看看阿

user: user-5
content: 加些断点看看运行到哪儿出现问题，再分析解决

user: user-6
content: 建议先学会调试方法再写程序，磨刀不费砍柴工的

user: user-0
content: 引用 1 楼 user-7的回复:0x00000000这个是空指针 你查看一下代码是不是有什么指针还没初始化 我看了几遍，没发现有空指针，而且一般如果是空指针不是会报不能从空地址读吗，这个是写，我怀疑是不是内存溢出了

user: user-7
content: 0x00000000这个是空指针 你查看一下代码是不是有什么指针还没初始化
user-0 提问: 可以在n是变量的情况下定义数组a[n]吗？

回复:
user: user-1
content: 引用 4 楼 alittlenewbiek 的回复:你的编译器能编译通过就说明支持VLA， 或者叫VM(variably - modified)类型。  最早是由C99标准引入的， 但是C99标准的一些特性并没有被大多数编译器支持， 所以C11标准非常识相地将VLA在内的一些特性定义为可选非强制的。  一旦支持VLA，还要满足以下条件： 1，只能是定义在block或者作为函数的参数内，即automatic storage duration 2，不能初始化  说清楚，大多数编译器，是哪些编译器。

user: user-1
content: 说话要负责任。 可变长度数组，是C标准支持的。

user: user-2
content: 不建议使用变量为下标定义数组.虽然有些编译器支持,但这是不标准的.使用常量来定义数组.

user: user-3
content: 可变参数不可以，需要确定数组长度。因为n是局部变量，在调用之前（调用该函数）n的值是不确定的，是一个随机值。

user: user-4
content: 目前C标准里是支持的，但对于C++，这个是非标，只是有些C++编译器支持

user: user-5
content: 你的编译器能编译通过就说明支持VLA， 或者叫VM(variably - modified)类型。  最早是由C99标准引入的， 但是C99标准的一些特性并没有被大多数编译器支持， 所以C11标准非常识相地将VLA在内的一些特性定义为可选非强制的。  一旦支持VLA，还要满足以下条件： 1，只能是定义在block或者作为函数的参数内，即automatic storage duration 2，不能初始化

user: user-6
content: 用堆，int* pa = new int[n];

user: user-7
content: 如果你的编译器支持C99标准就可以

user: user-8
content: N必须在编译的时候确定

user: user-9
content: 不能 int a[n];这个n必须是个常数

user: user-10
content: 这是一个特性，叫VLA(variable-length array)。在C99标准，或是某些编译器的扩展下，支持这样定义数组。
user-0 提问: 我哭了，关于二叉树非递归遍历的问题，太难了

回复:
user: user-1
content: 所有递归变成非递归，都可以使用list<>，自己保存堆栈，然后遍历list<>，解决

user: user-0
content: 我怀疑是自己的代码写的太少了

user: user-2
content: 这个就看个人的思维能力了，其实思路都挺简单的，就看你对栈的入栈出栈控制的想象能力了。 前序遍历的思路就是，先遍历父节点，再遍历左节点，后遍历右节点。 所以 if(p!=NULL) 就是判断左节点是否为空，如果不为空，说明还能向左走，就一直遍历左节点（先打印父节点是表为先遍历父节点，然后把父节点压栈后再p=父节点的左节点去遍历左节点） else就是如果左节点为空，也就表示没有左节点了（往左走不通了），就改为遍历右节点（父节点出栈，然后p=父节点的右节点继续遍历右节点）  中序遍历的思路就是，先遍历左节点，再遍历父节点，后遍历右节点 所以 if(p!=NULL) 也是判断左节点是否为空，如果不为空，说明还能向左走，就一直遍历左节点（把父节点压栈，然后p=父节点的左节先遍历左节点） else就是如果左节点为空，也就是没有左节点了（往左走不通了），就把父节点出栈，然后打印父节点（表示遍历完左节点以后接着遍历父节点），然后再p=父节点的右节点继续遍历右节点  后序遍历的思路就是，先遍历左节点，再遍历右节点，后遍历父节点 所以 if(p!=NULL) 也是判断左节点是否为空，如果不为空，说明还能向左走，就一直遍历左节点（把父节点压栈，p=父节点的左节点先遍历左节点） else就是如果左节点为空，也就是没有左节点了（往左走不通了），就继续遍历右节点，注意，此时父节点并没出栈（因为右节点遍历完才遍历父节点，所以父节点一时半会还要待在栈里，遍历完右节点才能出栈），同时为了避免重复遍历右节点（因为父节点还在栈顶就会取到相同的父节点，这样右节点就会相同），所以用个r来记录右节点是否已经遍历过，这也就是在else里的if else的意义。如果右节点已经遍历过了，那么父节点就开始出栈，然后打印父节点（表示遍历父节点）
user-0 提问: 求大佬帮我看看这份代码的思路

回复:
user: user-1
content: 编译运行会出错？是编译出错还是运行出错？ 如果是编译出错，有可能像LS说的，老的c编译器只支持变量定义放在最前； 如果是运行出错，那就debug跟踪一下到底是什么错？  另外，你不需要单独写一个func函数来递归，preorderTraversal本身的设计就支持递归 int* preorderTraversal(struct TreeNode* root, int* returnSize){     int leftSize=0, rightSize=0, *result=NULL, *left=NULL, *right=NULL; //老的c编译器只支持变量定义放在最前     *returnSize = 0;     if (root==NULL) return NULL;          if (root->left) left = preorderTraversal(root->left, &leftSize); //如果左节点不为空则递归遍历左子树（遍历结果保存在临时的left里）     if (root->right) right = preorderTraversal(root->left, &rightSize); //如果右节点不为空则递归遍历右子树（遍历结果保存在临时的right里）     *returnSize = 1 + leftSize + rightSize; //遍历结果总长度，1是root节点本身，leftSize是左子树遍历结果长度，rightSize是右子树遍历结果长度     result = (int *)malloc((*returnSize)*sizeof(int)); //保存遍历结果     result[0] = root->val; //保存root节点，如果是叶节点，递归得到的leftSize和rightSize都是0，result就只会保存叶节点root->val     if (leftSize > 0) { //如果左子树存在则保存左子树遍历结果         memcpy(result+1, left, leftSize*sizeof(int));         free(left); //释放左子树内存     }     if (rightSize > 0) { //如果右子树存在则保存右子树遍历结果         memcpy(result+1+leftSize, right, rightSize*sizeof(int));         free(right); //释放右子树内存     }     return result; }

user: user-2
content: 变量定义要在语句块最前面，后面难道不报错了？

user: user-0
content: 非常感谢，我还有一个疑问，下面是我用递归算法写的代码： /**  * Definition for a binary tree node.  * struct TreeNode {  *     int val;  *     struct TreeNode *left;  *     struct TreeNode *right;  * };  */   /**  * Note: The returned array must be malloced, assume caller calls free().  */  //递归算法 void func(struct TreeNode *root, int *res, int *returnSize){     if (root==NULL) return;     res[(*returnSize)++] = root->val;     func(root->left, res, returnSize);     func(root->right, res, returnSize); } int* preorderTraversal(struct TreeNode* root, int* returnSize){     //if (root==NULL) return NULL;           //为什么我写上这行代码后，编译运行会出错？错在哪？     *returnSize = 0;     int *res = (int *)malloc(sizeof(int)*1024);     func(root, res, returnSize);     return res; }

user: user-1
content: s是什么？你可以把s当作是堆栈，用来保存树的节点。s[top++]=xx是把xx节点入栈，xx=s[top--]就是栈顶节点出栈  s[top++]=root是把root入栈 while(top!=-1)表示栈里还有元素则一直循环 root=s[top--]就是栈顶节点出栈赋给root变量 result[(*size)++]=root->val就是把出栈节点的val保存到遍历结果 if(root->right) s[top++]=root->right表示如果节点的右节点不为空，则把右节点压栈  if(root->left) s[top++]=root->left表示如果节点的左节点不为空，则把左节点压栈  用你的示例来说明 s[]={root} //root入栈  while循环第一次 栈顶1节点出栈，s[]={}，root=1 result[]={1} 右节点入栈，s[]={2} 左节点不满足if，没入栈  while第二次循环 栈顶2节点出栈，s[]={}，root=2 result[]={1,2} 右节点不满足if，没入栈 左节点入栈，s[]={3}  while第三次循环 栈顶3节点出栈，s[]={}，root=3 result[]={1,2,3} 右节点不满足if，没入栈 左节点不满足if，没入栈  while第四次循环，s[]={}，top=-1，不满足，循环结束  所以最终结果result[]={1,2,3}  按照迭代的概念，可以算迭代算法（递归也是迭代的一种），递归算法一般都可以用堆栈来自己模拟，递归其实就是利用系统函数栈

user: user-2
content: 建议楼主先看看《C和指针》
user-0 提问: 编译报错时有些英文翻译不通

回复:
user: user-0
content: 引用 3 楼 棉猴的回复: 注意这些错误标号，然后百度就行了，比如百度error C4430 这是什么样的编译器？

user: user-1
content: 注意这些错误标号，然后百度就行了，比如百度error C4430

user: user-2
content: 发出来，让大家给你翻译一下～

user: user-3
content: 引用 4 楼 其实一开始我是拒绝的 的回复:[quote=引用 3 楼 棉猴的回复:] 注意这些错误标号，然后百度就行了，比如百度error C4430 这是什么样的编译器？[/quote] 这是vs的，你把你的错误发出来看看，你自己用的什么编译器。

user: user-4
content: 除了人，你能找到的最准确的也只有谷歌了
user-0 提问: 大佬们，请问怎么读取mdb文件？

回复:
user: user-1
content: 原始的接口 应该是DAO吧  看文档一律推荐用odbc了   https://docs.microsoft.com/en-us/cpp/data/mfc-database-classes-odbc-and-dao?view=vs-2019

user: user-2
content: 楼主可能对你老师的说法没有真正了解。建议先描述老师原话

user: user-3
content: mdb是access 2003或者更早版本的，你这个界面看，是access 2007，是accdb文件。

user: user-4
content: 课本不是有的吗？mbd处理

user: user-2
content: 引用 4 楼 轻箬笠 的回复:怎么处理数据库才算没链接数据库呢？ 我估计他们老师的原意是不能使用access软件打开mdb处理

user: user-5
content: 怎么处理数据库才算没链接数据库呢？

user: user-6
content: fscanf/fprintf方法？看到楼主的文件是有固定格式的。 要么就是fgets/string相关函数

user: user-0
content: 老师说是用原始的方法，到底是什么方法啊
user-0 提问: return返回问题

回复:
user: user-0
content: 引用 1 楼 user-2的回复:那就看你的需求是什么了，比如期待什么样的结果 返回2是当n为1时，阶乘结果为2，即1! = 2 返回1是当n为1时，阶乘结果为1，即1! = 1 如果你的需求是求n的阶乘的2倍，那就返回2 如果你的需求是求n的阶乘，那就返回1 哦，谢谢了哦，我懂了

user: user-1
content: 根据递归的原理，返回2和返回1就是差2倍的问题。因为返回2之后，递归执行了一半。 最后的执行是2 × 2 × 3...×10 返回1就是执行：1*2*3...*10

user: user-2
content: 那就看你的需求是什么了，比如期待什么样的结果 返回2是当n为1时，阶乘结果为2，即1! = 2 返回1是当n为1时，阶乘结果为1，即1! = 1 如果你的需求是求n的阶乘的2倍，那就返回2 如果你的需求是求n的阶乘，那就返回1

user: user-0
content: 引用 2 楼 自信男孩的回复:根据递归的原理，返回2和返回1就是差2倍的问题。因为返回2之后，递归执行了一半。 最后的执行是2 × 2 × 3...×10 返回1就是执行：1*2*3...*10 哦，对，这是个递归，我弄明白了，谢谢你啊
user-0 提问: 使用OpenSSL1.0.2代码编译错误

回复:
user: user-1
content: https://blog.csdn.net/changweige9192/article/details/77892649  https://superuser.com/questions/1126695/error-openssl-not-found-during-ffmpeg-configure  希望能帮到你～ 以后可以把错误信息发到百度上搜一下，先自己尝试解决一下～
user-0 提问: 数组问题求解

回复:
user: user-0
content: 引用 1 楼 user-2的回复:你要区分数组和数组元素 第一第二张图是用数组计算，不支持 第三张图是用数组元素计算，支持 即 int x[5]={5,6,7,8,9}; int y[5]={2,3,4,5,6}; 不支持x+y这种操作，因为x和y是个地址，是int*指针类型，也就是不支持指针+指针 但是支持x[0]+y[1]这种操作，因为x[0]和y[1]是数组元素，是int类型 谢谢大佬，我明白了

user: user-0
content: 引用 1 楼 user-2的回复:你要区分数组和数组元素 第一第二张图是用数组计算，不支持 第三张图是用数组元素计算，支持 即 int x[5]={5,6,7,8,9}; int y[5]={2,3,4,5,6}; 不支持x+y这种操作，因为x和y是个地址，是int*指针类型，也就是不支持指针+指针 但是支持x[0]+y[1]这种操作，因为x[0]和y[1]是数组元素，是int类型 谢谢大佬！我明白了

user: user-1
content: 不能数组运算是因为数组名不能做左值。比如第一图，数组就是作为左值了。   第三张图的可以运算，那是因为数组元素可以运算的，数组元素是可以读写的。

user: user-2
content: 你要区分数组和数组元素 第一第二张图是用数组计算，不支持 第三张图是用数组元素计算，支持 即 int x[5]={5,6,7,8,9}; int y[5]={2,3,4,5,6}; 不支持x+y这种操作，因为x和y是个地址，是int*指针类型，也就是不支持指针+指针 但是支持x[0]+y[1]这种操作，因为x[0]和y[1]是数组元素，是int类型
user-0 提问: 为什么s=0？

回复:
user: user-0
content: 没有注意啊

user: user-1
content: 引用 1 楼 真相重于对错 的回复:printf("%lf".... 跟%lf和%f没关系。

user: user-1
content: %f是输出浮点型，但是&s是unsigned long类型。类型不匹配，为什么是0.00000，因为浮点型和整型在内存的存储方式不一样，用浮点型去解析整型数据就得到0.00000

user: user-2
content: printf("s=%f\n",&s); 应当是 printf("s=%f\n",s); 不然你相当于输出s的地址(整型)，结果就是尝试用浮点数格式去格式化输出整型数据，所以结果不正确。

user: user-3
content: 你打印s的地址干嘛

user: user-4
content: print(“%lf”, s); double用%lf，打印不需要取地址&

user: user-5
content: printf("%lf"....
user-0 提问: C语言链表相关的技术bug(由于之前发帖到fb，所以部分英文注释)

回复:
user: user-1
content: #include<stdio.h> #include<stdlib.h>  struct Student {     char cName[20];     int iNumber;     struct Student* Pnext;  }student;  int iCount;  struct Student* Creat() {     struct Student* pHead = NULL; //initialize pHead     struct Student* pNew;     struct Student* pEnd;//to move pointer     iCount = 0;     pNew = (struct Student*)malloc(sizeof(struct Student));     //pEnd = (struct Student*)malloc(sizeof(struct Student));      printf("Please enter Name firstly,then enter number\n");     scanf_s("%s", pNew->cName, sizeof(pNew->cName);     scanf_s("%d", &pNew->iNumber);      while (pNew->iNumber != 0)     {         iCount++;//global variable         //if (iCount == 0) { //ready to create the first node         if (iCount == 1) { //ready to create the first node             //pNew->Pnext = NULL;             pEnd = pNew;             pHead = pNew;//          }         else         {             //pNew->Pnext = NULL;             pEnd->Pnext = pNew; //move the present pointer to next node             pEnd = pNew; //          }         pNew = (struct Student*)malloc(sizeof(struct Student));         scanf_s("%s", pNew->cName, sizeof(pNew->cName);         scanf_s("%d", &pNew->iNumber);     }     if (iCount)         pEnd->Pnext = NULL;     free(pNew);      return pHead; //can find the any node of LinkedList by pHead  }  void Print(struct Student* pHead) {     struct Student* pTemp; //temporary variable     int iIndex = 1; //using index to seek aim node      printf("The list has %d members\n", iCount);     printf("\n");      pTemp = pHead; //you know the mean      while (pTemp != NULL)     {         printf("the No %d is:\n", iIndex);         printf("Name:%s\n", pTemp->cName);         printf("Number:%d\n", pTemp->iNumber);         printf("\n");         iIndex++;         pTemp = pTemp->Pnext;     }   } int main() {     struct Student* pHead;//define Head node     pHead = Creat(); //create node     Print(pHead); //print Linked List     return 0;  }   供参考～  建议楼主对比代码找出自己的问题～

user: user-2
content: 问题不少啊 问题1，pEnd = (struct Student*)malloc(sizeof(struct Student)); //这里有内存泄漏 问题2， iCount++;//global variable if (iCount == 0) { //ready to create the first node //这里的if不满足，因为上面iCount++导致iCount不为0，所以导致pHead没有被设定 问题3， while (pNew->iNumber != 0) //如果输入iNumber为0，这里已经退出循环，导致以下不会执行 else { pNew->Pnext = NULL; pEnd->Pnext = pNew; //move the present pointer to next node pEnd = pNew; //   } 所以导致pEnd没有指向最后一个节点（即pEnd是倒数第二个节点，不是最后一个节点）  问题4， while (pTemp != NULL) { printf("the No %d is:\n", iIndex); printf("Name:%s\n", pTemp->cName); printf("Number:%d\n", pTemp->iNumber); printf("\n");  iIndex++;  pTemp = pTemp->Pnext; //这里漏了移动链表指针了，导致while死循环  }  问题已经指出，LZ自行修改吧
user-0 提问: 识别区域颜色

回复:
user: user-0
content: 识别颜色单个点的颜色能实现，但是容易出现误差，所以我想改成识别区域的，我用的是STM32的核心板

user: user-1
content: 要识别区域吗，识别区域需要AI，识别颜色，看你的开发环境了，如果嵌入式直接接CMOS，输出的就是RGB值，如果是PC，得到的应该是图片，用opencv处理一下得到颜色
user-0 提问: 求救！同一份代码，连续用相同的编译器编译两次结果完全不同

回复:
user: user-0
content: 感谢，问题大部分确定为时间问题，项目里生成的一些.pyc文件，压缩文件里面时间不一致导致，追问一下，docker容器的时间是否可以保持不变

user: user-1
content: 还有这种要求，写程序又不是做编译器的

user: user-2
content: 文件中有时间戳,不可能会一样.

user: user-3
content: http://bbs.cskin.net/thread-3013-1-2.html  https://bbs.csdn.net/topics/270055083

user: user-4
content: 還有這樣的要求，爲了做壞事嗎？

user: user-5
content: 另外查看代码是否有未定义行为，对于未定义行为，代码执行顺序可能不同，也就是编译生成的指令不同。

user: user-5
content: 编译器会自动优化，估计编译器会根据某种算法选择优化策略（类似负载均衡算法）。把编译时的优化选项参数设成一样编译试试。 纯属个人推断

user: user-0
content: 编译输出的二进制文件不同，公司要求必须一致
user-0 提问: 遇到奇怪现象，求大神解释~~

回复:
user: user-0
content: 引用 7 楼 qybao 的回复:你这个 if(USB_CtrlCode == USB_CTRL_LIST) else if(USB_CtrlCode == USB_CTRL_DATA) 你是怎么确保哪个分支先执行的？如果你没进入if（条件不满足），先进入else if（条件满足），那LIST_ARRAY_TEMP就没有被设置。我调试过了， 先发送指令读取list信息，上位机得到回复确认正确后， 再发送读取data指令， 发现结果不符， 调试监控变量， 发现了这个问题。

user: user-1
content: 你这个 if(USB_CtrlCode == USB_CTRL_LIST) else if(USB_CtrlCode == USB_CTRL_DATA) 你是怎么确保哪个分支先执行的？如果你没进入if（条件不满足），先进入else if（条件满足），那LIST_ARRAY_TEMP就没有被设置。

user: user-0
content: 引用 5 楼 poetryTang 的回复:LIST_ARRAY_TEMP在哪里定义的，确定是全局变量？如果真是，除了系统复位，数组里内容不可能会被清零，有软件看门狗吗？感谢回复， 起初我也有这个疑问。LIST_ARRAY_TEMP定义在这个源文件中，在.h中申明， 并且在main.c中include过。我尝试直接在main.c的main()前定义， 现象依旧。而且确定不是复位， 因为只有这个数组被清零， 其他变量都好好的。

user: user-0
content: 引用 1 楼 qybao 的回复:把代码补全，看看你是如何操作全局变量的 通过监视器发现，当进入FLASH_READ_DATA这个函数时，LIST_ARRAY_TEMP的值被清零了。我在这个else if内重新调用FLASH_READ_LIST这个函数问题可以解决。不知道为何这样， 全局变量的值 不是应该赋过一次之后就能保存到下次被改写吗。

user: user-0
content: 引用 1 楼 qybao 的回复:把代码补全，看看你是如何操作全局变量的 switch(USB_FunCode){ case USB_FUN_READ:{ if(USB_CtrlCode == USB_CTRL_LIST){ FLASH_READ_LIST(LIST_ARRAY_TEMP,&DATA_SUMNUM,&DATA_FLAG); DataLen = DATA_SUMNUM*9 + 3; //FrameLen = DataLen + 5; // USB_Frame[2] = DataLen >> 8; // USB_Frame[3] = DataLen; USB_Frame[6] = DATA_SUMNUM; for(i = 0;i < DATA_SUMNUM*9;i++){ USB_Frame[i + 7] = LIST_ARRAY_TEMP[i]; }   //USB_Frame[FrameLen-1] = USB_SendFrameSum(&USB_Frame[4],DataLen);      } else if(USB_CtrlCode == USB_CTRL_DATA) { DATA_SN = *(data + 6); //FLASH_READ_LIST(LIST_ARRAY_TEMP,&DATA_SUMNUM,&DATA_FLAG); if(DATA_SN > 0 && DATA_SN <= DATA_SUMNUM){ DataLen = FLASH_READ_DATA(&USB_Frame[6],DATA_SN) + 2;   void FLASH_READ_LIST(uint8_t * pBuffer,uint8_t *SUMNUM,uint8_t *FLAG) {      uint8_t HEAD[2] = {0};      Hal_W25QXX_Read(HEAD,0,2);     if(HEAD[1] == 255){     Hal_W25QXX_Erase_Chip();   HEAD[0] = 0;   HEAD[1] = 0;   *SUMNUM=HEAD[0];   *FLAG=HEAD[1];     Hal_W25QXX_Write(HEAD,0,2);   } else{ *SUMNUM=HEAD[0]; *FLAG=HEAD[1]; } Hal_W25QXX_Read(pBuffer,2,*SUMNUM*9); }   uint16_t FLASH_READ_DATA(uint8_t *pbuff,uint8_t SN) { uint16_t NumByteToRead = 0; NumByteToRead += LIST_ARRAY_TEMP[SN*9-2]<<8; NumByteToRead += LIST_ARRAY_TEMP[SN*9-1]; Hal_W25QXX_Read(pbuff,SN*65536,NumByteToRead); return (NumByteToRead); }

user: user-1
content: 把代码补全，看看你是如何操作全局变量的

user: user-2
content: LIST_ARRAY_TEMP在哪里定义的，确定是全局变量？如果真是，除了系统复位，数组里内容不可能会被清零，有软件看门狗吗？
user-0 提问: 结构体赋值问题

回复:
user: user-0
content: 能不能在我原始代码上面改成正确的格式，感谢大佬~

user: user-1
content: x = { y, z }; 这种语法只在初始化时可用(此时整个 {} 被称作初始化列表)，例如 int a = { 1 }; 如果需要在普通语句内实现结构体赋值，= 的右边必须是一个同类型的结构体，例如  struct stru { 	int a; 	double b; }; struct stru a, b = { 1, 2 }; // 方法 1 a = b; // 方法 2，但老编译器不支持，比如你的 vs a = (struct stru) { 1, 2 }; // 注意：这句不是类型转换，而是使用了复合字面量
user-0 提问: 萌新求助

回复:
user: user-0
content: 引用 5 楼 poetryTang的回复:看编译输出，你说的16进制那一行，只是警告，不影响运行，只是结果不是你想要的； 错误出在itoa这个函数，按这个error提示搜索一下就可以了 谢谢大佬解答

user: user-1
content: 看编译输出，你说的16进制那一行，只是警告，不影响运行，只是结果不是你想要的； 错误出在itoa这个函数，按这个error提示搜索一下就可以了

user: user-0
content: 引用 2 楼 weixin_46284757的回复:最后一个a前面要加一个& 大佬，还是不行

user: user-0
content: 引用 1 楼 user-3的回复:看你的意思是要输出2，8，16进制数， 那么去掉%p和一个a  或者保留%p但把最后一个a写成&a  因为%p是打印指针，但你现在看的是类型和变量部分，指针先不用管  P. S. 买本书看是最好的 大佬，还是不行

user: user-2
content: 最后一个a前面要加一个&

user: user-3
content: 看你的意思是要输出2，8，16进制数， 那么去掉%p和一个a  或者保留%p但把最后一个a写成&a  因为%p是打印指针，但你现在看的是类型和变量部分，指针先不用管  P. S. 买本书看是最好的
user-0 提问: for循环少循环了一次

回复:
user: user-1
content: 推荐你看一下这篇文章，读取字符串的时候，用gets和scanf时候注意他们的区别和适用的地方。 Gets和scanf的区别 https://blog.csdn.net/qq_42820594/article/details/82714251

user: user-1
content: for循环前面加一个fflush(stdin)或者下面读取字符串用scanf都行

user: user-2
content: #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h>  int main() {     int count;     while(scanf("%d", &count) != EOF){         while (getchar() != '\n') ; /* Notice the semicolon */         int i;         char str[100];         for(i = 0; i < count; i++){             gets(str);          /* Don't compile with C11 which removes gets() */             printf("%d:%s\n", i, str);         }         printf("------------------------------\n");     } }

user: user-0
content: 引用 3 楼 alittlenewbiek 的回复：1楼说的没错。  原因在于scanf， 比如当你输入123并回车后， 输入缓冲区的内容是"123\n"， scanf期望读一个int，因此从输入缓冲区里面一个一个的读取， 当读到\n时发现不是int，把\n退回输入缓冲区， 最终123放入变量里面，缓冲区还有一个回车符  当一个程序同时需要输入数值型和字符型时，这个问题最能凸现出来。  解决方法 在每个输入函数后面，加上 while(get char()  != '\n') ; 另外，可以再封装一下输入函数和以上代码段，形成自己的标准函数， 具体可以参考C Primer Plus的第7章 (具体我忘了，有两章都是讲IO的，看get_s()函数)我应该怎么改  能把代码贴一下吗

user: user-2
content: 1楼说的没错。  原因在于scanf， 比如当你输入123并回车后， 输入缓冲区的内容是"123\n"， scanf期望读一个int，因此从输入缓冲区里面一个一个的读取， 当读到\n时发现不是int，把\n退回输入缓冲区， 最终123放入变量里面，缓冲区还有一个回车符  当一个程序同时需要输入数值型和字符型时，这个问题最能凸现出来。  解决方法 在每个输入函数后面，加上 while(get char()  != '\n') ; 另外，可以再封装一下输入函数和以上代码段，形成自己的标准函数， 具体可以参考C Primer Plus的第7章 (具体我忘了，有两章都是讲IO的，看get_s()函数)

user: user-3
content: 为啥你的输出成这样了。

user: user-4
content: 是读了回车造成的吗？ getchar(); (or fflush(stdin); 吃掉回车试试
user-0 提问: 求帮助啊，为什么崩了啊。

回复:
user: user-1
content: 引用 3 楼 mzhan017的回复:Open函数第一个参数去悼& 函数原型：FILE * fopen(const char * path,const char * mode);  而且要加path

user: user-1
content: Open函数第一个参数去悼&

user: user-2
content: errno_t err;  if( (err  = fopen_s( &fp, "contact.txt", "b" )) ==0 )  试试

user: user-2
content: 代码贴出来呀
user-0 提问: 这个程序的输出有些不明白？求指教

回复:
user: user-1
content: 就像一群人围成个圈，编号为1，2，3，4，5； 然后从0开始数，每数1个数移动到下一个人，把数到5对应的人删除，并打印出编号； 第一次是1(0),2(1),3(2),4(3),5(4),1(5),所以打印1； 第二次是2(0),3(1),4(2),5(3),2(4),3(5),所以打印3； 第三次是4(0),5(1),2(2),4(3),5(4),2(5),所以打印2； 以此类推。 如果改成  j=1; while (j<=m) 就更像从1到m报数了

user: user-0
content: 这个输出有些懵
user-0 提问: 关于printf(）函数的使用！

回复:
user: user-1
content: 首先要知道“,%d”是个指针，指向“,%d”所在的内存地址 !i，当i=0，!i=1，当i>0，!i=0 所以“,%d”+1=“%d”，“,%d”+0=“,%d” 或许换成指针的形式你可能更好理解 char *s = “,%d”，s+1是什么？你不妨打印出来看看，printf(“%s”, s+1); 如果指针还不能让你理解，你再换成字符数组。char s[]=“,%d”，&s[1]是什么？&s[0]是字符串的首地址，&s[1]是字符串第二个字符开始的地址，“,%d”第一个字符是逗号，第二个字符是%，从第二个字符地址开始的字符串就是 “%d” 所以现在该明白字符串地址+整数的意义了吧？
user-0 提问: 如何在随机位置生成随机数？

回复:
user: user-0
content: 已经找到错误，srand(time(NULL))语句要放在int定义函数后面，srand（time（NULL））语句后面在定义都将定义失败。

user: user-0
content: 大概就是这样。

user: user-1
content: 什么错误？建议贴出来～

user: user-2
content: 如果你正在使用 vs2010，请将 srand 所在行与下一行互换位置；否则请检查标点符号是否正确输入。

user: user-3
content: 这是一个分号问题。 再看一下代码

user: user-4
content: 看起來應該是你在srand函數結尾處的分號打錯了，第一個error是說這一句開始之前要先有一個分號。之後的錯誤都跟這個錯誤有關，解決了這個就解決了後面。
user-0 提问: 有大佬帮忙看一下这道题目吗？

回复:
user: user-1
content: c语言不支持变量定义数组大小，所以不管加不加1都会报错， 不过这个问题不在这，能看出这里编译器支持用变量定义数组长度， 问题出在为什么要加1，因为有可能出现空字符串，此时len=0，而数组大小必须大于零

user: user-2
content: 像这种动态分配数组，最好用malloc

user: user-3
content: +1是因此字符串里要有'\0'的位置

user: user-4
content: 不用加1也可以 不加1编译出错是因为你的编译器不支持用变量来定义数组长度，所以你要自己动态申请内存。 即 char *stack = new char[len];

user: user-5
content: 不用加1，也可以通过编译的呀！

user: user-0
content: 但是不加1，编译会出错

user: user-6
content: 确实不用，top在[-1，len）变化
user-0 提问: 大学学完C语言之后怎么提高呢？

回复:
user: user-1
content: 自己设想一下，做一个小应用出来，会有很好的体验的。

user: user-2
content: 好比写作文，800字（课程设计）和100字（练习）的主要区别其实不是在于技术含量。

user: user-0
content: 引用 1 楼 ?Victor.??的回复:专业有方向吧  应该根据方向学一学 嗯嗯，谢谢，是我有点急了

user: user-0
content: 引用 2 楼 Italink的回复:主要是看你的专业和兴趣，如果想提高算法能力，可以去力扣，牛客，pta上刷题，参加一些编程比赛，其他的，得靠你自己摸索 噢，这个不错，谢谢啦

user: user-3
content: 主要是看你的专业和兴趣，如果想提高算法能力，可以去力扣，牛客，pta上刷题，参加一些编程比赛，其他的，得靠你自己摸索

user: user-4
content: 专业有方向吧  应该根据方向学一学
user-0 提问: 怎么将c语言代码转换为java代码

回复:
user: user-1
content: 你懂java语法和c语法，你直接就可以修改了，明显数组做参数操作，java怎么可能和c一样直接写指针

user: user-2
content: 你得能看懂java和c才可以转，因为两种语言的语法以及类库是完全不同的、

user: user-0
content: 不行，放到idea就直接报错了

user: user-3
content: 你试一下把这个函数直接放到JAVA工程里编译一下，看看是否能够编译通过。JAVA和C语言在基本类型上还是相同的。
user-0 提问: 【疑惑】关于指针取址遇到的一丝丝小问题（嵌入式、C语言）

回复:
user: user-1
content: %p打印的是指针p变量里的内容，即membuff的地址。 至于用%x和%p的输出的区别，没看出来。但是需要注意的是%x和%p打印的长度可能不一样，比如在64为系统里，%x打印的是4字节的地址，而%p输出的是8字节的地址。
user-0 提问: 关于逆波兰表达式求值的问题

回复:
user: user-0
content: 非常感谢，终于明白了

user: user-1
content: 首先看一维数组和二维数组的区别 char ch[32]; //一维字符数组 scanf(“%s”, ch); //只能存一个字符串 printf(“%s”, ch);  char chs[2][16]; //二维字符数组 for(int j=0; j<2; j++) {     scanf(“%s”, chs[j]); //可以存多个字符串     printf(“%s”, chs[j]); }  所以，tokens要用二维数组，才能存多个字符串，比如，示例1，[“2”, “1”, “+”, “3”, “*”] tokens[0]=“2”; tokens[1]=“1”; tokens[2]=“+”; tokens[3]=“3”; tokens[4]=“*”; 其中tokens[0]=“2”就是tokens[0][0]=‘2’，tokens[0][1]=‘\0’，也就是tokens[0]的第一个字符是‘2’，第二个字符是‘\0’字符串结束符。所以应该明白为什么tokens是二维数组了吧？一维是存储到字符串，二维是存储到字符。所以，应该明白为什么会有tokens[row][0]，tokens[row][1]了吧，这是取字符串tokens[row]的第一个字符和第二个字符。  对于上面的示例1，要遍历整个tokens，是不是要 for(j=0; j<5; j++) {     printf(“%s”, tokens[j]);//用字符串的方式     for(k=0; k<strlen(tokens[j]); k++) {         printf(“%c”, tokens[j][k]); //用字符的方式     } } 所以程序里的for循环就是要遍历tokens，分别取出tokens的每个字符串来做判断。  那么好了，继续按上面的示例1，当row循环到2时，tokens[row]=tokens[2]=“+”，这是字符串的方式，用字符的方式，是不是就是tokens[2][0]=‘+’，即第一个字符为‘+’，所以if(‘+’==tokens[row][0])就是判断当前字符串的第一个字符是不是为‘+’  同理，减号‘-’的判断是不是应该是if(‘-’==tokens[row][0])，程序里为什么还多了&& ‘\0’==tokens[row][1]？ lz自己想想，tokens[row]=“-”和tokens[row]=“-5”的两个字符串长度分别是多少？两个字符串的第一个字符是什么，第二个字符是什么？想明白了这里就能理解了。  我觉得如果lz对后缀表达式的计算过程如果清楚的话，这里的程序应该很好理解，比如示例1，[“2”, “1”, “+”, “3”, “*”] 遍历tokens的每个字符串 第1次循环，tokens[row]=tokens[0]=“2”，把“2”转成2，压栈pStack[0]=2  第2次循环，tokens[row]=tokens[1]=“2”，把“1”转成1，压栈pStack[1]=1  第3次循环，tokens[row]=tokens[2]=“+”，if(‘+’==tokens[row][0])成立，也就是当前字符串是“+”操作符，于是从操作数栈弹出两个操作数，左操作数是pStack[0]=2，右操作数是pStack[1]=1，进行+运算，得到2+1=3，然后把该结果压栈，即pStack[0]=3，这里为什么是pStack[0]？因为上面第1，2次循环，pStack一共压栈2个操作数，所以出栈2个操作数数后，pStack就空了，所以计算结果3再压栈就是pStack的第一个元素  第3次循环，tokens[row]=tokens[3]=“3”，把“3”转成3，压栈pStack[1]=3  第4次循环，tokens[row]=tokens[3]=“*”，else if(‘*’==tokens[row][0])成立，也就是当前字符串是“*”操作符，于是从操作数栈弹出两个操作数，左操作数是pStack[0]=3，右操作数是pStack[1]=3，进行*运算，得到3*3=9，然后该结果压栈，即pStack[0]=9  然后循环结束，最后返回栈顶元素pStack[0]=9 所以示例1的输出结果为9  整个后缀表达式的思路非常好理解，遍历后缀表达式，遇到操作数则把操作数压栈，遇到运算符（+-*/）则从栈里弹出2个操作数进行计算，然后把计算结果压榨，如此循环，直到遍历后缀表达式结束。  建议lz先把思路理解好了，再去理解程序，那程序就非常好理解了。

user: user-0
content: 还是不懂

user: user-1
content: 1 一维数组能表示字符串吗？要知道，字符串本身就是个字符数组。 char str[][]={“abc”, “efg”, “ijk”} str[0]=“abc”, str[0][0]=‘a’ 是不是需要二维数组？这个二维数组是用来存储输入信息的  2 这个for循环就是循环输入信息的每个字符串  3 这里是判断当前循环的字符串是不是“+”，改成if(strcmp(“+”, tokens[row])==0) 估计你就更好理解一些，str[]=“+”，str[0]=‘+’，所以用字符串比较，tokens[row]就可以了，用字符比较就是tokens[row][0]  4 这里是判断当前字符串是不是“-”，str[]=“-“，是不是就是str[0]=‘-‘, str[1]=‘\0’//字符串结束符？这里之所以这么判断，就是考虑到当前循环字符串可能是“-5”这种情况，这种情况下，tokens[row][1]就不是字符串结束符，其实，用if(strcmp(“-”, tokens[row])==0) 估计你会更容易理解些。

user: user-2
content: 那是字符串，本身就是一维数组，所以就是二维数组了

user: user-0
content: 为什么要用到二维数组？难道不是把数字和符号都放在一维数组中吗？

user: user-2
content: 为什么是二重指针？因为指向的是二维数组 for循环作用：读取输入的二维数组，也即逆波兰表达式，遇到数字入栈，遇到运算符出栈并计算 为什么是tokens[row][0]？因为这是二维数组，每一行都是字符串，这样才可表示 "17" 等多数字 这里'\0' == tokens[row][1]是防止负数被误判为"-"运算符

user: user-0
content: 都好几天了，没有人能够回答我吗？
user-0 提问: 一道指针问题

回复:
user: user-1
content: 推导如下： p[3] = {1,2,3} q[4] = {5,6,7,0} *pp++ = p              相当于 pp[0] = p  *pp = q (后置++后) 相当于 pp[1] = q  *(pp+1) = q; *(*(pp+1)+1) = *(q+1) = q[1] = 6;  pp++ = q ==》此句结束后 pp+1 => pp[1] *(--pp) = p = &p[0] =>pp先-- =》pp[0] *(pp[0]) => p =>&p[0] **(--pp) = p[0] = 1;    也不知表达清楚了没，供参考吧

user: user-2
content: *pp++ = p;      //后缀运算符优先级高于赋值运算符，*pp++ = p执行顺序： *pp，*pp=p，pp++ 也就是上面说的pp[0] = p         *pp = q;      //pp++后， pp[1] = q       printf("%d,%d\n",*(*(pp+1)+1),**(--pp)); 	 /*                  *(pp+1) = q 	 		(*(pp+1)+1) = q+1 			*(*(pp+1)+1) = *(q+1) -> q[1] = 6 					得 *(*(pp+1)+1) = 6 			上一步 pp+1后是 pp[1],(--pp) = pp[0] 			*(--pp) = *pp[0] -> *p[0] 			p[0] = 1,得 **(--pp) = 1 	  	 */

user: user-3
content: 想分析这些指针的含义，可以考虑把这些指针的地址打印出来%p，以便分析。  *(*(pp+1)+1) 这个地方越界了，因为pp申请了2个int *类型的空间，并且在打印之前pp已经指向了第二个int *。因此再pp+1已经越界了。所以这个输出是未定义行为。  #include <stdio.h> #include <stdlib.h>  int main (void) {     int *p,*q,**pp;     int i;      p = (int*) malloc( 3*sizeof(int) );     for(int i = 0;i < 3;i++)     {         *(p+i) = i+1;     }     q = (int*) malloc( 4*sizeof(int) );     for(int i = 0;i < 3;i++)     {         *(q+i) = i+5;     }      pp = (int **) malloc(2*sizeof(int*));     printf("%p, %p, %p, %p\n", p, q, pp, pp+1);     *pp++ = p;     *pp = q;     printf("%p, %p, %p, %p\n", p, q, pp, pp-1);     printf("%p, %p, %p, %p\n", p, q, pp, pp+1);     for (i = 0; i < 3; i++)         printf("%d\t", *(*pp + i));     putchar(10);     printf("%d,%d\n",*(*(pp+1)+1),**(--pp));     free(p);     free(q);     free(pp);      return 0; } 代码中：   *pp++ = p;是指将p赋值给*pp，然后pp++;即pp指向第二个int*元素。（malloc申请了2个int *, 并且pp指向第一个int *） *pp = q;这个就好理解了，第二个元素存q的地址。

user: user-4
content: 楼主可以试试只输出一个 printf("%d\n",*(*(pp+1)+1)); 就会发现问题了

user: user-4
content: 这三条语句，     *pp++ = p;  *pp = q;  printf("%d,%d\n",*(*(pp+1)+1),**(--pp)); 由于第一条后pp已经自增，所以再执行(pp+1)就越界了， 不过这有个BUG,就是printf的执行顺序问题，这里先执行(--pp)，所以程序阴差阳错的对了
user-0 提问: 关于PTA中的题查找子串

回复:
user: user-1
content: 引用 7 楼 深山旧梦还惊觉的回复:[quote=引用 6 楼 trustme___ 的回复:]同学你的测试点是自己调出来的还是老师给了授权？，我自己做只有正确和错误这两个提示，唉~ 啊 你是在哪做的啊 [/quote] 无所谓了，学校要求不同吧

user: user-1
content: 引用 7 楼 深山旧梦还惊觉的回复:[quote=引用 6 楼 trustme___ 的回复:]同学你的测试点是自己调出来的还是老师给了授权？，我自己做只有正确和错误这两个提示，唉~ 啊 你是在哪做的啊 [/quote] 就是pta，不过我必须要老师授权才可以看测试点

user: user-0
content: 引用 9 楼 trustme___ 的回复:[quote=引用 7 楼 深山旧梦还惊觉的回复:][quote=引用 6 楼 trustme___ 的回复:]同学你的测试点是自己调出来的还是老师给了授权？，我自己做只有正确和错误这两个提示，唉~ 啊 你是在哪做的啊 [/quote] 无所谓了，学校要求不同吧[/quote] 我这个是浙大PTA，我这好多不会，枯了

user: user-0
content: 引用 6 楼 trustme___ 的回复:同学你的测试点是自己调出来的还是老师给了授权？，我自己做只有正确和错误这两个提示，唉~ 啊 你是在哪做的啊

user: user-1
content: 同学你的测试点是自己调出来的还是老师给了授权？，我自己做只有正确和错误这两个提示，唉~

user: user-2
content: 引用 4 楼 深山旧梦还惊觉 的回复:[quote=引用 3 楼 自信男孩 的回复:]while( j+k>= MAXS || s[j+k]!= t[k]) return NULL; 加上一个=号，否则也会导致越界。因为j+k的取值是[0, MAXS-1] 大佬您好，我改了一下，在自己电脑运行是没问题但是提交的时候裁判程序还是报那个错误。[/quote]   if( i-l <= MAXS){ 这句有意义吗？i是子串长度，l是源串长度，那么i - l肯定小于MAXS。即使i > l，那么只要不大于30，都是成立的。但是如果i > l，那么就不应该比较了吧。  char *search( char *s, char *t ) {     int i,k,l;     int j=0;     l = strlen(s);     i = strlen(t);     printf("i = %d, l = %d\n", i, l);     if( i < l) {         while(s[j]){                                          //循环至数组结束             if(s[j]==t[0]){                                     //如果发现第一个字母                 for( k=1 ; k<i ;k++){                           //对后俩个字母                     //while( s[j+k]!= t[k]|| j+k>MAXS) return NULL;          //制药后面的字母不对就返回null                     while( j + k >= l || s[j+k]!= t[k]) return NULL;          //制药后面的字母不对就返回null                 }                  return &s[j];                                   //如果都对上返回首字母地址              }                                  //如果找不到第一个字母返回null             j++;         }     }     return NULL; }  供参考～  如果还有问题，建议测试样例中加上输入的源串长度正好是MAXS-1或者大于等于MAXS。 楼主的输入逻辑里，没有对输入的内容大于等于MAXS做判断。

user: user-0
content: 引用 3 楼 自信男孩 的回复:while( j+k>= MAXS || s[j+k]!= t[k]) return NULL; 加上一个=号，否则也会导致越界。因为j+k的取值是[0, MAXS-1] 大佬您好，我改了一下，在自己电脑运行是没问题但是提交的时候裁判程序还是报那个错误。

user: user-2
content: while( j+k>= MAXS || s[j+k]!= t[k]) return NULL; 加上一个=号，否则也会导致越界。因为j+k的取值是[0, MAXS-1]

user: user-2
content: while( s[j+k]!= t[k]|| j+k>MAXS) return NULL; 这条语句要先判断j+k > MAXS，然后再判断s[j+k] != t[k];  while( j+k>MAXS || s[j+k]!= t[k]) return NULL;  否则会导致越界。

user: user-0
content: 这个是错误 传错图片了
user-0 提问: 为什么输出了两次

回复:
user: user-1
content: 当i=39和i=61时，都会满足c1 + c2 + c3 + c4 + c5 + c6 == 6这个条件，也就是说，此时c1~c6的值都是1

user: user-2
content: 其实吧，就是循环中，出现了两次满足if(c1+c2+c3+c4+c5+c6==6)这一条件的情况，与getchar()无关

user: user-3
content: getchar( ); 这条语句需要输入一次才能退出main。   直接回车即可。  输入两次怀疑是因为这个getchar();需要输入一次，所以总共要输入2次。
user-0 提问: 	[Error] expected ')' before ';' token

回复:
user: user-1
content: c5=(C&&!D || (!C&&D); 这句很明显缺少一个括号匹配（右括号） 改成如下：  c5=(C&&!D) || (!C&&D);  楼主的逻辑建议优化一下，6层循环还是第一次看到。循环多，效率就降低了～

user: user-0
content: 找到问题了 c5=(C&&!D || (!C&&D);  少了个)

user: user-2
content: 是否是(C&&!D)||(!C&&D)  ?  代码中的括号显然不匹配