遭人遗弃的goto:

  • 高手潜规则:禁止使用goto
  • 项目经验:程序质量与goto的出现次数成反比
  • 最后的判决:将goto打入冷宫

程序示例1:(goto副作用分析)

 #include <stdio.h>
#include <malloc.h> void func(int n)
{
int* p = NULL; if( n < )
{
goto STATUS;
} p = (int*)malloc(sizeof(int) * n); STATUS:
p[] = n; free(p);
} int main()
{
printf("begin...\n"); printf("func(1)\n"); func(); printf("func(-1)\n"); func(-); printf("end...\n"); return ;
}

在函数中,从第8行到第16行本来是顺序执行的,可是当满组if条件的时候,就会破环这个程序原来的结构,导致出现错误。

goto语句就介绍到这里,下面来讲一下void:

void修饰函数返回值和参数:

  • 如果函数没有返回值,那么就应该将其声明为void
  • 如果函数没有参数,应该声明其参数为void

程序示例2:

 #include<stdio.h>

 f()
{ } int main()
{
int i= f(,,,);
printf("%d\n",i);
return ;
}

上面这段程序,可能会有人认为它在编译的时候会报错,其实不然:

  • 当函数没有返回值的时候,会默认返回一个int类型,也就是说你可以在这个函数里面加上一条return用于返回一个int语句,但是如果你不加的话,编译器会默认给你返回一个1。
  • 当函数的参数列表没有任何参数,且没有声明为void,默认可以接受任意多个参数

为什莫会这样呢,因为C语言不是一种强类型的语言。

程序示例3:

#include<stdio.h>

 void f(void)
{
return ;
} int main()
{
int i= f(,,,);//error
printf("%d\n",i);
return ;
}

这段代码是将示例2中的代码稍加修改得到的,现在这段代码是不可以通过编译的。

  void的意义,有人想到,void既然是一种类型,那么我们是否可以像使用其他类型,比如说int,char 一样的使用它来创建变量呢?答案是否定的,你可以将void理解为一种抽象类型。

  不存在void普通变量(指针变量例外),C语言中没有定义void究竟是多大内存的别名,也就是说没有void标尺,无法在内存中裁剪出void对应的变量。

小贴士:

ANSIC:标准C语言规范

扩展C:在ANSIC的基础上进行了扩充

程序示例4:

 #include<stdio.h>

 int main()
{
printf("%d\n",sizeof(void));
return ;
}

上面这段代码在ANSIC编译器中无法通过编译,但是对于支持GNU标准的额gcc编译器而言是合法的。(但是我们最好是按照C语言标准来学习C语言,所以我们可以认为上面这段代码是不合法的,有的编译器生产厂家认为标准C的特性不够,是自己加上去的)

void虽然不能定义普通的变量,但是可以创建指针变量:

  • C语言规定只有相同类型的指针才可以相互赋值
  • void *  指针作为左值用于 “接受” 任意类型的指针
  • void* 指针作为右值使用时需要进行强制类型转换

程序示例5:

 #include<stdio.h>
#include<stdlib.h>
int main()
{
int *pi = (int *) malloc(sizeof(int));
char *pc = (char *)malloc(sizeof(char));
void *p=NULL;
int *pni=NULL;
char * pnc=NULL; p=pi; //ok
pni =p; //error p=pc; //ok
pnc = p; //error return ;
}

在标准C语言中12 和 15 行会报错,但是有的编译器会扩展C语言规范,所以上述代码在你的编译器中有可能时通过的。

程序示例6:

#include <stdio.h>

void MemSet(void* src, int length, unsigned char n)
{
unsigned char* p = (unsigned char*)src; int i = ; for(i=; i<length; i++)
{
p[i] = n;
}
} int main()
{
int a[];
int i = ; MemSet(a, sizeof(a), ); for(i=; i<; i++)
{
printf("%d\n", a[i]);
} return ;
}

MeMset这个函数用void类型的指针接受一个int(也可以接受其他类型的指针),然后将其强制转化为unsigned char 类型的指针,将其每个字节都设置为0,最后在主函数会输出 5 个0,因为每一个字节都被设置为0,所以四个为0的字节组合的一个int类型的值也是0,你也可以将他的每个自己设置为其他的数。

小结:

  • 现代软件工程中禁止使用goto语句
  • void是一种抽象类型的数据类型
  • void类型不能用于定义变量
  • void类型用于声明函数的无参数
  • void类型用于用于声明函数的无返回值
  • 可以定义void* 类型的指针
  • void* 类型的子真可以接受任意类型的指针值

