C常见陷阱,scanf不执行,以及指针类型应用传递。

Posted hanrui0617

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C常见陷阱,scanf不执行,以及指针类型应用传递。相关的知识,希望对你有一定的参考价值。

1.最近写了个结构体,一开始是这样的:

typedef struct fsll

{

  int  data_field;

  struct fsll *next;

}FSLL;

很普通的一个链表结构体,工作需要数据域改成char类型。

typedef struct fsll

{

  char data_field;

  struct fsll *next;

}FSLL;

...

for(...)

{

printf("请输入数据域内容:")

scanf("%c",&p->data_field);

}

发现scanf每隔一句就会被跳过一次。执行结果就是链表中的数据域是这样的:( )->(A)->( )->(C)->....

其实原因就是windows下,键入回车键产生了两个字符:013 回车与010换行。编辑器把013回车作为判断输入结束的标志,而010  也就是 留在了输入流的首端。第二次循环中。scanf的真正功能是从输入流中读取相应数量的字符,%d不会匹配 ,所以一般的数字链表不会产生这种问题。但%c,%s这种,可以从输入流中读取 ,也就造成了第二次scanf从键盘赋值得到了一个 (输出 什么也不显示),效果看起来就像是scanf间歇性被跳过。解决办法很简单,就是每次用scanf获取键盘的字符类型时,在语句前面调用一次getchar();消耗掉 ,以便scanf可以获取正确的值。关于getchar的妙用还有很多,以后有机会慢慢讲。

for(...)

{

printf("请输入数据域内容:")

getchar();

scanf("%c",&p->next);

}

2.把建立线性表封装成函数,实现在主函数中调用中,碰到了问题。由于纯C语言并不支持引用传递,所以像这种写法是会报错的:

void create_linked_list(FSLL *&head);

但如果想让参数在主函数与自定义函数之间传递(真正改变head的值),需要使用地址传递的方式,而用地址传递一个指针变量的写法也是真的很难看:

void create_linked_list(FSLL **head);

没错,这就是把指针变量的地址传进来,直接改地址对应的值,实现对实际参数的改变(真底层);

调用的时候是这样:

FSLL *head;

create_linked_list(&head);

以上就结束了本片博客

 

 

typedef struct fsll

{

  int  data_field;

  struct fsll *next;

}FSLL;

以上是关于C常见陷阱,scanf不执行,以及指针类型应用传递。的主要内容,如果未能解决你的问题,请参考以下文章

在ARM64下编程的常见陷阱:C语言常见陷阱

《C陷阱和缺陷》读书笔记-其二:语义陷阱

语义陷阱

嵌入式 Linux C语言——C语言的安全问题和指针陷阱

《C陷阱与缺陷》整理二

使用指针时的“陷阱”