【C语言冷知识】05_让人误解的嵌套

本文探讨了C语言教科书中关于嵌套的概念,指出其实质是独立空间中的相同元素重叠,强调了理解和记忆分支结构、循环和函数时应关注独立空间的规则,而非将其视为不同类别。
摘要由CSDN通过智能技术生成


1、教科书中的嵌套

  在C语言教科书里面,当遇到分支结构、循环、函数调用和结构体的时候,都会提及到一个概念,就是嵌套,笼统地说就是套娃,A里面可以有和A同类的东西,当时学的时候挺费脑子的,书里面还有一堆习题让你去区分到底哪个是哪个,在毕业后回头看这个章节觉得是不需要存在的,反而让人误解有什么新东西的产生。书里面是这样去描述的:
在这里插入图片描述

1.1、分支结构的嵌套

  在if语句中又包含一个或者多个if语句称为if语句的嵌套。接着书本给出一个很容易让人判断错误的例子,第一个if其实是没有else的,但是刻意的对齐和糟糕的编程风格实在是误导别人。
在这里插入图片描述
  在这里,小白想给出自己对于if-else的理解:
  1、每一个if或者else后面,是一个新的独立空间,它可以操作所有符合作用域范围内的对象,以及定义新的变量类型,但是不能定义函数;
  2、为了正确理解,必须在ifelse后面添加花括号{}以代表独立空间的边界,并且以不同的缩进表达不同的空间;
  3、对于C语言标准,if后面可以没有else,也可以有else
  4、如果if后面有else,那么他们必然处于同层空间;

  现在我们抛开嵌套这个概念,重新回去看那个糟糕的例子,根据3和4整理如下:

if () {
    if () {
    } else {
        if () {
        } else {
        }
    }
}

  就这样子的编程风格,你还会有疑问么,即使不需要人肉整理,现在很多格式化工具就能帮你办到,比如我用AStyle格式化前后的样子如下:
在这里插入图片描述

在这里插入图片描述

1.2、循环的嵌套

  一个循环体内又包含另一个完整的循环结构,称为循环的嵌套。于是书中列举了一些的情况:
在这里插入图片描述
  其实更加复杂了,也是一样,抛开嵌套,直接挪用if-else的部分理解内容:
  1、每一个循环后面,是一个新的独立空间,它可以操作所有符合作用域范围内的对象,以及定义新的变量类型,但是不能定义函数;
  2、为了正确理解,必须在循环后面添加花括号{}以代表独立空间的边界,并且以不同的缩进表达不同的空间;
  到这里,大概发现了一些共性,if-else和循环的理解里面,第1和2点几乎一样?if-else的第3和4都是针对它本身的,难道第1和2是公用的东西?不急,我们接着往下看;
在这里插入图片描述

1.3、函数的嵌套

  一个函数定义中又调用了另一个函数,称为函数嵌套。书中也给了一些例子:
在这里插入图片描述
  话不多说,我们直接套用if-else的部分理解内容:
  1、每一个函数定义后面,是一个新的独立空间,它可以操作所有符合作用域范围内的对象,以及定义新的变量类型,但是不能定义函数;
  2、为了正确理解,必须在函数定义后面添加花括号{}以代表独立空间的边界,并且以不同的缩进表达不同的空间;
  没错,居然也能直接套用,而且毫无PS痕迹,所以你还觉得书中讲不同的嵌套是每一个新的东西吗?它们其实是同一个东西;
在这里插入图片描述

2、忘记嵌套,做回自己

  小白理解其实没有所谓的嵌套,它只在不同层的独立空间中出现了相同或者相似的内容而已,如果只关注当前空间,那么什么分支结构、函数调用和循环都永远只有1个,学会”忘记“,能更好帮助你专注在某一层空间内,铭记下面的2条共性:

  1、每一个X后面,是一个新的独立空间,它可以操作所有符合作用域范围内的对象,以及定义新的变量类型,但是不能定义函数;
  2、为了正确理解,必须在X后面添加花括号{}以代表独立空间的边界,并且以不同的缩进表达不同的空间;

  其中X就是函数定义、循环和分支结构,他们都是可以创造新空间的语言结构,在新的空间里面,将又会是一个新的轮回,它依然可以出现和上一层空间相同的东西;
在这里插入图片描述

  以新的视角看一下这段代码,正常人是不会这样写的,而Flag这个名字重复出现在不同层的独立空间中,但是没有任何语法和语义的问题,只是存在理解问题:

void Func(void)
{
    uint8_t Flag = 0;
    
    if (Flag) {
        uint8_t Flag = 1;
        while (Flag) {
            static uint8_t Flag = 0;
            
            Flag++;
            if (Flag >= 100) {
                for(uint8_t Flag = 0; Flag <= 100; ++Flag) {
                }
                break;
            }
        }
    } else {
        for(uint8_t Flag = 0; Flag <= 100; ++Flag) {
            while (1) {
                static int8_t Flag = -100;
                
                Flag++;
                if (Flag >= 0) {
                    uint8_t Flag = 0;
                    
                    if (Flag) {
                        printf("Test 1\r\n");
                    } else {
                        printf("Test 0\r\n");
                    }
                    
                    break;
                }
            }
        }
    }
}

  • 22
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值