当前位置: > 华清远见教育科技集团 > 嵌入式学习 > 讲师博文 > 关于使用C语言编程的一些细节问题
关于使用C语言编程的一些细节问题
时间:2016-12-13作者:华清远见

使用了野指针

#include<stdio.h>
        #include<string.h>

        int main(void){
            char *str,*str1,*str2;

            printf("input str1 and str2");
            scanf("%s%s",str1,str2);

            printf("str1 = %s\n str2 = %s\n",str1,str2);
            return 0;
        }

任何的输入,程序都要为输入预留空间,输入字符串就必须要为其留空间。但是char *str1只是为存储指针留下了空间,而不是为存储若干个字符开辟了空间。Str1中的内容是本应是用来存储字符的空间的地址。由于未经过初始化,导致str1里面存放的是随机值。这就是我们俗称的"野指针"。也就是说,我们根本不确定这个指针到底指向的空间是哪里,使用这样的指针,会对内存中的某些数据意外地进行改写,这是绝对不可以的。

在C语言中,我们分配存储空间的方式有两个:

1. Char string[100]; 定义一个局部变量,并且指定其空间的大小。

2. Char *p ; p = (char*)malloc(size_of_string); 定义一个指针,为这个指针所指向的位置分配需要的空间大小。Malloc是在堆上分配空间的函数,可以根据自己的需要来分配空间,但是,在不使用这块空间的时候,需要自己利用free()函数手动释放空间。

为了防止野指针的出现,我们在定义完指针变量后,要为指针变量赋值NULL。这是一个空指针,可以防止野指针指向我们不确定的位置。

Scanf() 函数的调用

很多初学者,调用scanf的时候,总会这样写:
        Int a;
        Scanf("%d\n",&a);

然后,会发现输入多少个回车,程序都没有反应。

这个错误在于把使用printf函数的习惯带入到了scanf函数中了,而对于scanf函数的格式字符串中的'\n'的意义缺乏了解。

Scanf函数调用时,这个'\n',并不是表示输入一个回车换行。

我们来看scanf函数原型:
        Intscanf(const char * restrict format,…);

Scanf函数在format所指向的字符串控制下读取标准输入设备上的输入。Format所指向的字符串中的字符序列叫做指令,这种指令有一下三种:
        ●  转换说明,如"%d",它指示读取一个与十进制整数相匹配的字符序列。
        ●  普通字符,如"A",它表示scanf函数读取与"A"精确匹配的字符
        ●  空白字符,如"""\n"或者"\t"。空白字符在scanf函数调用时,指示scanf读取输入设备所输入的一系列连续的空白字符(即输入回车,空格或TAB),知道遇到非空白字符为止。

所以,scanf函数调用时,控制字符串中的一个空白字符,可以匹配无穷多个连续的空白字符序列。

对于"%c"的解释

Scanf函数的%c 转换说明符用于输入单个字符。

如果使用scanf("%3c",&c);如果从键盘连续输入3个字符"abc",由于c只是一个char类型的变量,那么系统就把第一个'a'字符赋给字符变量c。

但是,运行下面的代码:

#include<stdio.h>

        #include<stdlib.h>
        int main(void){
            char c1 = 'H';
            char c2 = 'E';
            char c3 = 'O';

            printf("first c1,c2,c3:%c%c%c\n",c1,c2,c3);

            printf("input:\n");
            scanf("%3c",&c3);

            printf("last c1,c2,c3:%c %c %c\n",c1,c2,c3);

            return 0;
        }

你会发现,输入的abc三个字符都被写入了内存。意外的改变了内存中的数据,这是十分危险的事情。事实上,scanf()函数中的"%c"并非是输入单个字符的,而是用来输入一组字符,只不过当宽度为1时,%c是可以输入单个字符的。但是若宽度不为1,输入的字符将会被写入内存中,修改了你未曾想到的变量,可能会导致很严重的bug。

Exit(0)

"exit(0)"的作用是退出程序并返回一个int类型的值给操作系统,这个值是可以被程序调用者检测到的,程序调用者可以根据这个值判断程序是在何种情况下结束的,并且根据这个来进行下一步的工作。

若程序正常结束,一般是返回0这个值(或EXIT_SUCCESS,这是在stdlib.h中定义的宏)。若程序无法完成工作,一般返回一个非零的值表示异常终止,在标准中返回EXIT_FAILURE。 当程序出现问题,无法正常执行而退出,视为一种异常退出,应该返回相应的值。在main函数中,return和exit函数返回效果是一样的,通常没有必要在main函数中使用exit退出。通常,在其他函数内退出程序时,由于return语句无法达到退出的作用,才需要调用exit函数。

发表评论
评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)