您好,
会员登录 快速注册
退出 ( 条未读消息)
关于本站 意见反馈 首页

公告:小宅博客网可以开发票了,需要发票的,去群里找群主哈!!
全部文章分类
  • 人工智能 >

  • 编程语言 >

  • WPF系列 >

  • ASP.NET系列 >

  • Linux >

  • 数据库 >

  • 嵌入式 >

  • WEB技术 >

  • PLC系列 >

  • 微服务与框架 >

  • 小宅DIY >

  • 学习资料 >

OpenCv基础 ANN车牌识别 yolov5车牌识别 指针式仪表识别 ROS系列 YOLO Halcon Detectron2 昇腾AI ChatGPT在线体验 英伟达JETSON ChatGLM ChatTTS FunASR 地平线 ByteTrack 魔搭社区 LangChain
C C# C++ Python Java Go
WPF
ASP.NET小功能 GPS定位系统-MVC GPS定位系统-VUE ASP.NET WebRTC
Linux Linux内核 Shell MakeFile
MySql SqlServer Oracle
STM8 STM32 51单片机
VUE入门 HTML JavaScript CSS layui镜像网站 ElementUi中文官网 element-plus 图标
三菱 欧姆龙 西门子 施耐德 松下 台达
IOTSharp IOTGateway ABP FRAMEWORK Docker
亚克力音响 编程仙途:智驭万法
面试题与技巧 Python入门技能树 微软C#教程
首页 编程之美 工具下载 全国就业 流量地图 文心一言
C
1、99乘法表 2、指针5分钟教程 3、12个有趣的C语言问答 佛祖保佑,永无BUG Linux MQ接收与发送 C语言 TCP客户端
2、指针5分钟教程
佛祖保佑,永无BUG
激萌の小宅 小宅博客网 C

文章作者:激萌の小宅

促销:¥0

价格:¥0

配送方式: 购买后立即生效(如购买异常,请联系站长)
付款之后一定要等待自动跳转结束,否则购买可能会失败
  • 0 天

    有效期

  • 0

    总销量

  • 0

    累计评价

12个有趣的C语言问答 - (三)


1,gets() 方法

       Q:以下代码有个被隐藏住的问题,你能找到它吗?

#include <stdio.h>
int main(void)
{
    char buff[10];
    memset(buff,0,sizeof(buff));
    gets(buff);
    printf("\n The buffer entered is [%s]\n",buff);
    return 0;
}

       A:这个不显眼的问题就是使用了 gets() 方法。此方法接受一个string类型参数,但是却没有检测此数值是否 有足够的空间来拷贝数据。所以这里我们一般用 fgets() 方法将来的更好。


2,strcpy() 方法

 Q:密码防护是很基本的功能,看看能否搞定下面这段代码?

#include <stdio.h> 
int main(intargc,char*argv[])
{
    int flag = 0;
    char passwd[10];
    memset(passwd,0,sizeof(passwd));
    strcpy(passwd, argv[1]);
    if(0 ==strcmp("LinuxGeek", passwd))
    {
        flag = 1;
    }
    if(flag)
    {
        printf("\n Password cracked \n");
    }
    else
    {
        printf("\n Incorrect passwd \n");
    }
    return 0;
}


3,main() 方法的返回类型

       Q:请问下面这段代码能否通过编译?如果能的话,那么这段代码中隐含什么问题吗?

#include <stdio.h>
void main(void)
{
    char *ptr = (char*)malloc(10);
    if(NULL == ptr)
    {
        printf("\n Malloc failed \n");
        return;
    }
    else
    {
        // Do some processing
        free(ptr);
    }
    return;
}

       A:答案是代码能通过编译,但是会留下针对main()方法的返回类型的警告。main()方法的真正返回类型应该为'int'而非'void'。这是因为'int'返回类型能够让程序返回状态值。尤其是当这段程序作为其他应用的附属程序时这个状态值将更加重要。


4,内存泄露

       Q:请问以下代码有内存泄露吗?

