杂记(unfinished

"本文详细讲解了C语言中NULL指针的概念、作用以及如何防止错误解引用。还介绍了strcpy函数的用途、注意事项,包括原字符串尾部的''处理以及内存空间大小的考虑。此外,文中提到了字符处理函数、循环控制与break/continue的使用,以及scanf和printf的配合技巧。"
摘要由CSDN通过智能技术生成

NULL

在c中NULL是个指针变量,指向地址0

简单来说,NULL的作用就是当一个指针变量没有被显性初始化时,将该指针变量的值赋为NULL。解引用前判断指针变量是否为NULL,如果为NULL说明该指针没有初始化过,不可解引用

可以防止我们错误的解引用指针

NULL是一个特殊的地址,在操作系统中定义该地址是不可以访问的,我猜测NULL也就是0地址是操作系统内核的地址,用户是不可访问的。一旦我们去解引用NULL地址,就会报段错误

strcpy函数

是将一个字符串复制到另一块空间地址上的函数
\0时停止拷贝,同时也将’\0’复制到目标空间

char*strcpy(char*destination,const char*source);

具体使用

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main(){
	char arr[10] = "########";
	printf("%s\n", strcpy(arr,"hello"));
} //输出结果hello
//第二种使用方法
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
 
int main(){
	char arr1[10] = "**********";
	char arr2[10] = "abcd";
	printf("%s\n", strcpy(arr1, arr2));
}

注意事项

原字符必须以’\0’结尾

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
 
int main()
{
	char arr1[10] = "**********";
	char arr2[] = { 'a','b','c','d' };
	printf("%s\n", strcpy(arr1,arr2)); //arr2字符串所在的内存空间后面存储的内容并不知道,会导致越界
}

目标空间必须足够大,以确保能放原字符串

目标空间必须可变

getchar() putchar()

这些函数只处理字符,所以比scanf函数更快

该函数以无符号char强制转换为int的形式读取返回函数,如果发生错误则返回EOF

用户输入的字符被放在缓冲区中,直到用户按下回车为止,回车字符也放在缓冲区

返回值是ASCII码,要用int类型存储,每一次循环读入一个字符

getchar函数不带任何参数,他从输入队列中返回下一个字符

ch=getchar();
scanf("%c",&ch); //等效于上面那个语句

putchar() 打印他的参数

putchar(ch);
printf("%c",ch);

同时存在两个输入函数

不正确的输入方法:

原因:两个输入函数的值都存在于一个缓冲区域,同时存在两个输入函数时,第一次输入的被scanf读取走,敲击回车键进入下一个语句时,只剩下了’\n’存在缓冲区中,所以直接走了else语句

//设置密码操作
int main(){
    char password[]={0};
    printf("please enter the password");
    scanf("%s",password);
    int ch =getchar();
    if(ch=='y')
        printf("right");
    else
        printf("FALSE");
}

改进方案

int main(){
    char password[]={0};
    printf("please enter the password");
    scanf("%s",password);
    printf("please check the password");
    while(getchar()!='\n'){
        ;
    }
    int ch =getchar();
    if(ch=='y')
        printf("right");
    else
        printf("FALSE");
}
int main(){
    int ch=0;
    while((ch=getchar())!=EOF){
        if(ch<'0' || ch>'9')
            continue;
        putchar(ch);
    }
}

多次使用scanf函数

函数第一次调用scanf之后,只从stdin中取走了信息,但是回车是没有取的,所以第二次调用会出现直接返回的现象,将回车取走

操作:加上fflush(),清空stdin
#include <stdio.h>
#include <math.h>
double cal(double a1, double b1, double a2, double b2){
    double t;
    t = sqrt(pow((a1-a2),2)+pow((b1-b2),2));
    return t;
}
int main(int argc, char const *argv[]){
    double x1 = 0, x2 = 0, y1 = 0, y2 = 0, d = 0;
    printf("Please input section A :\n");
    scanf("%lf%lf", &x1, &y1);
    fflush(stdin);
    printf("Please input section B :\n");
    scanf("%lf%lf", &x2, &y2);
    d = cal(x1,y1,x2,y2);
    printf("The distance is %f\n", d);
}

ctype.h系列的字符函数

c有一系列专门处理字符的函数,ctype.h这个头文件里包含了这些函数的原型

头文件中的字符测试函数

函数名如果是下列参数返回值为真
isalnum()字母数字(字母或数字)
isalpha()字母
isblank()标准的空白字符(空格、水平制表符或换行符)或任何本地化指定为空白的字符
iscntrl()控制字符,如ctrl+B
isdigit()数字
isgraph()除空格之外的任意可打印字符
islower()小写字母
isprint()大写字母
ispunct()标点符号(除空格或字母数字字符以外的任何可打印字符)
isspace()空白字符(空格、换行符、换页符、回车符、垂直制表符、水平制表符或其他本地化的字符)
isupper()大写字母
isxdigit()十六进制数字符

头文件中的字符映射函数

函数名行为
tolower()如果参数是大写字母,则函数返回值为小写字母,否则返回原始函数
toupper()如果参数是小写字母,则函数返回值为大写字母,否则返回原始函数

使用案例

#include <stdio.h>
#include <ctype.h>                // 包含isalpha()的函数原型
int main(void){
    char ch;

    while ((ch = getchar()) != '\n'){
        if (isalpha(ch))        // 如果是一个字符,
            putchar(ch + 1);   // 显示该字符的下一个字符
        else                    // 否则,
            putchar(ch);       // 原样显示
    }
    putchar(ch);                 // 显示换行符
}

continue break

continue

所有循环可以使用continue语句,执行到该语句时,会跳过本次迭代的剩余部分,并开始下一轮迭代,如果在嵌套循环里面,则只会影响包含该语句的内层循环

switch语句不能使用continue语句

避免使用continue

1.省略continue
2·把剩余部分放在else块中

当作占位符

优点:可读性更高

如若复杂化代码,则可以考虑在使用反向判断的情况下,不使用continue

while(getchar()!='\n'){
;
}
//第二种方法
while(getchar()!='\n'){
continue;
}

易错

如果执行continue语句,则会跳过后两个语句,直接执行while循环语句

int count=0;
while(count<10){
    ch=getchar();
    if(ch=='\n')
        continue;
    putchar();
    count++;
}

break

范围

所有的循环和break语句,跳出当前循环或者执行switch语句的剩余部分

作用

会终止包含他的循环,并继续执行下一阶段。

如果break语句位于嵌套循环之内,他只会影响当前循环

while(scanf("%f %f",&length,&width)==2);//利用scanf函数的返回值,判断输入的是否为浮点数

scanf函数的返回值

正整数

表示正确输入参数的个数

while(scanf("%f %f",&length,&width)==2);//利用scanf函数的返回值,判断输入的是否为浮点数

例如执行 scanf(“%d %d”, &a, &b);
如果用户输入”3 4”,可以正确输入,返回2(正确输入了两个变量);
如果用户输入”3,4”,可以正确输入a,无法输入b,返回1(正确输入了一个变量)。

0

表示用户的输入不匹配,无法正确输入任何值。如上例,用户如果输入”,3 4”,返回0。

EOF

这是在 stdio.h 里面定义的常量(通常值为-1),表示输入流已经结束。在Windows下,用户按下CTRL+Z(会看到一个^Z字符)再按下回车(可能需要重复2次),就表示输入结束;Linux/Unix下使用CTRL+D表示输入结束。

goto语句

组成

goto和标签名

part2:printf("refined analysis:\n";)
goto part2;

可以接受的一种方法

while (funct > 0){
     for (i = 1; i <= 100; i++){
          for (j = 1; j <= 50; j++){
               //其他语句
               if (问题)
                   goto help;
               //其他语句
          }
          //其他语句
     }
    // 其他语句
}
//其他语句
help: 语句
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值