接着上一篇,继续讲述一下关键字,今天主要是void及const等

1 void a? void *p? 哪个正确?

void的字面意思是“空类型”,void *则为“空类型指针”,void *可以指向任何类型的数据。看下下面的例子

如果我们在程序中使用 void a 及void *p?  你觉得结果会是什么呢?

他会提示 void a这一行 执行 error C2182: 'a' : illegal use of type 'void' 但是 void *p确实没有问题的。

这是因为定义变量时候(是否记得声明与定义的区别,见上一篇)必须分配内存,而如果定义成空类型变量,那么他就是会不知道要分配多少了,但是定义了void *p 因为p是一个指针,是很明确的是4bytes,所以可以分配,只是现在的p还不知道他会指向哪块内存。所以不要妄想用void来定义变量。

void主要用来:(1) 对函数返回的限定;(2) 对函数参数的限定;(3)指针

下面一一道来

1.1 对函数返回值的限定——如果无返回值请一定加上void

试下下面的程序

add(int a,int b)

{

return a+b;

}

int main(int argc, char* argv[])

{

int a=2;

int b=3;

printf("%d\n",add(a,b));

//printf("%d\n",addReturnVoid(a,b));

return 0;

}发现最后会输出 5,所以在C语言中,凡不加返回值类型限定的函数,就会被编译器作为返回整型值处理而不是void。

如果你还不死心,如果认为他是void,那么上面的add函数就应该等价于 void add ,你把它加上后再试下会出现error C2562: 'addReturnVoid' : 'void' function returning a value

所以,为了避免混乱,如果函数不返回任何值,那么必须用void修饰

1.2 对参数的限定——如果某函数不需要参数,请将()内填入void

试下这个程序

int fun()

{

return 1;

}

int main(int argc, char* argv[])

{

printf("%d\n",fun(3));

return 0;

}在codeblocks中他会顺利的通过,打印出1.

所以如果函数没有参数,还是将void加上,这都是好习惯

1.3 空类型指针 void *p

首先说一下,尽管定义空类型变量不行,而空类型指针可以,但是空类型指针不能进行算法运算。

例如 void  *p;

p++; 或者p+=1

这样都是不行的,因为我们知道,对指针类型进行加1等操作,是移动到他指向的数据类型的下一个类型,例如是int 型,他就移动4个单位,所以对空类型进行运算,他根本就不知道他要移动多少。所以这是出错的。

我们知道,如果不同类型的变量要相互赋值或者进行运算,必须经过强制转换,例如

float *pf;

int *pi;

pf= pi;

这样是会出错的,只能是pf=(float*) pi ; 这样进行强制转换

但是void*则不同,他可以直接赋值;例如

float *pf;

int *pi; void *p;

p=pf;

.....

p=pi;

但要注意,其他类型的指针可以支付赋值给空类型指针。但是并不是说空类型指针可以赋值给任何类型的指针,例如

pf=p;

pi=p;

这都是出错的,可以自己体会下原因。

另外,如果函数的参数可以是任意类型指针,那么应声明其参数为void *。典型的如内存操作函数memcpy和memset的函数原型分别为:

void * memcpy(void *dest, const void *src, size_t len);

void * memset ( void * buffer, int c, size_t num );

以及像malloc这样的,而其返回类型也是void型的,所以我们平时都会在返回前进行强制类型转换 例如 int *p=(int *) malloc(100*sizeof(int))

2 const关键字——其实应该是readonly

首先,一定不能认为const修饰的是常量,注意他修饰的是变量,只是这个变量的值不能再修改,是叫只读变量。而常量在编译阶段可以被使用,但是只读变量在编译阶段是不能被使用的,因为编译器还不知道这个变量是什么内容。

例如 const int MAX=10;

int a[MAX];

有些编译器会出错,因为我们在定义数组时候必须指定数组的大小,所以这也放映出const修饰的是变量,而不是常量

而const推出的初始目的,正是为了取代预编译指令,消除它的缺点,同时继承它的优点。

const是怎样消除#define缺点,继承优点?

节省空间,避免不必要的内存分配,同时提高效率.

编译器通常不为普通const变量分配存储空间,而是将他们保存在符号表中,这使得他成为编译期间的值,但没有存储与读内存的操作,使得他效率很高。

cosnt  定义的只读变量从汇编角度上来看,只是给出了对应的内存的地址,而不是像#define那样给处于了立即数,所以,const定义的只读变量在程序运行过程中只有一份拷贝,而#define定义的宏常量在内存中有若干个拷贝,#define宏在预编译阶段进行替换,而const修饰的只读变量是在编译时候确定其值,#define没有类型,而const修饰的只读变量有确定的数据类型

const修饰一般变量或数组

这种只读变量变量在定义时候,修饰符const可以用在类型说明符前,也可以用在类型说明符后,例如:

int consti= 2  或 const int i=2;都是一样

定义或说明一个只读数组可以如下:

int const a[5]={0}或者 const int a[5]={0};

const修饰指针

很多时候我们在被考察到cosnt修饰的究竟是指针不变还是指向的数据不变时候总是很迷糊,其实我们可以先忽略类型名,然后看const离谁最近就是修饰谁

const int *p //将int 去掉,const *p,可知const修饰的是*p,而不是指针变量p,所以是p可变,p指向的对象不可变

int const *p //同样, cosnt *p,与上面一致,p可变,p指向的对象不可变