#include <stdio.h>
void main(void)
{
    char*ptr = (char*)malloc(10);
    if(NULL == ptr)
    {
        printf("\n Malloc failed \n");
        return;
    }
    else
    {
        // Do some processing
    }
    return;
}

       A:好,虽然上面的代码没有对指针 ptr 进行内存释放,但实际上即使是程序结束也不会造成内存泄露,因为当程序结束时所有一开始被占据的内存就全部清空了。但如果上面这段代码是在 while 循环里面那将会造成严重的问题。

       Note: 如果你需要了解更多关于内存泄露的问题以及如何使用工具检测内存泄露,你可以参考这篇文章Valgrind


5,free() 方法

       Q:以下代码当用户输入'freeze'时会奔溃,而如果输入'zebra'则运行正常,这是为什么?

#include <stdio.h>
int main(intargc,char*argv[])
{
    char *ptr = (char*)malloc(10);
    if(NULL == ptr)
    {
        printf("\n Malloc failed \n");
        return -1;
    }
    elseif(argc == 1)
    {
        printf("\n Usage  \n");
    }
    else
    {
        memset(ptr, 0, 10);
        strncpy(ptr, argv[1], 9);
        while(*ptr !='z')
        {
            if(*ptr =='')
                break;
            else
                ptr++;
        }
        if(*ptr =='z')
        {
            printf("\n String contains 'z'\n");
            // Do some more processing
        }
       free(ptr);
    }
    return 0;
}

       A:问题的根源是因为代码在while循环中改变了 ptr 指针的地址。当输入为'zebra'时,while循环甚至在执行 第一遍前就结束了,所以free()释放的内存地址就是一开始malloc()分配的地址。但是当输入'freeze'时, ptr记录的地址在while循环中被更改,因为将会是错误的地址传递到free()方法中引起崩溃。


6,atexit with _exit

       Q:在以下代码,atexit()方法并没有被调用,你知道为什么吗?

#include <stdio.h>
void func(void)
{
    printf("\n Cleanup function called \n");
    return;
    }
int main(void)
{
    int i = 0;
    atexit(func);
    for(;i<0xffffff;i++);
    _exit(0);
}

       A:这是因为使用了 _exit() 方法。此方法并没有调用清除数据相关的方法,比如 atexit()等。


7,void* 与 C 结构体

       Q:能否设计一个方法接受任意类型的参数然后返回整数?同时是否有办法传递多个这样的参数?

       A:一个能接受任意类型参数的方法像下面这个样子:

int func(void*ptr)

       如果需要传递多个参数,那么我们可以传递一个包含这些参数的结构体


8,* 与 ++ 操作符

       Q:以下代码将输出什么?为什么?

#include <stdio.h>
int main(void)
{
    char *ptr ="Linux";
    printf("\n [%c] \n",*ptr++);
    printf("\n [%c] \n",*ptr);
    return 0;
}

       A:以上的输出将是:

[L]

[i]

       因为++与 * 的优先级一样,所以 *ptr++ 将会从右向左操作。按照这个逻辑,ptr++ 会先执行然后执行*ptr。所以第一个结果是'L'。也因为 ++ 被执行了,所以下一个printf() 结果是'i'。


9,Making changes in Code segment

       Q:以下代码运行时一定会崩溃,你能说出原因吗?

#include <stdio.h>
int main(void)
{
    char *ptr ="Linux";
    *ptr ='T';
    printf("\n [%s] \n", ptr);
    return 0;
}

       A:这是因为,通过 *ptr = 'T',此行代码尝试更改只读内存存储的字符串'Linux'。此操作当然行不通所以才会造成崩溃。


10,Process that changes its own name

       Q:你能否写一个程序在它运行时修改它的名称?

       A:以下代码可以完成

#include <stdio.h>
int main(intargc,char*argv[])
{
    int i = 0;
    char buff[100];
    memset(buff,0,sizeof(buff));
    strncpy(buff, argv[0],sizeof(buff));
    memset(argv[0],0,strlen(buff));
    strncpy(argv[0],"NewName", 7);
    // Simulate a wait. Check the process
    // name at this point.
    for(;i<0xffffffff;i++);
    return 0;
}


11,局部变量的返回地址

       Q:下面的代码有问题吗?如果有,如何修改?

#include <stdio.h>
int* inc(intval)
{
  int a = val;
  a++;
  return &a;
}

