Mxode/CSDN-C_Language-2013_2023 huggingface dataset:
user-0 提问: 如何保证多个子线程中数据读写不冲突

回复:
user: user-1
content: 引用 8 楼 xyj8035 的回复:[quote=引用 7 楼 陈仲甫的回复:]Win下你可以用简单的消息传递 123读到的数据都PostThreadMessage给4 这些数据会被自动串行化 放到一个消息队列中 请问有具体示例吗[/quote]  在接收线程中： BOOL bRet; MSG msg = {0}; while( (bRet = GetMessage( &msg, nullptr, 0, 0 )) != 0) {      if (bRet == -1)     {         // handle the error and possibly exit     }     else     {        if ((WM_APP+100) == msg.message)        {             ASSERT(msg.wParam == 200);             ASSERT(msg.lParam == 400);     } }  2\3\4中PostThreadMessage(IdOfThread1, WM_APP+100, 200, 400);

user: user-0
content: 引用 9 楼 千梦一生的回复:怀疑用不用锁的都上锁吧。 这样会导致速度慢很多啊。。。 我现在每个端口10ms刷新一次

user: user-2
content: 怀疑用不用锁的都上锁吧。

user: user-0
content: 引用 7 楼 陈仲甫的回复:Win下你可以用简单的消息传递 123读到的数据都PostThreadMessage给4 这些数据会被自动串行化 放到一个消息队列中 请问有具体示例吗

user: user-1
content: Win下你可以用简单的消息传递 123读到的数据都PostThreadMessage给4 这些数据会被自动串行化 放到一个消息队列中

user: user-3
content: 不同线程之间通信可以考虑用队列。在线程4中设置缓存buf，将1，2，3读取的数据进行保存处理。避开用锁。

user: user-4
content: 網上很多資料啊，搜索一下互斥鎖、多綫程編程都能找到。

user: user-0
content: 引用 3 楼 SuperLy的回复:如果只是读取数据，可以不用锁住，只需要在读取完成后判断一下是否读取完整就行。 具体怎么做 有示例吗

user: user-5
content: 如果只是读取数据，可以不用锁住，只需要在读取完成后判断一下是否读取完整就行。

user: user-6
content: 鎖沒加好吧，你看看這個有用沒 https://blog.csdn.net/suifengsanjin/article/details/104993163

user: user-7
content: 1. 对于简单的数据类型，可以用atomic 2. 有多少个共享数据就有多少个锁，每个锁只负责保护一个数据 3. 锁的范围尽可能小，尝试在锁里面把共享数据拷贝一份到local变量里 4. 锁尽量不要嵌套
user-0 提问: 这里必须用if-else的嵌套，为什么？

回复:
user: user-1
content: 不用也行，只是代码优化的问题。若上一个if已符合条件，则少调用一次if判断语句。

user: user-2
content: 因为除了英文字母和数字字符，还有标点符号字符，所以要分别判断各种字符的条件 这里不一定非要用if else，也可以用多个并列if，比如以下也能达到目的 if(c>='A'&&c<='Z'||c>'a'&&c<='z') numC++; // if(c>='0'&&c<='9')    numI++; //两个if并列  但两个if并列，比if else多了一次判断操作，性能稍微有所下降，即 if else的情况 if(c>='A'&&c<='Z'||c>'a'&&c<='z') numC++; //满足这里的if else if(c>='0'&&c<='9')    numI++; //就不会判断else if的条件 而并列if的情况 if(c>='A'&&c<='Z'||c>'a'&&c<='z') numC++; //满足了这里的if if(c>='0'&&c<='9')    numI++; //这里还会继续判断if条件，所以相比if else来说，多一次判断操作

user: user-3
content: 你的问题问的也有问题呢，用不用if else嵌套，要看你要实现什么，不用嵌套需要确认你输入的都能是你想要的吗？  if(c>='A'&&c<='Z'||c>'a'&&c<='z')  这个判断有问题呢  if((c>='A'&&c<='Z') || (c>'a'&&c<='z'))  改成这样～
user-0 提问: 循环嵌套问题求解

回复:
user: user-1
content: 晕，还是看错打印部分了，打印在外循环。 你就理解while的分析就好了，打印部分忽略

user: user-1
content: 上面打印部分说错了，打印部分在内循环外，看错了，看成打印部分在内循环了。 首先要理解，b--是先取b的值做运算，运算结束后b的值递减1 所以 i=1第一次大循环 b=i%2=1 然后第一次内循环 b=1，while(b-->=0)的执行顺序是，先取b的值1来做比较运算，运算结果为true，然后b递减1变为0，然后while(运算结果true)满足循环条件，进入内循环执行k++，k变为1（这里看错了，没有打印信息） 然后第二次内循环 b=0，while(b-->=0)的执行顺序是，先取b的值0来做比较运算，运算结果为true，然后b递减1变为-1，然后while(运算结果true)满足循环条件，进入内循环执行k++，k变为2 然后第三次内循环 b=-1，while(b-->=0)的执行顺序是，先取b的值-1来做比较运算，运算结果为false，然后b递减1变为-2，然后while(运算结果false)不满足循环条件，内循环结束 然后执行打印，b=-2，k=2（这里才有打印） 然后继续i=2第二次大循环 b=i%2=0 然后内循环，while(b-->=0)的执行顺序同上 依次类推，直到大循环结束

user: user-1
content: 分析图已经很明确了 首先要理解，b--是先取b的值做运算，运算结束后b的值递减1 所以 i=1第一次大循环 b=i%2=1 然后第一次内循环 b=1，while(b-->=0)的执行顺序是，先取b的值1来做比较运算，运算结果为true，然后b递减1变为0，然后while(运算结果true)满足循环条件，进入内循环执行k++，k变为1，打印b=0，k=1 然后第二次内循环 b=0，while(b-->=0)的执行顺序是，先取b的值0来做比较运算，运算结果为true，然后b递减1变为-1，然后while(运算结果true)满足循环条件，进入内循环执行k++，k变为2，打印b=-1，k=2 然后第三次内循环 b=-1，while(b-->=0)的执行顺序是，先取b的值-1来做比较运算，运算结果为false，，然后b递减1变为-2，然后while(运算结果false)不满足循环条件，内循环结束 内循环结束后继续i=2第二次大循环 b=i%2=0 然后内循环，while(b-->=0)的执行顺序同上 依次类推，直到大循环结束

user: user-2
content: b-- >=  0注意是先把b--整个表达式的值与0比较，再计算自减～
user-0 提问: 这个整么进行.txt文件读取啊  请教大神！！！

回复:
user: user-0
content: 蟹蟹 蟹蟹 弄好了

user: user-1
content: 单行读取，查看strtok函数用法，进行字符串分割，放到字符串数组中。 这是一位大神关于c语言字符串的分割函数。供参考：https://www.cnblogs.com/wkfvawl/p/9042695.html 如果在linux上，还可以考虑用 cut  ，awk 命令。

user: user-2
content: 首先，让你的程序和你要读取的txt在同一个文件夹里（不然你要自己手动敲地址），运用freopen，即freopen（"a.txt","r",stdin）;这一条语句，a.txt是你的文件名，r是以只读模式打开，stdin则是以标准形式读入， 如下： #include<stdio.h> int main() { 	freopen("a.txt","r",stdin); }

user: user-3
content: fscanf读取，因为是有固定格式的。

user: user-4
content: 根据每个单元的偏移按行读取

user: user-5
content: 不是以空格来分隔了？
user-0 提问: 如何在vs code 中实现不同C语言程序之间的函数互相调用的问题？

回复:
user: user-1
content: C和C++完整教程:https://blog.csdn.net/it_xiangqiang/category_10581430.html C和C++算法完整教程:https://blog.csdn.net/it_xiangqiang/category_10768339.html

user: user-2
content: 你这是visual studio吧

user: user-0
content: 不好意思，我这里更正一下文件main.c的内容  # include "stdio.h" # include "function.h"   /*包含的头文件*/ int main() { int a=2; int b=4;         printf( "%d\n",fun(a,b));         printf( "%d\n",times(a,b));         return 0; }

user: user-3
content: 这还不算难的，难的是不同架构间，不同系统、编译器不一样之间的相互调用。
user-0 提问: printf("now i=%d,flag=%d",i,flag);这条语句会执行吗？ 

回复:
user: user-1
content: 不会执行，因为这条语句和break在同一个代码块里，并且实在break之后，根据顺序执行，执行到break之后后面的就不会执行了，直接跳出循环了～

user: user-2
content: 不会，跳出循环
user-0 提问: 请问一下我的代码怎么不能自动登录到指定网页?求助大神解析一下.

回复:
user: user-1
content: 问题是为什么会登录对应的网站，网站的打开需要浏览器，楼主用命令并没有调用浏览器吧  建议了解一下网页打开的原理～
user-0 提问: c 语言指针变量相减

回复:
user: user-1
content: 指针 - 指针 = 两者差／指针所指向变量类型的长度  例如，int *a = 12; int*b = 6; a - b = (12-6)/4;  这里说的int类型字节长度为4

user: user-1
content: 引用 8 楼 真相重于对错的回复:[quote=引用 3 楼 sunjianan2020418 的回复:][quote=引用 1 楼 自信男孩的回复:]没什么问题，是对指针赋值呢。5,8地址。楼主并没有对5,8对应的内存做读写操作呢？只是指针的加减法，类似普通变量的加减法～ 为什么最后等于零了[/quote] char** 指向的地址里面存放的是char*,char* 的长度是4字节（32位），8 和 5之间不能存放一个char* ,指针相减结果是二者之间能够放多少个这个类型的数据 所以p1-p2 放不下一个，因此为0 如果改成char* p1 ,*p2; p1-p2 就是3[/quote] 这个回答是正解

user: user-0
content: 引用 7 楼 千梦一生的回复:[quote=引用 6 楼 千梦一生 的回复:]就是说，指针在电脑看来跟int没任何区别。唯一不同在于：你指定它是指针，那么，电脑就听你的把int的值当作地址来看。 再描述就是：你可以认为指针就是一个int【跟int一模一样】，但它被你叫做指针，所以，电脑允许你通过（*指针）的方式去把该int的值作为地址访问指向的数据。[/quote] 懂了谢谢

user: user-0
content: 引用 9 楼 暮霞。的回复:我觉得是因为，你的p，q都没有开辟指针的空间，在后面	p = (char**)5;q = (char**)8;这两句就好像是强行给两个指针空间地址 指针相减的结果=(地址1-地址2)/sizeof(类型) 如上就是 （8 - 5）/ 4 = 0.75 但是由于会默认输出int类型，因为0 好的谢谢你

user: user-0
content: 对的就是这样

user: user-2
content: 用gcc编译不行，打印不出来；不理解。

user: user-3
content: 我觉得是因为，你的p，q都没有开辟指针的空间，在后面	p = (char**)5;q = (char**)8;这两句就好像是强行给两个指针空间地址 指针相减的结果=(地址1-地址2)/sizeof(类型) 如上就是 （8 - 5）/ 4 = 0.75 但是由于会默认输出int类型，因为0

user: user-4
content: 引用 3 楼 sunjianan2020418 的回复:[quote=引用 1 楼 自信男孩的回复:]没什么问题，是对指针赋值呢。5,8地址。楼主并没有对5,8对应的内存做读写操作呢？只是指针的加减法，类似普通变量的加减法～ 为什么最后等于零了[/quote] char** 指向的地址里面存放的是char*,char* 的长度是4字节（32位），8 和 5之间不能存放一个char* ,指针相减结果是二者之间能够放多少个这个类型的数据 所以p1-p2 放不下一个，因此为0 如果改成char* p1 ,*p2; p1-p2 就是3

user: user-5
content: 引用 6 楼 千梦一生 的回复:就是说，指针在电脑看来跟int没任何区别。唯一不同在于：你指定它是指针，那么，电脑就听你的把int的值当作地址来看。 再描述就是：你可以认为指针就是一个int【跟int一模一样】，但它被你叫做指针，所以，电脑允许你通过（*指针）的方式去把该int的值作为地址访问指向的数据。

user: user-5
content: 就是说，指针在电脑看来跟int没任何区别。唯一不同在于：你指定它是指针，那么，电脑就听你的把int的值当作地址来看。

user: user-6
content: 两个指针相减的意义在于，假定它们指向同一个数组内的不同元素，则相减后，得到两个元素下标的差值。

user: user-0
content: 引用 2 楼 千梦一生的回复:你写的是代码。 机器理解的是0、1 中间有个叫编译器的为你把你的代码翻译给机器听。 指针、int的区别是编译器看的。机器看指针和int没区别 说的浅点呗还是不懂啊

user: user-0
content: 引用 1 楼 自信男孩的回复:没什么问题，是对指针赋值呢。5,8地址。楼主并没有对5,8对应的内存做读写操作呢？只是指针的加减法，类似普通变量的加减法～ 为什么最后等于零了

user: user-5
content: 你写的是代码。 机器理解的是0、1 中间有个叫编译器的为你把你的代码翻译给机器听。 指针、int的区别是编译器看的。机器看指针和int没区别

user: user-7
content: 没什么问题，是对指针赋值呢。5,8地址。楼主并没有对5,8对应的内存做读写操作呢？只是指针的加减法，类似普通变量的加减法～
user-0 提问: float尾数只有23位能够精确24位最大数是16777215.根本精确不到3.4e38这个取值范围。如果我赋值一个数大于

回复:
user: user-1
content: 浮点数是表示范围大, 但是精度不高,  23位二进制精度用10进制就是6-7位精度, 超过的精度会丢失  f=16777219.0  e=log(f)/log(2) e=0+(e|0)  m=(1<<23) n=(f/pow(2,e) - 1.0) n=n*m n=((n+0.5)|0)                         //这里四舍五入, 精度丢失  h = 0 | ((e+0x7f)<<23) | n    // 这里是16进制储存数据  v=h&(m-1) v=(v+0.0)/m f=(1.0+v)*pow(2,e)              // 这里最终结果成了  16777220    以下是计算步骤:  f = 16777219.00000000 16777219.00000000 e = log ( f ) / log ( 2 ) e = 16.63553251225261 / log ( 2 ) e = 16.63553251225261 / 0.6931471805599453 e = 24.00000025797396 24.00000025797396 e = 0 + ( e | 0 ) e = 0 + 0x0000000000000018 e = 24 24 m = ( 1 << 23 ) m = 0x0000000000800000 0x0000000000800000 n = ( f / pow ( 2 , e ) - 1.000000000000000 ) n = ( f / 16777216.00000000 - 1.000000000000000 ) n = ( 1.000000178813934 - 1.000000000000000 ) n = 1.788139343261719E-007 1.788139343261719E-007 n = n * m n = 1.500000000000000 1.500000000000000 n = ( ( n + 0.5000000000000000 ) | 0 ) n = ( 2.000000000000000 | 0 ) n = 0x0000000000000002 0x0000000000000002 h = 0 | ( ( e + 0x000000000000007F ) << 23 ) | n h = 0 | ( 151 << 23 ) | n h = 0 | 0x000000004B800000 | n h = 0x000000004B800000 | n h = 0x000000004B800002 0x000000004B800002 v = h & ( m - 1 ) v = h & 0x00000000007FFFFF v = 0x0000000000000002 0x0000000000000002 v = ( v + 0.0000000000000000 ) / m v = 2.000000000000000 / m v = 2.384185791015625E-007 2.384185791015625E-007 f = ( 1.000000000000000 + v ) * pow ( 2 , e ) f = 1.000000238418579 * pow ( 2 , e ) f = 1.000000238418579 * 16777216.00000000 f = 16777220.00000000 16777220.00000000

user: user-2
content: 自定义想要的数据类型，重载需要的计算方式。

user: user-0
content: 看我的问题在回答，我不是要你告诉我单精度是怎么存储的。我的问题是如果尾数超出23位后怎么转换成十进制比如 我定义一个float016777219二进制是1.00000000000000000000011*24尾数已经24位了超出尾数表示范围了。单结果是16777220是为什么 我的问题是如果指数超过23位后比如指数是25怎样还原十进制

user: user-3
content: https://www.cnblogs.com/fengliu-/p/7455246.html 建议了解一下这个～
user-0 提问: 链表中的删除问题

回复:
user: user-1
content: #include <stdio.h> #include <stdlib.h> #include <time.h>  typedef struct node {     int data;     struct node *next; }Node;  //void Creat(Node *h) void Creat(Node **h) {     int i,n;     Node *p , *node;     //h->next = NULL;     //p = h;     srand(time(0));     printf("请输入结点数量：");     scanf("%d",&n);     for (i = 0; i < n; i++)     {         node = (Node*)malloc(sizeof(Node));         node->data = rand() % n;         if (*h == NULL) {             (*h) = node;             p = (*h);         } else {             p->next = node;             p = node;         }     }     p->next = NULL; }  //void Delete(Node *h)   //n为被删除数据所在的位置 void Delete(Node **h)   //n为被删除数据所在的位置 {     int i,n;     Node *p=*h;     Node *q;     printf("请输入要删除第几个数据：");     scanf("%d",&n);      if (n == 1) {         *h = (*h)->next;         free(p);         return;     }     for (i = 1; i < n-1; i++)     {         if (!p)             break;         p = p->next;     }     if (!p) {         printf("Can't find it!\n");         return;     }      //q = p;     q = p->next;     if (!q) {         printf("Can't find it!\n");         return;     }     //p->next = (q->next)->next;     p->next = q->next;     //free(q->next);     free(q); }   void Print(Node *h) {     Node *p;     p = h;     printf("数据如下：");     //while (p->next != NULL)     while (p != NULL)     {         printf("%d ",p->data);         p = p->next;     }     printf("\n"); }  int main(void) {     Node *head = NULL;      Creat(&head);     Print(head);     Delete(&head);     Print(head);     return 0; } 供参考～  楼主的创建链表，删除链表以及输出都有问题～

user: user-2
content: 最好画个图这样更清晰一些 修改如下  for (i = 1; i < n; i++) {      p = p->next; } q = p->next; p->next = q->next; free(q)
user-0 提问: 常指针和指针常量

回复:
user: user-1
content: int* 声明一个指向内容为int类型指针从 可以类比 const *  是在声明一个指向内容为常量类型的指针 【并且实际情况也正是如此】

user: user-1
content: 引用 7 楼 Wyk2016 的回复:[quote=引用 1 楼 千梦一生的回复:]简单的一匹  * 和const的位置可以读出正确的名字  int* int 的 指针【即指针指向的内容是int】  const *  常量 的 指针 【即指针指向的内容是常量】  const int* int型常量 的 指针【即指针指向的内容是int型常量】   区分两者把语文学好就可以了 没有自己的见解，太死板，没有精髓，[/quote]  这就是我过去学习后自己的理解。难道你认为我是从哪里抄来的吗？ 最后发现区分指针常量、常量指针只需要看 * 和const的相对位置就行了。 而辨识二者的区别，则只需要把语文常识学好就行了。找到定语即可

user: user-0
content: 引用 1 楼 千梦一生的回复:简单的一匹  * 和const的位置可以读出正确的名字  int* int 的 指针【即指针指向的内容是int】  const *  常量 的 指针 【即指针指向的内容是常量】  const int* int型常量 的 指针【即指针指向的内容是int型常量】   区分两者把语文学好就可以了 没有自己的见解，太死板，没有精髓，

user: user-0
content: 引用 5 楼 Wyk2016的回复:各位大神，细品，什么是精练， 4楼的弟兄提议很好，

user: user-0
content: 各位大神，细品，什么是精练，

user: user-2
content: const* 常指针强调你不可以通过本指针来操作其指向的内容 这句话需要改一下，不可以通过本指针来修改（写）其指向的内容，不包括读哦，是可以读的

user: user-3
content: 说起来挺可笑的，绝大多数C语言图书都没把这个问题讲清楚。

user: user-4
content: 指向常量的指针表示该指针中存放的是常量的地址，常量指针指的是指针本身是常量，不能修改该指针中保存的地址，而该地址保存的可以是常量也可以是变量。 具体区别请参考《C++中指向常量的指针和常量指针》 希望能够帮到您！

user: user-1
content: 简单的一匹  * 和const的位置可以读出正确的名字  int* int 的 指针【即指针指向的内容是int】  const *  常量 的 指针 【即指针指向的内容是常量】  const int* int型常量 的 指针【即指针指向的内容是int型常量】   区分两者把语文学好就可以了
user-0 提问: 关于c语言返回值的地址问题

回复:
user: user-1
content: 把lptr赋值给头文件里的rtn。 这句话如果使用memcpy或者sprintf的话，应该是没有问题的。  可以在free掉lptr 只有加一句打印。 打印一下此时的rtn。看看问题出在哪里。

user: user-2
content: 你的代码呢？从你的描述来看，看不出为什么的。fun函数返回的是什么地址，局部变量地址，还是全局变量地址以及静态变量等等这些不清楚呢

user: user-3
content: 不知道。 不过如果是水平不到位的程序容易犯的一个错误是返回局部变量地址。这种是不安全不正确的

user: user-4

user: user-5
content: 你把代码贴全了 要知道fun是怎么返回结果的才能帮你分析

user: user-0
content: 引用 11 楼 自信男孩的回复:[quote=引用 6 楼 subosen 的回复:][quote=引用 4 楼 自信男孩的回复:]你的代码呢？从你的描述来看，看不出为什么的。fun函数返回的是什么地址，局部变量地址，还是全局变量地址以及静态变量等等这些不清楚呢 头文件定义返回的数据 char rtn[1024]; 下面是外部函数逻辑 char* fun(char* p){ char* lptr ; 下面逻辑省略写了哈 malloc开辟lptr的空间 一系列操作 把lptr赋值给头文件里的rtn free掉lptr return rtn; } 逻辑大致这样[/quote] 没看到参数p做了什么？那么这个参数有啥意义呢？[/quote] 在一系列操作里

user: user-2
content: 引用 6 楼 subosen 的回复:[quote=引用 4 楼 自信男孩的回复:]你的代码呢？从你的描述来看，看不出为什么的。fun函数返回的是什么地址，局部变量地址，还是全局变量地址以及静态变量等等这些不清楚呢 头文件定义返回的数据 char rtn[1024]; 下面是外部函数逻辑 char* fun(char* p){ char* lptr ; 下面逻辑省略写了哈 malloc开辟lptr的空间 一系列操作 把lptr赋值给头文件里的rtn free掉lptr return rtn; } 逻辑大致这样[/quote] 没看到参数p做了什么？那么这个参数有啥意义呢？

user: user-2
content: 引用 6 楼 subosen 的回复:[quote=引用 4 楼 自信男孩的回复:]你的代码呢？从你的描述来看，看不出为什么的。fun函数返回的是什么地址，局部变量地址，还是全局变量地址以及静态变量等等这些不清楚呢 头文件定义返回的数据 char rtn[1024]; 下面是外部函数逻辑 char* fun(char* p){ char* lptr ; 下面逻辑省略写了哈 malloc开辟lptr的空间 一系列操作 把lptr赋值给头文件里的rtn free掉lptr return rtn; } 逻辑大致这样[/quote] 楼主的是返回全局变量，如果不一致，那么看一下最后修改的是那个？

user: user-3
content: printf(,f(1),f(2));  f(1),f(2) 先于printf();  f(1),f(2)两个 形式一样的函数连续调用，第一个malloc【比如结构体A大小的数据1】后free掉它。紧跟着第二个函数一模一样的函数调用，再次malloc【由于上下文、以及环境几无变化，因此我认为】操作系统极有可能就又把你释放的那一块拿来给你用【比如你在这里创建了一个结构体A大小的数据2】，后再free掉它。 ------------------------此时f(1),f(2)返回的都是野指针，但都指向了第二个执行的【f(1)或者f(2)之一】f()函数处理后的数据：数据2 紧跟着printf(，数据2的指针【野指针，危险】，数据2的指针【野指针，危险】)

user: user-3
content: 引用 6 楼 subosen 的回复:把lptr赋值给头文件里的rtn free掉lptr return rtn; 返回了个野指针

user: user-0
content: 我是楼主，因为项目信息安全原因不能贴代码，只能大致说一说不好意思哈(T ^ T)

user: user-0
content: 引用 4 楼 自信男孩的回复:你的代码呢？从你的描述来看，看不出为什么的。fun函数返回的是什么地址，局部变量地址，还是全局变量地址以及静态变量等等这些不清楚呢 头文件定义返回的数据 char rtn[1024]; 下面是外部函数逻辑 char* fun(char* p){ char* lptr ; 下面逻辑省略写了哈 malloc开辟lptr的空间 一系列操作 把lptr赋值给头文件里的rtn free掉lptr return rtn; } 逻辑大致这样

user: user-0
content: 引用 1 楼 user-5的回复:你把代码贴全了 要知道fun是怎么返回结果的才能帮你分析 头文件定义返回的数据 char rtn[1024]; 下面是外部函数逻辑 char* fun(char* p){ char* lptr ; 下面逻辑省略写了哈 malloc开辟lptr的空间 一系列操作 把lptr赋值给头文件里的rtn free掉lptr return rtn; } 逻辑大致这样
user-0 提问: 为什么我输入第九个值后，才会倒序打印前8个值？

回复:
user: user-1
content: 您好，首先整理您的代码如下： #include <stdio.h>  int main(void)  { 	int number[8],a; 	 	for (a = 0;a < 8;++a) 		scanf_s("%d ", &number[a]); 		 	for (a = 7;a >= 0;a--) 		printf("%d ", number[a]); 		 	printf("\ndone"); 	 	return 0; }  其次我参考了如下网址： https://blog.csdn.net/silleyj/article/details/8545408  接着我使用了在线编译，模拟了您的代码，有如下几种情况 1、当输入 7 个参数时，由于是在线模拟，他自己给我补了一个随机数上去，然后倒序打印出 8 个数； 2、当输入 8 个参数时，可以正常倒序打印； 3、由上述两种情况分析，代码应该是没问题的。  思考方向： 1、参考上述网址，使用 scanf_s 时，是否要加第三个指定数据长度的参数？ 2、在输入第 8 个数值之后，是否有按下回车的操作？个人感觉，如果没有此操作，编译器可能不知道你是否输入完毕，只有当你输入第 9 个元素时，超出数据范围，才会跳出。  建议： 1、后续代码建议直接放到代码框中，便于阅读~

user: user-2
content: #include <stdio.h>  int main(void) {     int number[8],a;     for (a = 0;a < 8;++a)         //scanf_s("%d ", &number[a]); 	scanf_s("%d", &number[a]);     for (a = 7;a >= 0;a--)         printf("%d ", number[a]);     printf("\ndone");     return 0; } 供参考～  去掉%d后面的空格
user-0 提问: 删除字符串中指定的字符

回复:
user: user-1
content: 上面有点错误，稍微修改 while(str[i]!=‘\0’) {     while (str[i]==c) { //这里用while，因为后面移向前的字符也可能是c         for(j=i; str[j]!=‘\0’; j++) {             str[j]=str[j+1];         }     }     i++; } 这个算法太频繁移动元素了，效率不高 改成以下更好一些 for(i=0,j=0; str[i]!=‘\0’; i++) {     if(str[i]!=c) str[j++] = str[i]; //只保存不为c的字符 } str[j]=‘\0’; //最后加上字符串符

user: user-1
content: 把while(str[i]==c)改成while(str[i]!=‘\0’) 否则一旦str[i]!=c循环就结束了了，后面还有str[i]==c也不会被处理了 所以 while(str[i]!=‘\0’) {     if (str[i]==c) {         for(j=i; str[j]!=‘\0’; j++) {             str[j]=str[j+1];         }     }     i++; }

user: user-2
content: char *de_character(char* src, int ch) {     char *ret = src;     char *dst = src;     while (*src) {         if (*src != ch)             *dst++ = *src;         src++;     }     *dst = '\0';      return ret; }  供参考～
user-0 提问: srand()和rand()

回复:
user: user-1
content: C:\Program Files (x86)\Windows Kits\10\Source\10.0.10150.0\ucrt\stdlib\rand.cpp // // rand.cpp // //      Copyright (c) Microsoft Corporation. All rights reserved. // // Defines rand(), which generates psuedorandom numbers. // #include <corecrt_internal.h> #include <stdlib.h>    // Seeds the random number generator with the provided integer. extern "C" void __cdecl srand(unsigned int const seed) {     __acrt_getptd()->_rand_state = seed; }    // Returns a pseudorandom number in the range [0,32767]. extern "C" int __cdecl rand() {     __acrt_ptd* const ptd = __acrt_getptd();      ptd->_rand_state = ptd->_rand_state * 214013 + 2531011;     return (ptd->_rand_state >> 16) & RAND_MAX; }

user: user-2
content: srand是设置随机数的种子， 正常情况下，这个函数不应当过于频繁的调用，一般程序运行时初始化一次即可。

user: user-3
content: The srand() function sets its argument as the seed for a new sequence of pseudo-random integers to be returned by rand().  These sequences are repeatable by calling srand() with the same seed        value  srand是生成随机数的种子，如果放在循环里，那么就是种子跟着变化，那么生成的就是相同序列的数值。

user: user-4
content: 在C++中产生随机数的步骤分为两步：第一步是设置起始数；第二步是产生伪随机数。 srand()函数的作用是设置起始数，当起始数相同时，产生的随机数也是相同的，在for循环内部，您每次调用time()函数获取的时间都相同（for循环消耗的时间太短），即起始数是相同的，所以您获取到的随机数也是相同的。可以考虑在for循环中加一个延迟函数，例如 	for (i = 0; i < 10; i++) 	{ 		srand((time(NULL))); 		a[i] = rand() % 10; 		Sleep(1000);//-------延迟1秒--------- 	} 这样，每次调用time得到的就是不同的时间了，因此也会得到不同的随机数。需要注意的是，使用Sleep()函数，需要 #include <Windows.h> 另外，对于srand()函数和rand()函数产生随机数的详细方法，请参考《C++中产生随机整数的方法（srand()函数与rand()函数）》 希望能够帮到您！

user: user-0
content: 谢谢各位了，明白了
user-0 提问: 创建快捷方式为什么需要管理员运行？

回复:
user: user-1
content: 引用 5 楼 六道佩恩 的回复:话说这是在用指针访问C++的方法吗？ 微软为 COM 接口定义了自己的 ABI，并要求所有使用 COM 接口的编程语言都按照这个 ABI 进行操作。因此，无论是用 C 还是 C++ 语法访问 COM 接口，最终生成的 ABI 都是与 COM 兼容的，造成了 C 能访问 C++ 方法的“假象”。但在非 COM 代码中强烈不建议这么做，因为会损害稳定性和可移植性。

user: user-0
content: 引用 4 楼 user-1 的回复:[quote=引用 3 楼 六道佩恩 的回复:] 你这个不是C接口啊，我要C接口的 可参考 https://gitee.com/apkipa-byte/codes/qcwvad58tonkrgemz0jxl46/raw?blob_name=main.c，基于我给出的链接中的 C++ 例子。[/quote] 话说这是在用指针访问C++的方法吗？

user: user-1
content: CreateSymbolicLinkA 创建的是符号链接，不是所谓的快捷方式。创建快捷方式请使用 IShellLink 和 IPersistFile 接口。具体操作请参考 https://docs.microsoft.com/zh-cn/windows/win32/shell/links。

user: user-1
content: 引用 3 楼 六道佩恩 的回复:你这个不是C接口啊，我要C接口的 可参考 https://gitee.com/apkipa-byte/codes/qcwvad58tonkrgemz0jxl46/raw?blob_name=main.c，基于我给出的链接中的 C++ 例子。

user: user-0
content: 引用 1 楼 user-1 的回复:CreateSymbolicLinkA 创建的是符号链接，不是所谓的快捷方式。创建快捷方式请使用 IShellLink 和 IPersistFile 接口。具体操作请参考 https://docs.microsoft.com/zh-cn/windows/win32/shell/links。 你这个不是C接口啊，我要C接口的

user: user-0
content: 引用 1 楼 user-1 的回复:CreateSymbolicLinkA 创建的是符号链接，不是所谓的快捷方式。创建快捷方式请使用 IShellLink 和 IPersistFile 接口。具体操作请参考 https://docs.microsoft.com/zh-cn/windows/win32/shell/links。 这两种有什么区别？区别大吗？
user-0 提问: C语言在处理UTF-8字符时，数据类型为什么用char *，而不是unsigned char *？

回复:
user: user-1
content: 在C语言里，char类型可能等同于signed char，也可能等同于unsigned char，可以在编译时指定char类型到底等同于哪一个。要不，你问问Linux在编译时是怎么指定的？

user: user-2
content: 字符集编码现在也没有搞清楚

user: user-0
content: 因为涉及字节运算，我经常会遭遇符号位扩展方面的困扰，搞得简直都有些抑郁了！ 不得不条件反射地、歇斯底里地、不停地： x & 0xFF;  似乎只要一不留神，就会被符号位给坑害啦！呵呵。

user: user-3
content: 只有右移对有符号数、无符号数有不同操作，其他都没影响

user: user-0
content: 引用 2 楼 千梦一生 的回复:字符你认为拿来进行数字计算的可能性会多大？ 即便遇到了需要对字符编码进行数字运算。能这么做的估摸也对字符有一定的认识，会漏下这个？ unsigned 的意义完全就属于数学运算上的意义。 如果对字符确实有数学运算这方面的需求，可以根据具体运算情况进行选择是否unsigned。  若考虑到字符加密，需进行字节逻辑运算：^&|~的话，估计就不会轻下这个结论了。

user: user-4
content: 樓上說得對，它的意義僅僅在於“開闢一塊内存區”

user: user-5
content: 搞编码的，搞内存处理哪方面的人而言，{int、 unsigned int}，{char*，void*，...*},{int8,char, unsigned char}这些 真区别不大

user: user-4
content: 要看具體的處理代碼，char的符號位有用也僅是在當作短整數使用的情況

user: user-5
content: 字符你认为拿来进行数字计算的可能性会多大？ 即便遇到了需要对字符编码进行数字运算。能这么做的估摸也对字符有一定的认识，会漏下这个？  unsigned 的意义完全就属于数学运算上的意义。 如果对字符确实有数学运算这方面的需求，可以根据具体运算情况进行选择是否unsigned。

user: user-5
content: 我感觉啊。可能是因为少打一个unsigned的原因。

user: user-4
content: 位運算不需要考慮符號位，一樣處理
user-0 提问: 为什么while循环执行不了，菜鸟很懵逼

回复:
user: user-1
content: 问题不少,优化一下,我也是菜鸟,马上三年级  #include <stdio.h> int main()   { 	int number, min, max, count, /*status,*/ sum;  	//sum = 0;  	count = 0;  	printf("Enter lower and upper integer limits:");  	//scanf_s("%d %d", &min, &max);  	//status = (scanf_s("%d %d", &min, &max) == 2);  	while (scanf_s("%d %d", &min, &max)!=EOF) 	{ 		sum = 0;//防止多次操作累加  		for (number = min; number <= max; number++) 		{ 			count = number * number; 			sum += count; 		} 		printf("The sums of the squares from %d to %d is %d", min , max , sum); 		//printf("Enter next set of limits :"); 		//scanf_s("%d %d", &min, &max); 	} 	printf("Done"); 	return 0; }

user: user-2
content: 应该是if (status)  否则死循环了

user: user-3
content: 可以在while循环前打印一下status的值，看是否满足循环条件

user: user-4
content: 谢邀。 scanf_s("%d %d", &min, &max); status= (scanf_s("%d %d", &min, &max)==2); while (status)  {  以上，scanf_s调用了两次，这是没有必要的。可以保留第二个。 while语句要求括号内的控制表达式不为0，但是在while语句的循环体内又没有改变status的值，所以并不是没有循环，是它无法停下来。

user: user-5
content: 调试结果的图片发错了，不好意思

user: user-5
content: int number, min, max, count, sum, status; 	sum = 0; 	count = 0; 	printf("Enter lower and upper integer limits:"); 	//scanf_s("%d %d", &min, &max);//------注释掉这一行，下面还有一行代码是输入------- 	status = (scanf_s("%d %d", &min, &max) == 2); 	while (status) { 		for (number = min; min <= number&& number <= max; number++) {//min <= number <= max改为min <= number&& number <= max 			count = number * number; 			sum += count; 		} 		printf("The sums of the squares from %d to %d is %d\n", min*min, max*max, sum);//-----添加换行符号-------- 		printf("Enter next set of limits :"); 		scanf_s("%d %d", &min, &max); 	} 	printf("Done"); VS2015 C++环境跳调试 关于修改min <= number <= max的原因是，在C++中，min <= number <= max并不是像数学中的number大于等于min并且number小于等于max的意思，而是先计算min<=number，这个表达式的结果是true或者false，即1和0，假设是true，则是1，之后再比较1<=max，如果你输入的max是大于等于1的，则min <= number <= max的结果始终是true，就像楼上朋友说的，for是死循环了。所以要把min <= number <= max改成 min <= number&& number <= max

user: user-6
content: 执行不了还好，要是执行了就死循环了 while (status) //循环里没有改变status的处理，一旦进入循环就死循环了  执行不了说明你输入不对 status= (scanf_s("%d %d", &min, &max)==2); 所以status为false 根据的你的代码，你要输入两次数据才行 scanf_s("%d %d", &min, &max); //这里需要输入一次 status= (scanf_s("%d %d", &min, &max)==2); //这里还需要输入一次（为啥不和上面合并？），所以估计这里你忘了输入直接回车，就造成输入不对
user-0 提问: 求大佬帮我看看这段链表代码

回复:
user: user-1
content: 按照2L的思路写的段代码，没测试过，如果代码有问题LZ自己修改吧   struct ListNode* rotateRight(struct ListNode* head, int k){     if (head->next==NULL || head==NULL) return head;     int size = 0, pos = 0;     struct ListNode *temp = head;     struct ListNode *tail = head;     while (tail != NULL) { //算链表长度         size++;         tail = tail->next;     }          k = k%size; //算出移动个数     if (k==0) return head; //如果刚好转一圈，则链表不变          tail = head;     while (tail->next != NULL) {         pos++;         if (pos == size-k) { //如果             head = tail->next; //记录新head             tail->next = NULL; //新head之前的node变成了新的末节点，所以要修改其next为null             tail = head; //tail指向新head继续循环，找到旧链表的末节点             if (head->next == NULL) break; //如果新head刚好是旧链表的末节点则中断循环         }         tail = tail->next;     }     tail->next = temp; //旧链表的末节点指向旧head     return head; }

user: user-1
content: 末尾移动的元素的个数为k%链表长度（因为k==链表长度就刚好转一圈绕回原地） 比如 示例1，k=2，链表长度是5，所以移动k(2)%链表长度(2)=2 示例2，k=4，链表长度是3，所以移动k(4)%链表长度(3)=1
user-0 提问: 大佬们可以帮帮我吗（我是初学者）

回复:
user: user-1
content: int fun(int m) { 	int i, k; 	for (i = m + 1;; i++)  	{ 		for (k = 2; k < i; k++) 		{ 			/**************found**************/ 			if (i % k == 0)//-----如果等于0，说明i不是素数 			{ 				break;//如果i不是素数，则跳出for (k = 2; k < i; k++)，此时k的值小于i 			} 			/**************found**************/ 		} 		if (k >= i)//该行代码用于判断for (k = 2; k < i; k++)循环是怎么结束的（1）当k==i时for循环自然结束（2）当i%k==0时break结束 			//如果是（1）则说明i是素数，如果是（2）则说明i不是素数 		{ 			return(i); 		} 	} } 另外，对于for循环，还是加上大括号的好，即使只有一行执行代码！

user: user-0
content: 引用 1 楼 user-4的回复:其实if(k>=i)改成if(k==i)就可以 因为for(k=2; k<i; k++)里，如果if(i%k==0)一直不满足，k最终=i才会结束循环，所以用if(k==i)就可以了；同时，因为if(i%k==0)一直不满足k才能走到i，所以k走到i就说明没有一个数可以被i整除（如果有，就会break，k就不可能走到i），那就说明i是素数。 好的，差不多懂啦，谢谢老哥

user: user-0
content: 引用 3 楼 青山七海58的回复:论坛上你问语言的问题，懂的人会很乐意回答你，因为一看就知道。这种算法思路的问题要是有人肯花时间帮你看你就偷着乐吧。 哈哈哈哈好哒

user: user-0
content: 引用 4 楼 棉猴的回复:int fun(int m) { 	int i, k; 	for (i = m + 1;; i++)  	{ 		for (k = 2; k < i; k++) 		{ 			/**************found**************/ 			if (i % k == 0)//-----如果等于0，说明i不是素数 			{ 				break;//如果i不是素数，则跳出for (k = 2; k < i; k++)，此时k的值小于i 			} 			/**************found**************/ 		} 		if (k >= i)//该行代码用于判断for (k = 2; k < i; k++)循环是怎么结束的（1）当k==i时for循环自然结束（2）当i%k==0时break结束 			//如果是（1）则说明i是素数，如果是（2）则说明i不是素数 		{ 			return(i); 		} 	} } 另外，对于for循环，还是加上大括号的好，即使只有一行执行代码！ 谢谢老哥的解答

user: user-2
content: 论坛上你问语言的问题，懂的人会很乐意回答你，因为一看就知道。这种算法思路的问题要是有人肯花时间帮你看你就偷着乐吧。

user: user-3
content: int fun(int m) {     int i, k;     for (i = m + 1;; i++) {         for (k = 2; k < i; k++)             /**************found**************/             if (i % k == 0)                 break;         /**************found**************/         if (k == i)             return(i);     } }  void main() {     int n;     n = fun(2);     printf("n=%d\n", n); }   for (k = 2 ; k < i ; k++)  此循环中，k==i时退出，表示i不能被从2到i-1的整数整除。

user: user-4
content: 其实if(k>=i)改成if(k==i)就可以 因为for(k=2; k<i; k++)里，如果if(i%k==0)一直不满足，k最终=i才会结束循环，所以用if(k==i)就可以了；同时，因为if(i%k==0)一直不满足k才能走到i，所以k走到i就说明没有一个数可以被i整除（如果有，就会break，k就不可能走到i），那就说明i是素数。
user-0 提问: unix下动态库和头文件的问题

回复:
user: user-1
content: 1 主程序没引入头文件，程序里是用dlopen，dlsym的方式来调用动态库so的吗？如果是这样，编译时没必要指定so，主程序运行到dlopen时才会加载链接库 2 引入头文件并指定链接库一起编译，这样的方式，主程序在一起动时就加载链接库  你所谓的执行区别就是指这个吧，前者会在用到链接库时才加载so，后者是在主程序一起动就加载链接库so
user-0 提问: 求大佬帮忙分析这份代码的思路

回复:
user: user-1
content: 第N行的第J个数就是第N-1行的第J个和第J-1个的和,自己推才有意思哈

user: user-2
content: 这个for要结合上面的array[i] = 1和下面的array[0] = 1一起来看 首先要知道i层循环的意义，i层循环的结果就是得到第i行的数据，如1L所说 那么来看具体分析 array[i] = 1 这里首先就是设定第i行的最后一个元素 然后for j 循环依次倒推第i行的i-1位置之前的元素 //先理解这个，下面再详细展开 最后再array[0] = 1设定第i行的0位置的元素，这样第i行的数据就生成了  好，再来展开for j 循环 i=0时，array[i]=array[0]=1，for j循环没有满足跳过执行，最后array[0]=1，所以第i=0行的结果就只有1个元素 array[0]=1，即array[]={1}  i=1时，array[i]=array[1]=1，看到了没，相当于在第0行的基础上，在最后的位置最后追加一个元素（也就是多了个元素），即array[0]=1(原来i=0循环时生成)，array[1]=1(本次i循环时生成的)，然后for j没满足跳过执行，最后array[0]=1，所以第i=1行的结果就是有2个元素，即array[]={1,1}  i=2时，array[i]=array[2]=1，看到了没，又在第1行的基础上在末尾多追加了一个元素array[2]=1，即此时 array[]={1,1,1}，然后进入for j循环，倒推array[2]位置之前的元素，首先看j=i-1，即array[i-1]=array[1]的情况，我们用图的方式展示 i=1时，array[]={1,1} //这是上一次i循环的结果，也就是第1行 i=2时，array[]={1,1,1} //这是本次i循环，也就是第2行，array[j]=array[i-1]是不是相当于第1行的最后一个元素（蓝上）？那么array[j-1]是不是相当于第1行的倒数第二个元素（绿上）？所以array[j](蓝上)+array[j-1](绿上)=array[j](蓝下)=1+1=2 所以就可以倒推出第2行的j位置的元素，依次继续往前类推，直到for j循环结束，最后再array[0]=1，就是把第2行的首元素设为0，所以最终结果，第i=2行有3个元素，即array={1,2,1}  i=3时，先array[i]=array[3]=1在第2行的基础上在最后追加一个元素，即如下图 i=2时，array[]={1,2,1} i=3时，array[]={1,2,1,1} 然后for j 循环 ，第1次j循环 i=2时，array[]={1,2,1} i=3时，array[]={1,2,1,1} 得到 i=2时，array[]={1,2,1} i=3时，array[]={1,2,3,1} 第2次for j循环 i=2时，array[]={1,2,1} i=3时，array[]={1,2,3,1} 得到 i=2时，array[]={1,2,1} i=3时，array[]={1,3,3,1} 然后j循环退出，再array[0]=1，最终第i=3行有4个元素，即array[]={1,3,3,1}  所以for j不是公式，相当于把上一行（i-1行）的结果依次倒推，两两元素相加的结果最为本行（i行）的第 j 个元素

user: user-0
content: 为什么刚好得到不同阶的数？

user: user-3
content: 这个for循环，每循环一次，得到不同阶数的值，例如第一次循环得到[1，1],第二次循环得到[1,2,1]，第三次循环得到[1,3,3,1]

user: user-0
content: 引用 3 楼 qybao 的回复：这个for要结合上面的array[i] = 1和下面的array[0] = 1一起来看 首先要知道i层循环的意义，i层循环的结果就是得到第i行的数据，如1L所说 那么来看具体分析 array[i] = 1 这里首先就是设定第i行的最后一个元素 然后for j 循环依次倒推第i行的i-1位置之前的元素 //先理解这个，下面再详细展开 最后再array[0] = 1设定第i行的0位置的元素，这样第i行的数据就生成了  好，再来展开for j 循环 i=0时，array[i]=array[0]=1，for j循环没有满足跳过执行，最后array[0]=1，所以第i=0行的结果就只有1个元素 array[0]=1，即array[]={1}  i=1时，array[i]=array[1]=1，看到了没，相当于在第0行的基础上，在最后的位置最后追加一个元素（也就是多了个元素），即array[0]=1(原来i=0循环时生成)，array[1]=1(本次i循环时生成的)，然后for j没满足跳过执行，最后array[0]=1，所以第i=1行的结果就是有2个元素，即array[]={1,1}  i=2时，array[i]=array[2]=1，看到了没，又在第1行的基础上在末尾多追加了一个元素array[2]=1，即此时 array[]={1,1,1}，然后进入for j循环，倒推array[2]位置之前的元素，首先看j=i-1，即array[i-1]=array[1]的情况，我们用图的方式展示 i=1时，array[]={1,1} //这是上一次i循环的结果，也就是第1行 i=2时，array[]={1,1,1} //这是本次i循环，也就是第2行，array[j]=array[i-1]是不是相当于第1行的最后一个元素（蓝上）？那么array[j-1]是不是相当于第1行的倒数第二个元素（绿上）？所以array[j](蓝上)+array[j-1](绿上)=array[j](蓝下)=1+1=2 所以就可以倒推出第2行的j位置的元素，依次继续往前类推，直到for j循环结束，最后再array[0]=1，就是把第2行的首元素设为0，所以最终结果，第i=2行有3个元素，即array={1,2,1}  i=3时，先array[i]=array[3]=1在第2行的基础上在最后追加一个元素，即如下图 i=2时，array[]={1,2,1} i=3时，array[]={1,2,1,1} 然后for j 循环 ，第1次j循环 i=2时，array[]={1,2,1} i=3时，array[]={1,2,1,1} 得到 i=2时，array[]={1,2,1} i=3时，array[]={1,2,3,1} 第2次for j循环 i=2时，array[]={1,2,1} i=3时，array[]={1,2,3,1} 得到 i=2时，array[]={1,2,1} i=3时，array[]={1,3,3,1} 然后j循环退出，再array[0]=1，最终第i=3行有4个元素，即array[]={1,3,3,1}  所以for j不是公式，相当于把上一行（i-1行）的结果依次倒推，两两元素相加的结果最为本行（i行）的第 j 个元素qybao大佬，永远滴神！
user-0 提问: 请各位大佬帮忙解决一个指针问题，需要输出long long数据每两个字节的值

回复:
user: user-0
content: 感谢，看来还是没有摸透 引用 1 楼 自信男孩 的回复:改一下循环条件不就可以了吗？  for (i = n-1; i >= 0; i--) {     printf("%#x\t", *(p+i)); }

user: user-1
content: 改一下循环条件不就可以了吗？  for (i = n-1; i >= 0; i--) {     printf("%#x\t", *(p+i)); }
user-0 提问: scanf输入char*提示段错误linux

回复:
user: user-1
content: struct students { char *name; char *member; char *state; };  如果对指针内存分配不熟悉，还是建议用 char name[10] 这种方式

user: user-2
content: 都是野指针惹的祸，s是野指针，s->name也是野指针。所以结果是未定义的，出现段错误也是可能的。  #include<stdio.h> #include<stdlib.h> #define datesize 64  struct students {     char *name;     char *member;     char *state; };  void appendmessage() {     struct students *s;      s = (struct students *)malloc(sizeof(struct students));     if (!s)         return;      printf("学生姓名：");     //标记1     char *name = (char *)malloc(sizeof(char) * 32);     if (!name)         return;     scanf("%s",name);     //标记1 end     //标记2     s->name = (char *)malloc(sizeof(char) * 32);     if (!s->name)         return;     scanf("%s",(*s).name);     //标记2 end     printf("学生编号：");     s->member = (char *)malloc(sizeof(char) * 32);     if (!s->member)         return;     scanf("%s",(*s).member);     printf("学生状态：");     s->state = (char *)malloc(sizeof(char) * 32);     if (!s->state)         return;     scanf("%s",(*s).state);     printf("----写入文件----");     FILE *fp = fopen("studate.txt","ab");     //...... } 供参考～  上面的改法只是一种，也可以用数组或普通变量～
user-0 提问: c语言关于float问题

回复:
user: user-1
content: 请参考《C++浮点型变量的存储方式》 希望能够帮到您！

user: user-2
content: float是-3.4E+38到3.4E+38，没有超。100.0f的f表示这个是double，乘了之后会升级成double，就像你char乘int会升级成int。

user: user-3
content: float 指数-128——127
user-0 提问: c语言小白求助

回复:
user: user-1
content: value是float的，右边的值是double的

user: user-2
content: waitKey (0)?

user: user-3
content: 是不是那个“请按任意键继续”的黑色窗口啊？要是的话你需要添加头文件“stdlib.h”，然后在return 0； 的前面添加  system("pause");  这样一句就能了，这条语句的意思是 暂停程序，等待输入

user: user-4
content: 没看到enter界面，跟enter界面好像没关系吧。

user: user-4
content: 编译没问题吧，另外，enter界面是什么呢？

user: user-5
content: 不明白enter界面是啥，代码看上云是没错的
user-0 提问: sourceinsight 两个文件中定义了同名的结构体变量

回复:
user: user-1
content: 可以考虑改一下头文件，把两个同名结构体如果元素完全一样，可以用一个声明，如果结构体成员不一样，建议改一下其中一个结构体名字

user: user-2
content: 有一个概念叫命名空间namespace，就是为了解决这样的问题。 所以你可以把两个结构体放在两个不同的命名空间，引用时加上命名空间来区分即可 比如 namespace A { typedef struct x {     int a; } X; }  namespace B { typedef struct x {     int a;     int b; } X; }  引用时 A::X a; //引用A的结构体X B::X b; //引用B的结构体X
user-0 提问: 假定int a=2，b=3；，表达式(b/a*2.0>2.0*a/b)+(++a-b--)的值是？  为什么答案是0而不是1呢？

回复:
user: user-1
content: 这种题目不需要深究，写代码千万别这样写，看的人要累死 a++ 、a-- 这种，表达式尽量只包含a一次

user: user-2
content: 分两部分吧，第一个部分是+前。 (b/a*2.0>2.0*a/b)；要看结果是否为真还是假。  通过计算可知：2.0 > 4.0/3很明显为假。即0  +后： (++a-b--)即++a为3. b--先算(b--)即为3. 所以3-3 = 0； 最后是0+0=0

user: user-2
content: 引用 3 楼 朕守山河 的回复:要明白一般的编译器实际上是从右向左进行计算的 也就是先计算（++a-b--），计算这部分的时候，++a为3，-b--这个时候也为3，所以为0，算完这一步后，a的值为3，b的值变成2 那么(b/a*2.0>2.0*a/b)变成（2/3*2>2*3/2)为假，所以为0  最后0+0为0 建议测试一下～

user: user-2
content: 这个我考虑的是从左向右计算；因此结果应该是1+0=1  #include <stdio.h>  int main(void) {     int a=2,b=3;      printf("%d\n", (b/a*2.0>2.0*a/b)+(++a-b--));      return 0; } 在linux下测试结果是1.

user: user-2
content: 引用 7 楼 朕守山河 的回复:[quote=引用 5 楼 自信男孩 的回复:][quote=引用 4 楼 朕守山河 的回复:][quote=引用 1 楼 自信男孩 的回复:]分两部分吧，第一个部分是+前。 (b/a*2.0>2.0*a/b)；要看结果是否为真还是假。  通过计算可知：2.0 > 4.0/3很明显为假。即0  +后： (++a-b--)即++a为3. b--先算(b--)即为3. 所以3-3 = 0； 最后是0+0=0 2.0 > 4.0/3很明显为假。即0？？？你这个是怎么算出来的？ 这个问题是因为编译器原因[/quote] 就是true和false的值。 [/quote] 兄弟。。。麻烦你看明白我的意思了再回复哈 2>4/3结果为假？[/quote] 理解错了。那也不是2 > 4/3哦，应该是2.00000 > 4.00000/3；2和4是double类型哦。

user: user-3
content: 引用 5 楼 自信男孩 的回复:[quote=引用 4 楼 朕守山河 的回复:][quote=引用 1 楼 自信男孩 的回复:]分两部分吧，第一个部分是+前。 (b/a*2.0>2.0*a/b)；要看结果是否为真还是假。  通过计算可知：2.0 > 4.0/3很明显为假。即0  +后： (++a-b--)即++a为3. b--先算(b--)即为3. 所以3-3 = 0； 最后是0+0=0 2.0 > 4.0/3很明显为假。即0？？？你这个是怎么算出来的？ 这个问题是因为编译器原因[/quote] 就是true和false的值。 [/quote] 兄弟。。。麻烦你看明白我的意思了再回复哈 2>4/3结果为假？

user: user-3
content: 兄弟 你这个....麻烦看清楚意思了，2>4/3结果是假？

user: user-2
content: 引用 4 楼 朕守山河 的回复:[quote=引用 1 楼 自信男孩 的回复:]分两部分吧，第一个部分是+前。 (b/a*2.0>2.0*a/b)；要看结果是否为真还是假。  通过计算可知：2.0 > 4.0/3很明显为假。即0  +后： (++a-b--)即++a为3. b--先算(b--)即为3. 所以3-3 = 0； 最后是0+0=0 2.0 > 4.0/3很明显为假。即0？？？你这个是怎么算出来的？ 这个问题是因为编译器原因[/quote] 就是true和false的值。

user: user-3
content: 引用 1 楼 自信男孩 的回复:分两部分吧，第一个部分是+前。 (b/a*2.0>2.0*a/b)；要看结果是否为真还是假。  通过计算可知：2.0 > 4.0/3很明显为假。即0  +后： (++a-b--)即++a为3. b--先算(b--)即为3. 所以3-3 = 0； 最后是0+0=0 2.0 > 4.0/3很明显为假。即0？？？你这个是怎么算出来的？ 这个问题是因为编译器原因

user: user-3
content: 要明白一般的编译器实际上是从右向左进行计算的 也就是先计算（++a-b--），计算这部分的时候，++a为3，-b--这个时候也为3，所以为0，算完这一步后，a的值为3，b的值变成2 那么(b/a*2.0>2.0*a/b)变成（2/3*2>2*3/2)为假，所以为0  最后0+0为0

user: user-4
content: 这个表达式是典型的“使用变量的同时、又改变这个变量”。这种问题，建议你不要纠结，因为不同的編译器给出的结果是不一样的。 先抛开你的问题，看下面的例子： int a = 1; int b = a + a++; b的结果可能是2，也可能是3。 原因在于，所有的操作符(operator)，C的标准规定了优先级和结合律，但大多数没有规定计算的顺序(the order of evaluation)。 优先级和结合侓只是告诉你哪些操作符与哪些操作数绑定在一起，并且习惯上我们会用括号括起来，所以a + a++相当于 a + (a++)而不是(a+a)++； 但是即使是a + (a++)，编译器可以先考虑计算左边的a，也可以先考虑计算右边的a++，这个顺序是标准没有规定的。  所以，你的表达式(A) + (B)，先处理A的话是一个结果，先处理B的话是另外一个结果。 都对。
user-0 提问: 在自定义数组中如何将main函数中的数组和其他值比较？

回复:
user: user-0
content: 确实多了单引号。。

user: user-1
content: 所以可以使用对数组名进行位移的方式遍历数组中的所有元素。 请参考《C++中函数的数组形参》 《C++数组地址偏移》 希望能够帮到您！

user: user-2
content: 你自己不是搞定了吗？只不过while('n' != arr[i]) 可能期待的是 while(n != arr[I]) //没有引号，有引号是字符，没有引号才是你传进来的参数。 用arr[i]就可以访问数组的其它元素，所以估计是你写错了'n'，多了引号
user-0 提问: 关于C语言的语法 *p++ *= *q++;

回复:
user: user-1
content: a = *p++ * *q++等价于  a = *p  乘以 *q p = p+1; q = q+1;  如果是代码：  int[] A = int[10]; int[] B = int[20]; int *p = A//数组 int *q = B;//数组 int a; a = *p++ * *q++;  相当于  a = A[0]*B[0]; q = &A[1]; p = &B[1];

user: user-2
content: *p++ *= *q++; 展开应该是*p++ =(*q++) * (*p++);

user: user-1
content: a = *p++ * *q+++我不信他是对的

user: user-0
content: 引用 5 楼 千梦一生 的回复:a = *p++ * *q+++我不信他是对的 手抖多打了个+

user: user-3
content: *p++ *= *q++; 这样写，不如写成  p[i] *= q[i];看着舒服。 既然用了i建议用p[i], q[i];

user: user-1
content: 如此阴间的代码，我看着挺难受。

user: user-0
content: 引用 3 楼 自信男孩 的回复:*p++ *= *q++; 这样写，不如写成  p[i] *= q[i];看着舒服。 既然用了i建议用p[i], q[i]; 起初是写成这样的，但我这不是听说 *p++ 比下标访问更快吗， 就改成这样了。。。  发现挺麻烦，因为要保留一个指向头的指针，就得为一个数组准备2个指针，一个用来移动，一个始终指向头部  而且有的写法不易读，比如:  a = *p++ * *q+++ 这是啥，但它是正确的

user: user-0
content: 是可以的，是我的错。没有创建临时指针，把唯一指针移到末尾了
user-0 提问: 线性表的顺序存储结构

回复:
user: user-1
content: 说到底还是传值和传地址的问题

user: user-2
content: 楼主的代码可以贴全一些。  从数据结构和参数类型可知，Creat函数的第一个参数应该传&lin才可以，当然函数定义里第一个参数应该是Line *L。 否则不能从Creat函数里得到你想要的数据。

user: user-3
content: 报什么错了？Creat和Print函数怎么实现的？

user: user-4
content: 就目前的代码看，应该没啥错误，结构体名也是可以做参数传入的，只是用的比较少而已
user-0 提问: 怎么用C语言代码表示10负n次方

回复:
user: user-1
content: 整个n是需要有限制的吧，不成超过double或long double的小数范围，最好是能在有效的取值范围

user: user-2
content: 啥意思？ 比如 double a=1e-9 表示10的-9次方
user-0 提问: 求大佬帮我看看这道题目的详细思路和代码问题！

回复:
user: user-1
content: 很多都可以百度

user: user-2
content: lower_bound 就是二分法找q的元素的位置（适用于排好序的数组） 比如 a[]={1，2，3} 数组找q=3，l是左位置0，r是右位置2，中心位置是mid=(l+r)/2 = 1，a[1]=2<q=3，所以左位置+1即l=1；继续查找，中心位置mid=(l+r)/2=2，a[2]=2<q=3，所以左位置+1即l=2；此时不满足while循环，退出，所以l=2就是结果，即a[2]=3就是就是找到的结果 这个函数感觉有点缺陷，最后应该还要判断a[l]是否这的和q相等  INT_MAX是整形的最大值，因为要找最小长度，所以初始化最小值为整形最大值。就好像从数组a[]={3,2,1}找最小值，这样初始化min=100（相当于INT_MAX），这样一个for循环就能找到最小，即 int min=100; //100和INT_MAX一个意思，INT_MAX表示初始值就是整形最大的，这里的100是因为我们知道数组里没有大于100的元素 for(int k=0; k<3; k++)      if (a[k] < min) min=a[k]; //如果min不是最大，假设所以元素到大于min，那么就找不到min了，比如所以元素大于100，那最后min就找不到  sums数组是构建一个原数组前缀元素的和的数组，也就是原来数组的前i个元素的和就是sums数组的第i位置的元素。 nums = {1, 2, 3, 4} sums = {0, 1, 3, 6, 10} //看到了吗，sums数组会多出一个元素，所以要 numsSize + 1。nums[0]=1之前是0=sums[0]，nums[1]=2之前是1=sums[1]，nums[2]=3之前是1+2=3=sums[2]，nums[3]=4之前是1+2+3=6=sums[3]，4之后（相当于所有元素的和）是1+2+3+4=10=sums[4] sums最终是排好序的，所以二分法适用   //这个for循环想干嘛？ 这个for循环就是要求出sums的每个元素，上面说了，sums是nums的前缀和的数组，所以要for nums循环来一个一个加nums的前缀元素算出sums  //这个for循环的内容能解释一下吗？ 这个每次用sums的前一个元素加上s的值最为查找对象，然后用二分法来查找 比如 第一次用sums[0]+s作为目标值来进行二分法查找，第二次用sums[1]+s作为目标值来进行二分法查找，依次类推。然后每次二分法找到的结果判断是不是最小，如果是最小，则交换ans的值  思路： 其实就是要搞明白target=s+sums[i-1]的意义，上面说了，sums是nums的前缀的和，那么s+sums[i-1]是不是相当于s+nums[i-1]的前缀的和，nums[i-1]的前缀，是不是就是nums[0]到nums[i-1]的子串，所以相当于s+（nums[0]到nums[i-1]的子串的和）；搞明白这个意义就可以了，二分法只是快速查找而已，没什么特别意义。所以如果用二分法找到target的位置bound，那就说明从nums[i]到nums[bound]的和就是s（因为target-（nums[0]到nums[i-1]子串的和）=s），这样，从每次查找到的bound中选出最小的即可。
user-0 提问: C里手动分配内存必须手动回收吗？

回复:
user: user-1
content: 要看你是在哪里申请的空间，如果是在栈上申请的，比如alloca就是在栈上分配的动态，那么不需要手动回收。 如果实在堆上申请的空间，那是需要手动释放的，不过整个程序退出时，即使没有手动释放，系统也会帮忙回收的。

user: user-2
content: 1楼标准答案.

user: user-3
content: 必须。否则只有在程序退出的时候，系统才回收全部资源。 C语言没有java及C#之类的智能

user: user-4
content: 不会被自动回收

user: user-5
content: 在堆上分配的内存（也就是用malloc、new这样的语句分配的）不释放会一直存在，栈上分配的函数退出会自动回收。
user-0 提问: 数据结构中的链队列的入队操作

回复:
user: user-1
content: s->next= NULL;可以理解为初始化，s是链接到队列的末尾，队列的末尾的next不就是执行NULL吗？ 楼主看一下队列遍历里可以通过判断是否为NULL来确定是否到了末尾。  新的节点进来，就会把上一个s->next的NULL给覆盖了，就是用新的s覆盖上一个s->next

user: user-2
content: 新的结点连接到上一个结点的next域上，这个新结点的next又指向NULL。
user-0 提问: 学生成绩管理系统（c语言）

回复:
user: user-1
content: 有什么问题呢？还是单纯的代码展示？

user: user-2
content: 楼主的代码写的不全呢，比如： struct Class *banjixinxi(struct Class *head) {      int j;     for(j=1;j<=5;j++)     {         stuHead = chengjishuyu(j);      }     return head; } 这里的head什么也没做，直接返回，所以程序里除了一些编译错误，就是代码还没写完，即使没有这些错误也不能运行。建议楼主写完了再问吧
user-0 提问: VS2019开发C语言的问题

回复:
user: user-1
content: 请参考《VS2015中使用scanf()不报错的设置方法》 希望能够帮到您！

user: user-2
content: 使用scanf_s就好了，

user: user-0
content: 感谢大佬们！我懂了

user: user-3
content: 其实错误提示已经很明确的给出解决方法了

user: user-4
content: VS中设置#define _CRT_SECURE_NO_WARNINGS(解决C4996错误) 1.我们在编译老的用C语言的开源项目如lua源包的时候，可能因为一些老的.c文件使用了strcpy,scanf等不安全的函数，而报警告和错误，而导致无法编译通过。 2.此时我们有两种解决方案： a.在指定的源文件的开头定义：#define _CRT_SECURE_NO_WARNINGS  （只会在该文件里起作用） b.在项目属性里设置，这会在整个项目里生效，依次选择：属性->配置属性->C/C++ ->预处理器->预处理器定义->编辑 最下面加上一行：_CRT_SECURE_NO_WARNINGS   （注意不需要#define） 这个其实网上就能搜到答案

user: user-5
content: #define _CRT_SECURE_NO_WARNINGS #pragma warning(disable:4996)

user: user-6
content: 看错误信息是楼主的编译器不支持scanf需要用scanf_s（vs里支持的）。  把scanf改成 scanf_s("%d", &x); 试试～

user: user-7
content: 引用 4 楼 千梦一生 的回复:#define _CRT_SECURE_NO_WARNINGS #pragma warning(disable:4996) 如果用#define这一句一定要放在程序的第一行

user: user-8
content: 为啥不看报错信息，用啥instead

user: user-9
content: 去定义 _CRT_SECURE_NO xxx 就可以无视这个警告了。 因为这个函数不安全，已经早就抛弃了
user-0 提问: 关于VC里好多头文件不能用的问题，本人新手，请大神们务必回答一下！！！谢谢

回复:
user: user-1
content: 图形用户界面（GUI）编程可以学习C++ Builder，架构先进（和C#一样拖控件），入门比较容易。  　　C++ Builder是真正的可视化的开发工具。C++ Builder可以用鼠标拖拉控件加上设置属性轻松的“设计”出一个程序的图形用户界面，利用可视的组件/控件像“搭积木”一样，以“所见即所得”的方式搭建应用程序的界面，这也是C++ Builder这个名字中Builder的概念。这样，只需要用C++语言编写业务逻辑代码，类似于DOS下文本界面编程，只要专注于实现业务逻辑功能就可以了，代码非常简洁。数据的输入和表现，都在图形用户界面，非常直观、易用。这就是RAD开发（Rapid Application Development，快速应用程序开发）。  书籍推荐： 《C++Builder 6程序设计教程（第二版）》 （陆卫忠，刘文亮　等编著 /2011-04-01 /科学出版社）（当当网） 《C++Builder 6编程实例精解》（赵明现），PDF，是数字版的，非扫描版的，里面还有一个俄罗斯方块游戏的完整实现。 《精彩C++Builder 6程序设计》（台湾 吴逸贤），里面有10几个简单小游戏的实现，可以自己看懂以后再重写，才是自己掌握的。 《C++ Builder 5高级编程实例精解》（刘滨 编著）都是较大的实用的程序。  C++ Builder 6.0几个示例程序项目源代码下载：       C++ Builder第一个程序（模拟聊天室）v1.11 C++ Builder模拟数字双时钟示例（未完成）v0.2.1 C++ Builder纸牌游戏Demo v0.03 C++ Builder不规则图像透明贴图（位图的透明显示）三种方法及简单动画v1.3 C++ Builder写的《ZEC 四则运算练习程序》 海底海星情景v0.9.2 C++ Builder简单电话簿Demo例子v1.11

user: user-1
content: 那些是DOS平台游戏了，非要看看代码运行效果的话，可以用DOSBox运行Turbo C 2.0或Borland C++ 3.1（支持鼠标）来编译，Windows 2000以后无法直接运行。

user: user-2
content: <dos.h>、<bios.h>、<graphics.h>是用于DOS软件开发的，VC++6已经不支持DOS/win16开发了，如果需要的话，可以使用microsoft c/c++ 7.0或者VC++ 1.x

user: user-3
content: VC++6.0挺好的，对于缺少的头文件，可以从网上下载以后，再拷贝到VC++6.0的库文件夹下就可以了

user: user-0
content: 引用 10 楼 ooolinux的回复:那些是DOS平台游戏了，非要看看代码运行效果的话，可以用DOSBox运行Turbo C 2.0或Borland C++ 3.1（支持鼠标）来编译，Windows 2000以后无法直接运行。 非常感谢您可以告诉我这些

user: user-0
content: 十分感谢各位积极的回复！

user: user-0
content: 非常感谢！这对我很有用！

user: user-4
content: 要看创建的什么类型的项目

user: user-0
content: 引用 3 楼 smwhotjay的回复: 因为非vc6标准库了。 要自己手动指定安装 我现在贼头疼，解决不掉完成不了后面的任务

user: user-0
content: 引用 3 楼 smwhotjay的回复: 因为非vc6标准库了。 要自己手动指定安装 咳咳，那您可以告诉我怎么安装解决吗？毕竟这么多头文件，我也不知道该安装什么？安装在哪里？

user: user-0
content: 引用 2 楼 qybao的回复:查看一下这些头文件在include路径下吗？如果不在，你要用-I参数指定include路径来编译。 emmmm,我补充一下，主要是我学到系统相关的函数时发现的这些头文件，写一些基本的例题还是没什么问题的，就是目前就发现主要和系统相关的不行

user: user-5
content: 因为非vc6标准库了。 要自己手动指定安装

user: user-6
content: 查看一下这些头文件在include路径下吗？如果不在，你要用-I参数指定include路径来编译。

user: user-7
content: 应该是没有加在相应的库吧，
user-0 提问: 求大佬帮忙看看我这段代码错在哪？

回复:
user: user-1
content: if (j=-1 || haystack[i]==needle[j])； 你这行写错了吧？j = -1

user: user-2
content: int *getNext(char *p, int *next) {     int k=-1, j=0;     next[0] = -1;     while (j<strlen(p))     {         //if (k=-1 || p[k]==p[j])         if (k==-1 || p[k]==p[j])         {             next[++j] = ++k;         }         else         {             k = next[k];         }     }     return next; }  int strStr(char * haystack, char * needle){     if (needle==NULL) return 0;      int x = strlen(needle);     int i=0, j=0;     int *next = (int *)malloc(x*sizeof(int));      getNext(needle, next);      while (i<strlen(haystack) && j<strlen(needle))     {         //if (j=-1 || haystack[i]==needle[j])         if (j==-1 || haystack[i]==needle[j])         {             i++;             j++;         }         else         {             j = next[j];         }     }     if (j==strlen(needle))      return i-j;     else      return -1; } 供参考～  有这两处的问题～

user: user-0
content: 我全部搞懂了，谢谢各位大佬们

user: user-0
content: int *getNext(char *needle, int *next) {     int k=-1, j=0, n=strlen(needle);     next[0] = -1;     while (j<n)     {         if (k==-1 || needle[k]==needle[j])         {             next[++j] = ++k;         }         else         {             k = next[k];         }     }     return next; }  int strStr(char * haystack, char * needle){     int len1=strlen(haystack); 	int len2=strlen(needle);     if (len2==0) return 0;     int i=0, j=0;     int next[strlen(needle)+1];          //这里为什么要加1？我看其他KMP算法这里并没有加1     getNext(needle, next);     while (i<len1 && j<len2)     {         if (j==-1 || haystack[i]==needle[j])         {             i++;             j++;         }         else         {             j = next[j];         }     }     if (j>=len2)      return i-j;     else      return -1; }  大佬们，我已经写出正确的代码了，但是我不知道上面的next数组后面为什么要加1？

user: user-3
content: if (needle==NULL) return 0 改成 if (needle==NULL) return -1 并追加 if (strlen(needle)==0) return 0  空字符串不是NULL，是””

user: user-0
content: 错误一： if (needle==NULL) return 0 改成 if (needle==NULL) return -1 并追加 if (strlen(needle)==0) return 0  错误二：  //if (k=-1 || p[k]==p[j])     if (k==-1 || p[k]==p[j])  错误三：  //if (j=-1 || haystack[i]==needle[j])     if (j==-1 || haystack[i]==needle[j])  改完之后还是不行哭了，究竟还错在哪里
user-0 提问: 关于KMP算法的问题

回复:
user: user-0
content: 谢谢user-1大佬，你已经有效地回答了我很多问题了，非常感谢，看来我以后问问题还是要贴出具体代码才能让人更好地回答

user: user-1
content: 为什么next[0]=-1?这只是为了方便判断j回退到哪个位置，因为如果一直不匹配，j最多会回退到next[0]重新开始匹配，为了能判断j回退到next[0]，就要给next[0]赋一个特定值，一般这个特定值采用-1，因为后面的next不可能会出现负数，所以用个负数能方便判断j回退到了next[0]  写成next[1]=0，这个就看程序逻辑怎么控制了，因为用next[0]=-1，i=1，j=-1也能算出next[1]=0  j为什么等于-1？这是为了错开匹配字符串。next数组是用匹配字符串自己和自己错开1位来求的，比如 -abcd //原字符串（没有-字符，-只是为了对齐方便说明比较），i在第一个a位置，即0位置 xabcd //错开位置字符串（没有x字符，x字符只是为了方便说明开头错开一位），j在x位置 错开位置字符串的x位置相对于原字符串来说就是-1（因为a是0位置，a的左边x就是-1）  if j==-1 是为了判断匹配字符串是不是最开始匹配。p[i]==p[j]表示原字符串和错位位置字符串的该位置的字符相同。if的意思就是满足上述条件则算出next，并继续比较下一个字符 比如 aabb //原字符串，i在第一个a位置，即0位置 xaabb //错开位置字符串，j在x，即-1位置 第一轮循环，j==-1（最开始比较），所以i++，j++，算得next[1]=0；然后下一轮循环，原字符串p[i]即p[1]=a，错开位置字符串p[j]即p[0]=a，所以满足p[i]==p[j]，则继续比较下一个字符i++，j++，同时算的next[2]=1（即找到1个字符匹配，也就是匹配长度为1）；然后继续下一轮循环，原字符串p[i]即p[2]=b，错开位置字符串p[j]即p[1]=a，p[i]!=p[j]，进入else，重新回退错开字符串的位置j=next[j]=next[1]=0，所以变成 aabb //原字符串，此时i在第一个b位置 -xaabb //错开位置字符串j在a，即0位置 然后继续下一轮比较，原字符串p[i]即p[2]=b，错开位置字符串p[j]即p[0]=a，p[i]!=p[j]，进入else，j继续回退，即j=next[j]=next[0]=-1（第一个问题next[0]=1的意义就在这里，j回退到了最开始位置），所以变成 aabb //原字符串，此时i在第一个b位置 --xaabb //错开位置字符串j在x，即-1位置 然后继续下一轮循环，因为j==-1，所以直接比较下一个字符，所以i++，j++，算得next[3]=0 依次类推，最终算出全部的next  为什么next[j]刚好等于j？因为满足if，说明有j个字符匹配，所以匹配长度就是j（j==-1说明刚开始，有0个字符匹配）  为什么回溯到next[j]？因为next的意义就是保存了上次匹配的长度，所以如果发现不匹配，错开位置字符串就在跳过上一次匹配长度的基础上重新开始匹配，具体参见上面的分析。  if和else又看不懂了？其实kmp和getnext的if和else意思差不多，kmp是在t里找p字串，所以就是比较t和p的匹配度；而getnext是p和错开位置的p的匹配度比较，目的为了算出next；所以kmp和getnext的if和else逻辑一样的，都是找匹配度，只是前者是长串跟子串比，后者是自己跟错开位置的自己比  这个if麻烦也解释一下？这个if说明如果j能走到子串p的最后，则t就包含p，所以p在t的索引就是i-j；如果这个if不满足，说明p不能匹配完，所以t不包含p，则返回-1
user-0 提问: 关于C语言数组和指针有个问题

回复:
user: user-0
content: 引用 10 楼 火花20180731的回复:char* str = "abcdefg";  "abcdefg"是字面值常量，存储在常量区某一块，这里是把"abcdefg"在常量区的地址存到str指针中 char a[10]; 声明一个容量为10的数组，a是个局部变量，会在栈区中为a分配一块10字节的内存 copy通过str中存储的地址进入常量区内存把“abcdefg”拷贝到数组的内存中 char* a; 声明一个指针，指针所指内存用char格式读取。指针a和str都有自己的内存，都用来备份地址，不能用来存储字符串。 a没有初始化，所以a本身的内存存的是个垃圾值，也就是没有明确指向的指针是野指针，读写野指针的“目标内存”会引发段错误！造成程序崩溃。 谢谢啦！辛苦了，明白了

user: user-0
content: 引用 7 楼 千梦一生的回复:字典不是有目录吗，查字典找某个字的具体读音、释义的时候，先得找到目录那一条【那一行】，根据后边的书页，翻过去再能看对吧。 那一行就如同指针。你建立了一个那样的条目，但后面的书页【对应指针指向的地址】是未知的，可能是任何地方。意图通过该随机的地址去访问数据。这样的行为自然不被许可。 谢谢哥，明白了

user: user-0
content: 引用 11 楼 skzeng@ros的回复:觉得有帮助，又不结贴，你几个意思 这个我不知道手机版的在哪里结贴

user: user-1
content: 觉得有帮助，又不结贴，你几个意思

user: user-2
content: char* str = "abcdefg";  "abcdefg"是字面值常量，存储在常量区某一块，这里是把"abcdefg"在常量区的地址存到str指针中 char a[10]; 声明一个容量为10的数组，a是个局部变量，会在栈区中为a分配一块10字节的内存 copy通过str中存储的地址进入常量区内存把“abcdefg”拷贝到数组的内存中 char* a; 声明一个指针，指针所指内存用char格式读取。指针a和str都有自己的内存，都用来备份地址，不能用来存储字符串。 a没有初始化，所以a本身的内存存的是个垃圾值，也就是没有明确指向的指针是野指针，读写野指针的“目标内存”会引发段错误！造成程序崩溃。

user: user-3
content: 你的*a是一个野指针，它没有指向一块具体的内存，你对它进行copy操作就是对他指向的内存操作，但是它的指向未知，有可能是一块不允许访问的内存，就会报段错误，可以使用malloc：char *a = malloc(16);然后就可以了。 你定义一个数组a[]的话系统会自动在栈里面给它分配一块内存，是可以进行访问的。

user: user-4
content: char *a;是野指针，即指向的位置是随机的，a指向的内存区域不一定是可以写的，因此如果指向不可写，那么copy函数就是写，就会出现异常，不如段错误。  用数组，那么定义的空间是在栈上，栈上的空间是可以读写的。

user: user-5
content: 字典不是有目录吗，查字典找某个字的具体读音、释义的时候，先得找到目录那一条【那一行】，根据后边的书页，翻过去再能看对吧。 那一行就如同指针。你建立了一个那样的条目，但后面的书页【对应指针指向的地址】是未知的，可能是任何地方。意图通过该随机的地址去访问数据。这样的行为自然不被许可。

user: user-1
content: 很开心能帮到你，望尽快结贴～

user: user-0
content: 懂了。谢谢哥。我的那个原来是没有给指针分配空间

user: user-6
content: 可以用malloc给char *a分配一块内存，这样就可以使用了

user: user-1
content: 正确答案：如图是用数组可以输出的，而用指针也是可以输出的。不过题主的代码有问题。 问题所在：数组char a[10],默认定义为具有10个元素的一维数组。而指针的使用则必须指向一块内存地址，因此需要有定义，你可以自己分配一块新的地址，也可以指向已有量。因为变量就是内存空间里的值，而内存空间的名字就是地址。指针则指向地址。望采纳~

user: user-0
content: 不能是我那样 char *a吗

user: user-7
content: 用指针你要先初始化指针，让它指向一块有效的内存 比如 char *a = (char*)malloc(sizeof(char)*32);//a指向申请的内存 copy(a, str); free(a); //如果是自己申请内存，用完之后要自己释放内存
user-0 提问:  空洞文件的overflow问题。

回复:
user: user-1
content: 4*1024*1024*1024 这是4G的空间，建议减少到4*1024试试，应该就不会有溢出的提示了。

user: user-2
content: Vbox是实模式吧，不能访问那么多内存。
user-0 提问: 请问大家在Leetcode上为什么会显示 heap-buffer-overflow，实在找不出问题了

回复:
user: user-1
content: 第一个break如果在第一次nums[0]不满足，就跳出循环了，还能继续后面的？

user: user-2
content: int *res=malloc(sizeof(int)*2 ); //2个大小够么？ if(!ina(i,res,m)&&!ina(j,res,m)) //这之前res 缓冲区都没有赋值/初始化 是否调用的参数有误？

user: user-3
content: 同问，在做3sums时出现同样的问题

user: user-4
content: 这个错误一般是对内存越界 比如你malloc了4字节的空间 却给赋值超过4字节的东西  就会报这个错  你现在malloc了8个字节  你下面res[m]=j； m是否超过了2，是的话  就报这个错

user: user-0
content: 1. 两数之和

user: user-5
content: 不看意图的话,肯定是无限递归了. base没有考虑清楚导致的.

user: user-5
content: 题目编号可以说下. 只看代码不懂意图.
user-0 提问: 求解一个小问题

回复:
user: user-0
content: 引用 2 楼 自信男孩的回复:printf("最后的输出结果是%d,但a的值是%d",(a=2*8,a/4)); 这句代码里有两个%d，那么后面有几个参数对应呢？一个吧。那么另一个是不是一个随机值呢？ 谢谢大佬，我明白了

user: user-0
content: 引用 1 楼 user-2的回复:4198859应该是个随机值,因为printf("最后的输出结果是%d,但a的值是%d",(a=2*8,a/4));这是一个逗号表达式,只能算一个值,第二个%d没有值传给它!  逗号表达式:运算顺序从左到右,整个表达式的值为最后一个表达式的结果. 比如这里:(a=2*8,a/4)的计算过程: a=2*8  计算完后a =16; 然后计算a/4 计算结果为4; 所以整个表达式的结果是4; 所以printf中的第一个%d打印4. 第二个%d压根就没有传值! 谢谢大佬，我明白了

user: user-1
content: printf("最后的输出结果是%d,但a的值是%d",(a=2*8,a/4)); 这句代码里有两个%d，那么后面有几个参数对应呢？一个吧。那么另一个是不是一个随机值呢？

user: user-2
content: 4198859应该是个随机值,因为printf("最后的输出结果是%d,但a的值是%d",(a=2*8,a/4));这是一个逗号表达式,只能算一个值,第二个%d没有值传给它!  逗号表达式:运算顺序从左到右,整个表达式的值为最后一个表达式的结果. 比如这里:(a=2*8,a/4)的计算过程: a=2*8  计算完后a =16; 然后计算a/4 计算结果为4; 所以整个表达式的结果是4; 所以printf中的第一个%d打印4. 第二个%d压根就没有传值!
user-0 提问: k为什么是15？

回复:
user: user-1
content: 引用 4 楼 楚歌的楚啊 的回复:k = 10*10>15?10:15 乘号优先级比较高吧 错了 后面是15：10

user: user-1
content: k = 10*10>15?10:15 乘号优先级比较高吧

user: user-2
content: 引用 1 楼 真相重于对错 的回复:宏是直接的文本替换 展开后就是 k=10*(i)<(j)?(i):(j); 已经给你展开了，所以应该很清楚知道结果了，这个k就是j赋值的。 因为10 * (i)  < (j)这里*的优先级大于 <因此先执行10 * (i)然后执行 < (j);很明显判断为假，j赋值给k。

user: user-3
content: #define MIN(i,j) ((i)<(j)?(i):(j))

user: user-4
content: 宏是直接的文本替换 展开后就是 k=10*(i)<(j)?(i):(j);

user: user-0
content: 谢谢，

user: user-0
content: 引用 2 楼 mengjfu的回复:#define MIN(i,j) ((i)<(j)?(i):(j)) 非常感谢，涨知识了 谢谢

user: user-0
content: 引用 1 楼 真相重于对错的回复:宏是直接的文本替换 展开后就是 k=10*(i)<(j)?(i):(j); 谢谢，
user-0 提问: 求大神帮忙

回复:
user: user-1
content: 挺好的

user: user-2
content: vs没有问题，默认的转换估计不对。

user: user-3
content: 代码看上去是没问题的，什么错误截个图看看

user: user-4
content: 代码没错 ，应该把错误信息发出来 ， 估计是编译器方面的错误

user: user-5
content: 代码没问题，也不用强制类型转换，因为5*(F-32)/9;本身就是整型数据的四则运算。  楼主要说一下显示成什么格式了？认为是错误的。  printf("fahr=150,celsius=%d\n",C); 可以加一个换行符。

user: user-6
content: 结果强制转换一下试试(int)5*(F-32)/9