int *const p  //去掉int  成* const p 所以是p指针不变,p指向的对象可变

const int *const p //去掉int 成了 const * const p.所以是p指针不变,p指向的对象也不变

const修饰函数的参数或者函数的返回值

const修饰符可以修饰函数的参数,当不希望这个参数在函数体中被意外修改时候,则可以用const修饰,例如 void fun(const int i);

同样如果希望函数的返回值不被改变,则可以用const修饰函数的返回值, const int fun(void);

而在另一个链接文件中引用const只读变量时候,用 extern const int i;注意这么是声明而不是定义哦

c语言 error c2562,C语言之关键字(二) void,const相关推荐

  1. c语言error和,C语言ERROR精选.doc

    C语言ERROR精选 Ambiguous operators need parentheses ) ~. [1 L: f& a/ J不明确的运算需要用括号括起 # n5 J! G' c( m: ...

  2. c语言 error 9,C语言求助(_) c:9: error: syntax error before '[' token

    满意答案 dvii6347 2014.04.26 采纳率:44%    等级:6 已帮助:109人 大概看一下,,,程序要干嘛,有几处错误给你指出了.不懂再追问~ #include int Weigh ...

  3. c语言getchar用法_C语言 — 关键字

    几十个关键字不多,用得多了自然会记住,相信大家也不会担心.下面是C语言中的 32 个关键字: 一丶C语言关键字 第一个关键字:auto 用来声明自动变量.可以显式的声明变量为自动变量.只要不是声明在所 ...

  4. c语言自定义关键词,C语言关键字详解

    相对于其他语言来说,C语言的关键字算是少的了.在C98中关键子总共只有32个,我们来分析一下每个关键字在C语言中它独特的作用. 1.关于数据类型的关键字 (1) char :声明字符型变量或函数 (2 ...

  5. C语言 error C4996: This function or variable may be unsafe - C语言零基础入门教程

    目录 一.error C4996 简介 二.error C4996 解决办法 1.采用_s 结尾的安全版本 2.去掉 visual studio "安全开发生命周期(SDL)检查" ...

  6. 【C语言重点难点精讲】关键字精讲

    必读: C语言关键字是一个非常重要的话题,因为它能在相当的程度上将C语言的核心内容串联起来,起到一种提纲挈领的效果 下面的内容重点提及的是相应关键字特别值得注意的地方,这些地方是我们经常忽略的,而且考 ...

  7. C语言深度解剖读书笔记(1.关键字的秘密)

    开始本节学习笔记之前,先说几句题外话.其实对于C语言深度解剖这本书来说,看完了有一段时间了,一直没有时间来写这篇博客.正巧还刚刚看完了国嵌唐老师的C语言视频,觉得两者是异曲同工,所以就把两者一起记录下 ...

  8. c语言error2228,c语言error C2228: left of '.tag' must have class/struct/union type

    c语言error C2228: left of '.tag' must have class/struct/union type0 #include #include #include #define ...

  9. R语言 Error in file(file, “rt“) : 无法打开链结

    R语言 Error in file(file, "rt") : 无法打开链结 此外: Warning message: In file(file, "rt") ...

  10. C语言 ERROR C2040 ' ' differs in levels of indirection from ' '

    C语言 ERROR C2040 ' ' differs in levels of indirection from  '  ' 出现这个错误,原因极有可能为函数或者变量的使用在定义之前 解决方法为 在 ...

最新文章

  1. sources root pycharm 怎么设置_使用python语言开发ROOT之搭建环境方法探索
  2. 只要60页!牛逼不行的Python数据分析入门知识手册
  3. qpython3安装kivy_kivy库的安装
  4. centos安装nginx步骤
  5. ssh excel 导入 mysql_ssh poi解析excel并将数据存入数据库
  6. 虚拟局域网软件开源_ZeroTier虚拟局域网免费远程桌面体验--替代TeamViewer
  7. EF批量插入太慢?那是你的姿势不对
  8. 57javabean简介
  9. OpenGl绘制螺旋线
  10. 《Android游戏开发详解》——第2章,第2.10节使用对象
  11. 30分钟快速上手Docker,看这篇就对了!
  12. (包含每张图片的3DMM系数,可以直接重建出3D人脸)AFLW2000-3D数据库介绍及自带代码使用
  13. magisk卸载内置软件_手机发烧友必备之 Magisk
  14. matlab psf点扩散函数,什么是点扩散函数PSF?-ZEMAX,OpticStudio-光行天下-国内光电行业门户-光学,光电,光机技术及其软件运用专业网站!...
  15. 100+篇论文合集:GNN在NLP中的应用
  16. 最新WIFI分销大师小程序源码+带后端/亲测可用
  17. 初学Python之fractions模块下Fraction使用方法
  18. Scrapy框架 - 学习日记2
  19. 7. GC 调优(实战篇) - GC参考手册
  20. 到处都是“公馆”,中国小区命名为何如此“没文化”?

热门文章

  1. 《快播》仿网易云音乐UI,在线视频,在线图片的开源项目
  2. 2022:中国存储的生死时速
  3. 前端-回到顶部效果总结
  4. 制作纯DOS启动U盘
  5. C语言EasyX详解(小球碰撞)
  6. Android11(RK3568)自定义服务制作(3)-Hardware制作和权限管理
  7. 贾维斯雨滴桌面(素材跟教程都有)
  8. 下载指定版本的NDK
  9. selenium2 原理和常用api
  10. 剑指offer-刷题总结