int main(void)
{
    int a = 10;
    int *val = inc(a);
    printf("\n Incremented value is equal to [%d] \n", *val);
    return 0;
}

       A:虽然上面的代码有时运行会很好,但是在方法 inc() 中有很严重的隐患。当inc()方法执行后,再次使用局部变量的地址就会造成不可估量的结果。解决之道就是传递变量a的地址给main()。


12,处理 printf() 参数

       Q:以下代码输出请问是什么?

#include <stdio.h>
int main(void)
{
    int a = 10, b = 20, c = 30;
    printf("\n %d..%d..%d \n", a+b+c, (b = b*2), (c = c*2));
    return 0;
}

       A:输出将是

110..40..60

       这是因为参数都是从右向左处理的,然后打印出来却是从左向右。

2、指针5分钟教程
佛祖保佑,永无BUG

友情链接: CSDN激萌の小宅 95知识库 自考题库 罗分明个人网络博客 精益编程leanboot

小宅博客  www.bilibili996.com All Rights Reserved. 备案号: 闽ICP备2024034575号

网站经营许可证  福建省福州市 Copyright©2021-2025 版权所有

小宅博客
首页 智能家居 地图定位
公告:小宅博客网可以开发票了,需要发票的,去群里找群主哈!!

文章作者:激萌の小宅

促销:¥0

价格:¥0

配送方式: 购买后立即生效(如购买异常,请联系站长)
付款之后一定要等待自动跳转结束,否则购买可能会失败
  • 0 天

    有效期

  • 0

    总销量

  • 0

    累计评价

12个有趣的C语言问答 - (三)


1,gets() 方法

       Q:以下代码有个被隐藏住的问题,你能找到它吗?

#include <stdio.h>
int main(void)
{
    char buff[10];
    memset(buff,0,sizeof(buff));
    gets(buff);
    printf("\n The buffer entered is [%s]\n",buff);
    return 0;
}

       A:这个不显眼的问题就是使用了 gets() 方法。此方法接受一个string类型参数,但是却没有检测此数值是否 有足够的空间来拷贝数据。所以这里我们一般用 fgets() 方法将来的更好。


2,strcpy() 方法

 Q:密码防护是很基本的功能,看看能否搞定下面这段代码?

#include <stdio.h> 
int main(intargc,char*argv[])
{
    int flag = 0;
    char passwd[10];
    memset(passwd,0,sizeof(passwd));
    strcpy(passwd, argv[1]);
    if(0 ==strcmp("LinuxGeek", passwd))
    {
        flag = 1;
    }
    if(flag)
    {
        printf("\n Password cracked \n");
    }
    else
    {
        printf("\n Incorrect passwd \n");
    }
    return 0;
}


3,main() 方法的返回类型

       Q:请问下面这段代码能否通过编译?如果能的话,那么这段代码中隐含什么问题吗?

#include <stdio.h>
void main(void)
{
    char *ptr = (char*)malloc(10);
    if(NULL == ptr)
    {
        printf("\n Malloc failed \n");
        return;
    }
    else
    {
        // Do some processing
        free(ptr);
    }
    return;
}

       A:答案是代码能通过编译,但是会留下针对main()方法的返回类型的警告。main()方法的真正返回类型应该为'int'而非'void'。这是因为'int'返回类型能够让程序返回状态值。尤其是当这段程序作为其他应用的附属程序时这个状态值将更加重要。


4,内存泄露

       Q:请问以下代码有内存泄露吗?

#include <stdio.h>
void main(void)
{
    char*ptr = (char*)malloc(10);
    if(NULL == ptr)
    {
        printf("\n Malloc failed \n");
        return;
    }
    else
    {
        // Do some processing
    }
    return;
}

       A:好,虽然上面的代码没有对指针 ptr 进行内存释放,但实际上即使是程序结束也不会造成内存泄露,因为当程序结束时所有一开始被占据的内存就全部清空了。但如果上面这段代码是在 while 循环里面那将会造成严重的问题。

       Note: 如果你需要了解更多关于内存泄露的问题以及如何使用工具检测内存泄露,你可以参考这篇文章Valgrind


5,free() 方法

       Q:以下代码当用户输入'freeze'时会奔溃,而如果输入'zebra'则运行正常,这是为什么?

