精华内容
下载资源
问答
  • C语言函数重新输入由于使用了不受保护的系统资源(例如全局变量区,中断向量表),因此除非确保相互排斥(使用信号灯/代码的关键部分禁止中断),否则无法在多任务环境中运行等重入函数:没有静态数据结构不会返回指向...

    C语言函数重新输入

    由于使用了不受保护的系统资源(例如全局变量区,中断向量表),因此除非确保相互排斥(使用信号灯/代码的关键部分禁止中断),否则无法在多任务环境中运行等

    重入函数:

    没有静态数据结构不会返回指向静态数据的指针. 所有函数数据均由函数调用者提供. 使用自动变量,或通过复制全局变量来保护全局变量. 如果必须访问全局变量,请使用互斥信号来保护它们. 调用非可重入函数

    不可重入函数为:

    如果函数在重入条件下使用不受保护的共享资源,则该函数是不可重入的.

    函数中使用静态变量,无论它是全局静态变量还是局部静态变量. 该函数返回一个静态变量. 在函数中调用非可重入函数. 函数中使用静态数据结构. 在函数中调用malloc()或free()函数. 该函数调用其他标准I / O函数. 该函数是单例中的成员函数. 并使用不使用线程独立存储的成员变量

    将非可重入函数重写为可重入函数:

    1. 不要使用全局变量

    2. 当与硬件交互时可能发生中断时ccriticalsection对应c语言,请先关闭该中断(某些系列称为“进入/退出内核”或使用OS_ENTER_KERNAL / OS_EXIT_KERNAL来描述,这是关键部分的保护)

    3. 不要调用非可重入函数

    4. 小心使用堆栈,最好在使用前使用OS_ENTER_KERNAL

    中断是嵌入式系统的重要组成部分,这导致许多编译器开发人员提供了扩展,该扩展允许标准C支持中断. ISR:

    错误:

    1,ISR没有返回值

    如果它具有返回值,并返回给谁,则某种中断源将生成一个中断,并且系统将使用ISR进行处理. ISR链接到某个中断源,并且中断源的生成是随机的. 因此,ISR没有固定的调用方和固定的返回地址,因此返回值没有用.

    2,ISR无法传递参数

    3. 在许多编译器/处理器中,浮点数不是可重入的. 有些不允许在ISR中进行浮点运算.

    4. ISR应该简短有效. 进行浮点数运算是不明智的.

    5,printf是不可重入函数.

    说明:

    1. 浮点数: 通常,浮点操作由专用硬件执行. 例如,假设有一个名为FLOAT的硬件寄存器,用于计算和存储浮点数的中间运算结果.

    假设有这样的功能

    如果是第一次执行,则浮点运算的结果会暂时存储在FLOAT寄存器中,并在此时被中断,并且中断函数或其他进程也将调用fun函数,这是第二次调用的fun函数将在执行过程中破坏第一个FLOAT寄存器中的结果,因此,当返回第一个fun函数时,结果将不正确.

    2,printf功能

    引用全局变量stdout,它是标准输入和输出流的对象

    malloc --------全局内存分配表

    免费--------全局内存分配表

    Unix通常具有可重入的函数版本,其名称后缀_r

    这种情况发生在多任务系统中. 当在任务执行期间捕获并处理信号时,信号处理程序会暂时中断该过程正在执行的指令序列. 如果从信号处理程序返回,它将继续在过程断点处执行正常的指令序列. 从恢复到断点重新执行,函数所依赖的环境没有改变,可以说该函数是可重入的. 否则它不是可重入的.

    众所周知,在进程中断期间,系统会保存并恢复进程的上下文,但是恢复的上下文仅限于少数上下文,例如返回地址,cpu寄存器等,以及内部诸如全局或静态变量,缓冲区等函数. 它不受保护,因此如果在函数中断期间这些值发生变化,则当函数返回到断点以继续执行时结果将不可预测. 例如,对于malloc,例如,某个进程当前正在执行malloc以分配堆空间. 此时,程序捕获信号中断. 信号处理程序中还有一个malloc. 这将对流程环境造成损害,因为Malloc通常会为其分配的存储区维护一个链接表. 在插入和执行信号处理功能时,该进程可能正在此表上运行,并且信号处理功能的调用仅覆盖了该过程的操作,从而导致错误.

    以下大多数条件是不可重入函数:

    (1)使用静态数据结构;

    (2)称为malloc或free;

    (3)调用标准I / O函数;标准io库的许多实现都以不可重入的方式使用全局数据结构.

    (4)进行了浮点运算. 在许多处理器/编译器中,浮点运算通常是不可重入的(浮点运算通常使用协处理器或软件仿真来实现.

    1)信号处理程序A在内部和外部调用相同的不可重入函数B; B在执行过程中被信号中断并进入A(在A中调用B),并在完成后返回到B的中断点以继续执行. 这时,B函数的环境可能会更改,结果是不可预测的

    2)多个线程在进程内部共享资源. 如果两个线程A和B调用相同的不可重入函数F,则程A进入F之后,该线程被调度为切换到B,并且B也执行F. 再次切换到线程A时,调用F的结果也是意外的

    请注意,即使在信号处理程序中调用可重入函数也存在问题. 通常,在信号处理程序中调用可重入函数时,应先保存errno,然后再保存errno. (因为每个线程只有一个errno变量,所以信号处理函数可以修改其值. 要了解经常捕获的信号是SIGCHLD,它的信号处理程序通常调用wait函数,并且可以更改所有wait函数. errno. ) / p>

    可重入功能列表:

    _exit(),access(),警报(),cfgetispeed(),cfgetospeed(),cfsetispeed(),cfsetospeed(),chdir(),chmod(),chown(),close(),creat() ,Dup(),dup2(),execle(),execve(),fcntl(),fork(),fpathconf(),fstat(),fsync(),getegid(),geteuid(),getgid(),getgroups) (),Getpgrp(),getpid(),getppid(),getuid(),kill(),link(),lseek(),mkdir(),mkfifo(),open(),pathconf(),pause()) ,Pipe(),raise(),read(),重命名(),rmdir(),setgid(),setpgid(),setsid()ccriticalsection对应c语言,setuid(),sigaction(),sigaddset(),sigdelset(),sigemptyset) (),Sigfillset(),sigismember(),signal(),sigpending(),sigprocmask(),sigsuspend(),sleep(),stat(),sysconf(),tcdrain(),tcflow(),tcflush() ,Tcgetattr(),t cgetpgrp(),tcsendbreak(),tcsetattr(),tcsetpgrp(),time(),times(),umask(),uname(),unlink(),utime(),wait(), waitpid(),写().

    在本书的信号处理程序中调用非重入函数的示例:

    #include

    #include

    #include

    静态无效函数(int signo)

    {

    struct passwd * rootptr;

    if(((rootptr = getpwnam(“ root”))== NULL)

    {

    err_sys(“ getpwnam错误”);

    }

    信号(SIGALRM,函数);

    警报(1);

    }

    int main(int argc,char ** argv)

    {

    信号(SIGALRM,函数);

    警报(1);

    对于(;;)

    {

    if(((ptr = getpwnam(“ sar”))== NULL)

    {

    err_sys(“ getpwnam错误”);

    }

    }

    返回0;

    }

    给SIGALRM信号,然后设置一个计时器. 在for函数的执行过程中的某个时刻,也许相应的信号在getpwnam函数的运行过程中被中断,进入信号处理函数func,并在运行期间再次接收. 很容易遇到意想不到的问题.

    ================================================ ==== ==================================

    不可重入函数在返回之前不能再次调用. 例如,printf,malloc,free等是不可重入的函数. 因为中断可能随时发生,例如在执行printf期间,您不能在中断处理程序中调用printf,否则将重新输入printf.

    大多数函数都不是可重入的,因为在函数中引用了全局变量. 例如,printf将引用全局变量stdout,malloc,并自由引用全局内存分配表.

    个人理解: 如果发生中断,则在运行至printf时,假定发生了中断嵌套,并且此时已占用stdout资源,因此第二个中断printf等待第一个中断stdout资源的释放. 中断正在等待第二个中断返回,从而导致死锁. 我不知道这是否正确.

    非重入函数表示如果在调用函数之前再次调用该函数,则可能会产生错误. 可重入函数不存在此问题.

    非重入函数通常在实现时使用全局资源. 在多线程环境中,如果不能很好地处理数据保护和互斥访问,则会发生错误.

    常见的不可重入功能为:

    printf --------参考全局变量stdout

    malloc --------全局内存分配表

    免费--------全局内存分配表

    在Unix中,通常存在带有_r后缀的同名重入函数版本. 如果没有,请尝试在可预见的地方添加保护锁同步机制等.

    本文来自电脑杂谈,转载请注明本文网址:

    http://www.pc-fly.com/a/jisuanjixue/article-150757-1.html

    展开全文
  • ``` char alp; do { alp=getchar(); if(alp<65&&alp>90) { printf("Be sure to enter a upper letter"); } }while(alp<65&&alp>90); ``` 这样为什么不行?
  • #include int main() { char password[10]={0};...printf("请输入密码:\n"); for(i = 0;i { scanf("%s",password); if(strcmp(password,"123456") == 0) {  break; } else { printf("密码错误,请输入密码:
    #include <string.h>
    int main()
    {
    char password[10]={0};
    int i;
    printf("请输入密码:\n");
    for(i = 0;i < 3;i++)
    {
    scanf("%s",password);
    if(strcmp(password,"123456") == 0)
    {
       break;
    }
    else
    {
    printf("密码错误,请输入密码:\n");
    }
    }
    if(i == 3)
    printf("退出系统\n");
    else
    printf("登录成功\n");
    return 0;
    }
    展开全文
  • 前言:正式步入计算机专业,因为学习节奏很快和自己也开始松懈懒散,看到曾经的第一篇记载狠狠打脸,便决定不放弃这个好习惯,重新拾起! 通过四个月的学习,主要了解到 1.格式输入输出函数scanf,printf; 2....

    前言:正式步入计算机专业,因为学习节奏很快和自己也开始松懈懒散,看到曾经的第一篇记载狠狠打脸,便决定不放弃这个好习惯,重新拾起!
    通过四个月的学习,主要了解到
    1.格式输入输出函数scanf,printf;
    2.字符输入输出函数getchar,putchar;
    3.字符串输入输出函数gets,puts

    格式输出函数printf()
    一般格式:printf(“输出格式”,输出参数列表);
    其中输出格式的一般格式:% 输出附加格式说明符 输出格式说明符
    格式符的注意事项:
    %-md(有-左对齐;无-右对齐;无m或总宽度超过m时按实际宽度输出;不足m位补空格)
    %-m.nf或%-m.ne (同上,其中小数n位)

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    以上代码的分析如下
    在这里插入图片描述

    补充:关于进制转换
    在这里插入图片描述

    格式输入函数scanf
    一般格式:scanf(“输入格式”,输入参数地址列表);
    在终端输入形式的注意事项:
    以输入以下三个数9、8、6为例
    ①scanf("%d%d%d",&a,&b,&c);
    在终端由键盘输入为“9(空格)8(空格)6(空格)” (其中空格可用回车键或Tab键代替,它们都是非打印字符键)
    ②在输入数据时,遇到非法字符(不属于数值的字符)则结束
    如scanf("%d%c%f",&a,&b,&c);
    若在终端由键盘输入“1234m123o.45”遇到非法字符‘o’,在对应printf("%d,%c,%f",a,b,c);输出结果为“123,m,123”

    以下的实例输入中分别以回车,空格,Tab键隔开
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    字符输出函数putchar
    功能:从计算机向显示器输出一个字符
    格式:putchar©; (参数c可以是字符型或整型常量、变量、表达式)
    在这里插入图片描述

    字符输入函数getchar
    功能:从键盘向计算机输入一个字符
    格式:getchar(); (该函数不带参数,但必须带括号)
    在这里插入图片描述
    以上为输入OK后按下回车的情况;以下为输入O然后按下回车的情况,此时回车键可视为有效字符(’\n’)输出空行
    在这里插入图片描述

    字符串输入函数gets
    格式:gets(字符数组);
    功能:从键盘读入一个字符串到字符数组,输入的字符串允许包含空格,输入字符串时以回车键结束,系统自动在字符串末尾加上’\0’结束符。
    优点:相对而言,scanf函数的%s格式输入字符串中不能含空格
    在这里插入图片描述

    字符串输出函数puts
    格式:puts(字符数组);
    功能:从字符数组的首地址开始,输出字符数组,同时将‘\0’转换为换行字符。
    优点:相对而言,printf函数后面加语句printf("\n");才能换行
    在这里插入图片描述

    展开全文
  • 从键盘输入一个小于1000的正数,要求输出它的...若不是,则要求重新输入。解:程序:#include#include#define M 1000int main(){ int x,y; printf("请输入一个小于%d的正数x:",M); scanf("%d", &x); while(x>M) {

    从键盘输入一个小于1000的正数,要求输出它的平方根(如平方根不是整数,则输出其整数部分)。要求在输入数据后先对其进行检查是否为小于1000的正数。若不是,则要求重新输入。

    解:程序:

    #include<stdio.h>

    #include<math.h>

    #define M 1000

    int main()

    {

    int x,y;

    printf("请输入一个小于%d的正数x:",M);

    scanf("%d", &x);

    while(x>M)

    {

    printf("输入的数据不符合要求,请重新输入一个小于%d的正数x:", M);

    scanf("%d", &x);

    y = sqrt(x);

    }

    y = sqrt(x);

    printf("%d的平方根的整数部分是:%d\n",x,y);

    return 0;

    }

    结果1

    请输入一个小于1000的正数x81

    81的平方根的整数部分是:9

    请按任意键继续. . .

    结果2

    请输入一个小于1000的正数x1200

    输入的数据不符合要求,请重新输入一个小于1000的正数x7612

    输入的数据不符合要求,请重新输入一个小于1000的正数x121

    121的平方根的整数部分是:11

    请按任意键继续. . .


    本文出自 “岩枭” 博客,请务必保留此出处http://yaoyaolx.blog.51cto.com/10732111/1741420

    展开全文
  • C语言输入结束符EOF

    千次阅读 2014-11-25 22:25:15
    这次重新阅读《C语言程序设计》发现这个问题在开始时就讲了,原文摘录如下:  在没有输入时,getchar函数将返回一个特殊值,这个特殊值与任何实际字符都不同。这个值成为EOF(end of file)。  EOF定义在头文件中...
  • 从键盘输入一个小于1000的正数,要求输出它的平方根(如...若不是,则要求重新输入。解:程序:#include<stdio.h>#include<math.h>#define M 1000int main(){ int x,y; printf("请输入一个小于%d的...
  • https://jingyan.baidu.com/article/b0b63dbf0e24c64a4930705a.html
  • 代码: # include &lt;stdio.h&gt;   int main() {  int a,b,c,d=1;  printf("please input a number : \n");  scanf("%d",&amp;a);...please input a numb...
  • 今天在看同事的代码时遇上下面一行代码:fscanf(pfile, "WEBSPORT=\"%[^\"]\n...既然陌生,就必须要重新熟悉才行,于是上网查找了一下,彻底地弄明白上面的含义,重新熟悉了一下scanf函数的格式控制符。在此备忘个人...
  • 若不是,则要求重新输入。 解题思路:题目要求输入的数小于1000,为了增加程序的灵活性,定义符号常量M为1000,如果题目要求输入的数小于10000,只需修改define指令即可,不必修改主函数。 源代码演示: #include<...
  • 通过while控制输入的不是字母的话就重新输入,是的话就执行下一步判断。 #include<stdio.h> int main() { char ch; printf("请可爱的你输入一个字母:\n"); scanf("%c",&ch); while(!(ch>='a'&...
  • C语言输入未知长度字符数组

    万次阅读 2019-02-10 15:31:03
    重新捡起学习C语言系列 C语言输入未知长度字符数组 问题描述:在最基础的C语言中使用scanf()函数简单输入一行长串字符数组,以回车结束。储存每一个字符以参与后面的运算,或者将他们打印下来。 细节问题 回车...
  • 使用的理由(范围):如果输入数据很庞大,需要一次又一次的重新输入和调试时可采用本函数。 freopen()函数: 1.格式 FILE*freopen(constchar*filename,constchar*mode,FILE*stream); 2.参数说明 filename:要...
  • 最多能输入三次密码,密码正确,提示“登录成功”, 密码错误,可以重新输入,最多输入三次。三次均错,则提示退出程序。 int main() { int i = 0; for (i = 0; i < 3; i++) { char arr[10] = { 0 }; printf...
  • C语言输入的一个字符串进行排序

    万次阅读 2015-06-01 10:45:16
    #include #include #include void main() { char str[50]; int i,j,len; printf("请输入字符串:"); scanf("%s",str); len=strlen(str);//计算你输入的字符串的长度 ...重新输入:"); s
  • 验证用户输入的日期格式是否正确,如果不正确,则提示重新输入,直到重新输入正确为止。 (提示:需要定义一个表示日期的结构体类型struct Date,包括年、月、日信息,并用typedef重新定义新类型名Date;检查日期是否...
  • C语言健壮性 - 读入非法字符提示用户重新输入

    千次阅读 多人点赞 2020-09-19 21:50:44
    为了增强程序的健壮性,有必要的一点就是,你需要对用户输入的不合法的数据进行处理,以防止由于用户的错误操作导致的程序崩溃。 比如,当你写了一个程序,比如一个简单的计算器(部分如下图),你希望用户每次...
  • 卡在循环出不来了……想知道多重方法解决这种问题!!!谢谢各位大佬指点[img=https://img-bbs.csdn.net/upload/202011/08/1604825761_245394.png][/img][img=...
  • C语言的文件操作 freopen 今天做USACO 用到了文件的操作。 之前做USACO只是格式化的些 写 freopen("xxx.in","r",stdin) 和"freopen("xxx.out","w",stdout)" 百度百科上是这么介绍的:  函数名: freopen  功...
  • C语言实现密码输入 ...可以重新输入,最多输入三次。三次均错,则提示退出程序。 代码呈上 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h>...
  • C语言输入输出重定,freopen()妙用

    千次阅读 2016-04-21 10:29:48
    使用的理由(范围):如果输入数据很庞大,需要一次又一次的重新输入和调试时可采用本函数。 freopen ()函数: 1.格式 FILE * freopen ( const char * filename, const char * mode, FILE * stream...
  • 使用的理由(范围):如果输入数据很庞大,需要一次又一次的重新输入和调试时可采用本函数。 freopen ()函数: 1.格式 FILE * freopen ( const char * filename, const char * mode, FILE * ...
  • 1、一维数组与指针数组声明为int a[10];...其中*numbers指向的是numbers[0],其中输入第一个数numbers[0]可以直接使用scanf("%d", numbers);不需使用&符号。数组与指针的关系:*numbers=numbers[0]; *(numbers+n...
  • ![图片说明]... 如图,将c的加减输入转换成Mips格式,最多输入128个字符,需要用到$1-$7, $t0-$t9,如果9个不够需要从$t0重新开始。 能写出来非常感谢,如果不能提供思路即可。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,061
精华内容 424
关键字:

c语言重新输入

c语言 订阅