C语言进阶——goto 和 void 的分析08的更多相关文章

  1. C语言进阶_goto与void解析

    世间真正温煦的春色,都熨帖者大地,潜伏在深谷. 一.简介 goto与void是两个不常用的关键字,C语言中的Goto关键字传承字汇编语言,使用方法也与汇编语言相同.void是类型关键字,可修饰函数和变 ...

  2. 《C语言进阶剖析》课程目录

    <C语言进阶剖析>学习笔记                                                         本文总结自狄泰软件学院唐佐林老师的<C语言 ...

  3. 【R笔记】R语言进阶之4:数据整形(reshape)

    R语言进阶之4:数据整形(reshape) 2013-05-31 10:15 xxx 网易博客 字号:T | T 从不同途径得到的数据的组织方式是多种多样的,很多数据都要经过整理才能进行有效的分析,数 ...

  4. R语言入门级实例——用igragh包分析社群

    R语言入门级实例——用igragh包分析社群 引入—— 本文的主要目的是初步实现R的igraph包的基础功能,包括绘制关系网络图(social relationship).利用算法进行社群发现(com ...

  5. 彩虹女神跃长空,Go语言进阶之Go语言高性能Web框架Iris项目实战-项目入口与路由EP01

    书接上回,我们已经安装好Iris框架,并且构建好了Iris项目,同时配置了fresh自动监控项目的实时编译,万事俱备,只欠东风,彩虹女神蓄势待发.现在我们来看看Iris的基础功能,如何编写项目入口文件 ...

  6. 第8课 goto 和 void 分析

    1. 遭人遗弃的goto (1)高手潜规则:禁用goto (2)项目经验:程序质量与goto出现的次数成反比 (3)最后的判决:将goto打入冷宫(1)循环语句的基本工作方式 [实例分析]goto副作 ...

  7. 第8课 goto和void分析

    遭人遗弃的goto: C语言是一种面向过程的结构化语言,其中主要结构有三种,顺序执行.选择执行.循环执行.再复杂的程序也是由这三种结构组合而成的. goto破坏了结构化特性,使程序以第四种方式执行,结 ...

  8. C语言进阶——enum, sizeof, typedef 分析11

    枚举类型的使用方法: enum是C语言的 一种自定义类型 enum值是可以根据需要自定义的整型值 第一个enum的值默认为0 默认情况下的enum值是在前一个定义值的基础上加 1 enum类型的变量只 ...

  9. C语言进阶—— 逻辑运算符分析15

    印象中的逻辑运算符: ---学生:老师,在我的印象中,逻辑运算符用在条件判断的时候,真挺简单的,还有必要深究吗? ---老师:逻辑运算符确实在条件判断的时候用的比较多,但是并不能说简单... 请思考下 ...

随机推荐

  1. intellijidea课程 intellijidea神器使用技巧2-1 无处不在的跳转

    idea快捷键(基于windows平台) 1 书签跳转 Ctrl alt [ ]   ==> 项目之间的跳转 Ctrl shift E ==> 文件之间的跳转(最近编辑的文件) Ctrl ...

  2. Django Rest Framework进阶一

    一.认证 认证请求头 #!/usr/bin/env python # -*- coding:utf-8 -*- from rest_framework.views import APIView fro ...

  3. 1064. 计算斐波那契第n项 通项公式

    题目描述 输入n,编写程序输出斐波那契数列的第n项.其中斐波那契数列f(n)的定义如下: f(1)=0,f(2)=1         f(n)=f(n-1)+f(n-2)(n>=2) 输入 一行 ...

  4. ansible软件相关模块丶计划任务,剧本

    软件相关模块 yum rpm 和yum 的区别 rpm:redhat package manager yum可以解决依赖关系 yum 源配置 [epel] name=Extra Packages fo ...

  5. mui打包vue项目

    1,新建app项目,打包vue,修改config/index.js的输出路径 2,把build打包后的dist目录下的文件拷到app目录下 3.修改app下面的index文件,改变压缩格式,修改“/s ...

  6. springboot 修改和设置 banner

    springboot 修改和设置 banner 先上图 修改步骤 1.在src/main/resources下新建一个banner.txt文档 2.通过http://patorjk.com/softw ...

  7. php程序员发展建议

    2017PHP程序员的进阶之路 又是一年毕业季,可能会有好多毕业生即将进入开发这个圈子,踏上码农这个不归路.根据这些年在开发圈子总结的LNMP程序猿发展轨迹,结合个人经验体会,总结出很多程序员对未来的 ...

  8. thinkphp的find()方法获取结果

    find方法返回的是一行记录,结果是一个数组,数组的key和sql中的field相对应,假设: $res=$model->find(filed="a,b,c"); 获取结果中 ...

  9. python数组列表、字典、拷贝、字符串

    python中字符串方法 name = "I teased at life as if it were a foolish game" print(name.capitalize( ...

  10. iis 7 操作 .net

    下面说一下.NET对IIS7操作.IIS7的操作和IIS5/6(using system.DirectoryServices;使用类DirectoryEntry )有很大的不同,在IIS7里增加了 M ...