#include <stdio.h>
int main(intargc,char*argv[])
{
    char *ptr = (char*)malloc(10);
    if(NULL == ptr)
    {
        printf("\n Malloc failed \n");
        return -1;
    }
    elseif(argc == 1)
    {
        printf("\n Usage  \n");
    }
    else
    {
        memset(ptr, 0, 10);
        strncpy(ptr, argv[1], 9);
        while(*ptr !='z')
        {
            if(*ptr =='')
                break;
            else
                ptr++;
        }
        if(*ptr =='z')
        {
            printf("\n String contains 'z'\n");
            // Do some more processing
        }
       free(ptr);
    }
    return 0;
}

       A:问题的根源是因为代码在while循环中改变了 ptr 指针的地址。当输入为'zebra'时,while循环甚至在执行 第一遍前就结束了,所以free()释放的内存地址就是一开始malloc()分配的地址。但是当输入'freeze'时, ptr记录的地址在while循环中被更改,因为将会是错误的地址传递到free()方法中引起崩溃。


6,atexit with _exit

       Q:在以下代码,atexit()方法并没有被调用,你知道为什么吗?

#include <stdio.h>
void func(void)
{
    printf("\n Cleanup function called \n");
    return;
    }
int main(void)
{
    int i = 0;
    atexit(func);
    for(;i<0xffffff;i++);
    _exit(0);
}

       A:这是因为使用了 _exit() 方法。此方法并没有调用清除数据相关的方法,比如 atexit()等。


7,void* 与 C 结构体

       Q:能否设计一个方法接受任意类型的参数然后返回整数?同时是否有办法传递多个这样的参数?

       A:一个能接受任意类型参数的方法像下面这个样子:

int func(void*ptr)

       如果需要传递多个参数,那么我们可以传递一个包含这些参数的结构体


8,* 与 ++ 操作符

       Q:以下代码将输出什么?为什么?

#include <stdio.h>
int main(void)
{
    char *ptr ="Linux";
    printf("\n [%c] \n",*ptr++);
    printf("\n [%c] \n",*ptr);
    return 0;
}

       A:以上的输出将是:

[L]

[i]

       因为++与 * 的优先级一样,所以 *ptr++ 将会从右向左操作。按照这个逻辑,ptr++ 会先执行然后执行*ptr。所以第一个结果是'L'。也因为 ++ 被执行了,所以下一个printf() 结果是'i'。


9,Making changes in Code segment

       Q:以下代码运行时一定会崩溃,你能说出原因吗?

#include <stdio.h>
int main(void)
{
    char *ptr ="Linux";
    *ptr ='T';
    printf("\n [%s] \n", ptr);
    return 0;
}

       A:这是因为,通过 *ptr = 'T',此行代码尝试更改只读内存存储的字符串'Linux'。此操作当然行不通所以才会造成崩溃。


10,Process that changes its own name

       Q:你能否写一个程序在它运行时修改它的名称?

       A:以下代码可以完成

#include <stdio.h>
int main(intargc,char*argv[])
{
    int i = 0;
    char buff[100];
    memset(buff,0,sizeof(buff));
    strncpy(buff, argv[0],sizeof(buff));
    memset(argv[0],0,strlen(buff));
    strncpy(argv[0],"NewName", 7);
    // Simulate a wait. Check the process
    // name at this point.
    for(;i<0xffffffff;i++);
    return 0;
}


11,局部变量的返回地址

       Q:下面的代码有问题吗?如果有,如何修改?

#include <stdio.h>
int* inc(intval)
{
  int a = val;
  a++;
  return &a;
}

int main(void)
{
    int a = 10;
    int *val = inc(a);
    printf("\n Incremented value is equal to [%d] \n", *val);
    return 0;
}

       A:虽然上面的代码有时运行会很好,但是在方法 inc() 中有很严重的隐患。当inc()方法执行后,再次使用局部变量的地址就会造成不可估量的结果。解决之道就是传递变量a的地址给main()。


12,处理 printf() 参数

       Q:以下代码输出请问是什么?

#include <stdio.h>
int main(void)
{
    int a = 10, b = 20, c = 30;
    printf("\n %d..%d..%d \n", a+b+c, (b = b*2), (c = c*2));
    return 0;
}

       A:输出将是

110..40..60

       这是因为参数都是从右向左处理的,然后打印出来却是从左向右。