C语言关键字解析

2023-11-06

在C语言中有32个关键字,如下表所示:
这里写图片描述
释:
(1)声明:
1)告诉编译器,这个名字已经匹配到一块内存上;
2)告诉编译器,这个名字已经预定了,其他地方再也不能用它来作为变量名或对象名。
(2)定义:
编译器创建一个对象,为这个对象分配一块内存空间,并给它取上名字,这个名字就是我们经常所说的变量名或者对象名。
(3)声明和定义的区别:
1)声明可以出现多次,但是定义只能一次。
2)定义创建了对象,并为对象分配内存,但是声明只是匹配了一块内存,并没有分配内存。

为了方便记忆,将关键字分成几类:
第一类,有关数据“模子”的关键字:void、char、short、int、long、float、double、sizeof;
第二类,有关数据符号的关键字:signed、unsigned;
第三类,构造类型:struct、union、enum、typedef;
第四类,有关存储与生命周期的类型:auto、static、extern、register、const、volatile;
第五类,有关语句的类型:if、else、for、while、do、switch、case、fault、goto、break、continue、return

以下,将主要介绍sizeof、typedef、register、signed和unsigned、volatile、static等关键字。

1、register——最快的关键字
(1)说明:这个关键字请求编译器尽可能的将变量存放在CPU内部的寄存器中,而不是通过内存寻址访问以提高效率(是尽可能,不是绝对)。
(2)解释:寄存器其实就是一块一块小的存储空间,只不过其存储速度比内存快得多,但是价格昂贵。
(3)注意:
1)register变量必须是一个单个的值,并且其长度必须小于或等于整形的长度。
2)register变量可能不存在内存中,所以不能用取地址运算符“&”来获取register变量的地址。

2、static——最名不符实的关键字
(1)说明:声明静态变量。
(2)作用:
1)修饰变量:static可以修饰局部变量和全局变量,它们都存放在内部的静态区中。
A、静态全局变量:作用域仅限于变量被定义的文件中,其他文件即使使用extern声明也不能使用它。准确的说:作用域是从定义之处开始到文件结束。在定义之处前面的那些代码行也不能使用它,想要使用就得在前面再加extern***。
B、静态局部变量:作用域仅限于该函数里,该文件中的其他函数也用不了。虽然局部变量的生命周期随着函数的结束而终止,但是因为被static修饰的变量总是存在内存的静态区,所以即使这个函数运行结束,这个静态变量的值也不会被销毁,函数下次使用时仍然能用到这个值。
【例1】

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>

static int i = 0;

void func1()
{
	i = 0;
	i++;
}

void func2()
{
	static int j = 0;
	j++;
}

int main()
{
	int k = 0;
	for (k = 0; k < 10; k++)
	{
		func1();
		func2();
	}
	system("pause");
	return 0;
}

运行结果:
在这里插入图片描述

释:
a、每次调用func1函数时,i(静态全局变量)都被强制置0, 所以i等于1。
b、虽然调用func2函数10次,但是“static int j = 0”语句只被执行了一次,所以j等于10。

2)修饰函数:函数前面加static使得函数成为静态函数,表示该函数的作用域仅限于本文件。好处是:不同的人编写不同函数时不用担心自己定义的函数是否会与其他文件中的函数同名。

3、符号关键字——unsigned和signed
(1)说明:最高位如果是1,表明这个数是负数,其值为除最高位以外的剩余位的值加上“-”号;最高位如果是0,表明这个数是正数,其值为除最高位以外的剩余位的值。
【例2】signed char
0000 0001表示1;1000 0001表示-1。
8位的char类型数,其值表示的范围为:-27—(27-1)。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main()
{
	signed char a[1000];
	int i;
	for (i = 0; i < 1000; i++)
	{
		a[i] = -1 - i;
	}
	printf("% d\n", strlen(a));
	system("pause");
	return 0;
}

答案是:255。
释:计算机系统中,数值以补码的方式来存储。因为用补码可以将符号位和其他位统一处理,并且减法和加法都可以用补码来处理,当最高位(符号位)有进位时,进位将被舍弃。并且,strlen遇“\0”则终止。

注意:单纯的char类型应该只用于字符值得存储和使用;有符号和无符号的char类型变量只能用于数值的存储和使用。

4、const
(1)说明:const是constant的缩写,表示恒古不变。被const修饰的变量称为常变量,准确来说应该是只读的变量。
(2)作用:
1)修饰只读变量:定义const只读变量,具有不可变性。
A、const int Max = 100;
释:const修饰的只读变量必须在定义的同时初始化,因为定义后就不能再被改变了。
B、int Array[Max];
释:这样编译时会报错,数组下标只能是常量,即使常变量也不可以,但是宏常数可以。
【问题1】case语句修饰的只读变量必须在定义的同时初始化,为什么?
答:因为case后面只能是常量、字符型常量和常量表达式。
2)修饰数组
3)修饰指针
【例3】p可变,p指向的对象不可变

int const *p;//p可变,p指向的对象不可变
int* const p;//p不可变,p指向的对象可变
const int* const p;//p不可变,p指向的对象也不可变

4)修饰函数的参数和返回值

5、volatile—最易变的关键字
(1)说明:volatile是易变、不稳定的意思。
(2)作用:用volatile修饰的变量可以被某些编译器未知的因素更改,即更新数据,未知的因素如操作系统、硬件或者其他线程等。
【例4】
int i = 10;
int j = i;//1)语句
int k = i;//2)语句
分析:编译时编译器认为i的值没有发生变化,所以在1)语句时从内存中取出i的值赋给j后并没有被丢掉,在2)语句时继续用这个值给k赋值,而不生成汇编代码重新从内存里取出i的值。

【例5】
volatlie int i = 10;
int j = i;
int k = i;
分析:例2与例1不同的是,volatile关键字告诉编译器,i的值随时可能发生变化,则每次用i,编译器都会生成汇编代码从内存中取i的值。

【问题2】const volatile int i = 10;这行代码有没有问题?如果没有,那么i到底是什么属性?
答:没有问题。因为const表示常量语义,被const修饰的对象在所在的作用域里无法进行修改;volatile表示易变的,即在运行期对象可能在当前程序上下文的控制流以外被修改。发生易变的情况,如:在多线程中。被其他线程修改;对象所在的存储器可能被多个硬件设备随机修改等情况。例如,只读的状态寄存器,它是volatile属性,因为它可能被意外的修改。但是,同时它也具有const属性,因为它修饰的内容只能被读而不能被写。可知:它们控制的范围不同,被const修饰的对象在程序本身内不能修改,而被volatile修饰的对象可能在本程序外被修改。所以,const和volatile一起使用没有问题。

6、sizeof——最冤枉的关键字
(1)说明:sizeof是关键字不是函数,用于计算对象的所占的内存大小。
【例6】sizeof是关键字不是函数
int i = 0;
(A)sizeof(int); (B)sizeof(i); (C)sizeof int; (D)sizeof i;
结果是:在32位系统下,A、B、D的值都为4,而C编译出错。
释:sizeof是关键字,带不带括号都可以,但是在int前面可以加unsigned和signed,不可以加sizeof。

【例7】计算以形参传递整个数组时的大小

int b[100];
void fun(int b[100])
{
sizeof(b);
}

结果是:sizeof(b)等于4,即一个元素的大小。
释:数组当形参时,不能将整个数组传值,只能传单个元素。

【例7】有关数组和指针占内存空间大小的计算
1)int *p = NULL;
sizeof§的值是什么?sizeof(*p)的值又是多少?
答:都是4个字节。
2)int a[100];
sizeof(a)的值是多少?//400
sizeof(a[100])呢?//4,因为sizeof只计算,不访问
sizeof(&a)呢?//4
sizeof(&a[0])呢?//4

更多关于sizeof的计算,请访问博客——“计算对象所占的内存大小

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言关键字解析 的相关文章

  • 有没有办法分析 WCF 应用程序的性能?

    我们正在尝试测量我们的系统的性能 该系统是一个使用 WCF 调用的 NET 3 5 应用程序 问题是到目前为止 我们无法分析这些调用中的方法 编写了一个 winforms 客户端应用程序来测试我们的系统 我们尝试使用ANTS 4 Profi
  • 将数据集导出到 EXCEL

    我使用以下代码将数据库表中的字段导出到 Excel 中 我想要做的是能够编写一条 SQL 语句从多个表中检索字段并将其导出到 Excel 中 这段代码只允许我导出一张表 另外 如何显示保存提示对话框 示例代码将不胜感激 非常感谢 prote
  • 将数组从 C# 编组到 C++ 并返回:PInvokeStackImbalance

    我有一个 C 函数 我想从 C 访问它 问题是我不断收到 PInvokeStackImbalance 异常 但我不知道为什么 当检查异常被关闭时 一切都运行良好并且符合预期 我的 C 函数的签名是 extern C double solve
  • VBA 中的 VSTO:AddIn.Object 有时不返回任何内容 (null)

    Given VSTO 插件 An override object RequestComAddInAutomationService 它返回一个名为的类的实例Facade在我的场景中 Excel 2007 中的 VBA 宏可访问AddIn O
  • 多个源文件中包含包含“const”的头文件

    Why does not包含定义的头文件const并被多个源文件包含会产生编译错误multiple definition const in header file h const int num 5 int x Error Multiple
  • 无法使用 ASP.NET Core 从 JWT 令牌获取声明

    我正在尝试使用 ASP NET Core 实现 JWT 持有者身份验证的非常简单的实现 我从控制器返回的响应有点像这样 var identity new ClaimsIdentity identity AddClaim new Claim
  • c++11 中的 std::thread 问题

    我在尝试从标准模板库编译具有多线程的程序时遇到一些麻烦 当我尝试编译以下程序时 它返回一个晦涩的错误 include
  • c#Registry to XML无效字符问题

    我在尝试从注册表创建 XML 文件时遇到问题 在我的笔记本电脑 W7 64b 上它工作正常 生成了 xml 文件 但在另一台计算机 Xp 32b 上抛出异常 System ArgumentException 十六进制值 0x00 是无效字符
  • 是否可以用 C# 为 Android 编写应用程序?

    我们都知道Android运行Dalvik VM程序 通常开发人员用 Java 编写程序并将其编译为 Dalvik 字节码 我想知道是否有可能创建一个可以接受 C 代码并将其编译为 Dalvik 字节码的编译器 嗯 这是一种选择 或者您可以在
  • 使用经度和纬度查找给定距离内的所有附近客户

    我有一个包含客户经度和纬度的数据库 我有一个搜索表单 用户将在其中输入日志 纬度 距离下拉列表包含 50 英里 100 英里 当用户单击搜索时 我想编写一个 linq 查询从数据库中获取此距离半径内的所有客户 如何使用 C 和 linq 来
  • NHibernate 中具有不同类型答案的问题

    我正在尝试找到一个问卷问题的简洁解决方案 假设我有一个Questionnaire类有一个集合Answers e g public class Questionnaire public virtual ISet
  • 我可以在C中直接比较int和size_t吗?

    我可以比较一个int and a size t像这样的变量 int i 1 size t y 2 if i y Do something 或者我必须输入其中之一 只要满足以下条件 它就是安全的int为零或正数 如果它是负数 并且size t
  • gcc 中的“假设”子句

    gcc 最新版本 4 8 4 9 是否有类似于以下的 假设 子句 assume 内置icc支持吗 例如 assume n 8 0 从 gcc 4 8 2 开始 gcc 中没有 assume 的等效项 我不知道为什么 这会非常有用 马夫索建议
  • 如何从标准输入读取一行,阻塞直到找到换行符?

    我试图从命令行的标准输入一次读取任意长度的一行 我不确定是否能够包含 GNU readline 并且更喜欢使用库函数 我读过的文档表明getline应该可以工作 但在我的实验中它不会阻塞 我的示例程序 include
  • 什么是多重重继承?

    我将以下称为 多重重新继承 直接继承一个类一次 并通过继承其一个或多个后代来间接继承一次或多次 通过继承一个类的两个或多个后代来间接继承一个类两次或多次 我想知道它是否存在以及如何明确访问嵌入的子对象 1 Professional C 2n
  • 使用 LINQ to SQL 的 .NET 架构的最佳设计实践(DAL 必要吗?我们真的可以使用 POCO吗?要采用的设计模式吗?)

    我避免在 net arch n 层架构上编写看起来像是另一个线程的内容 但请耐心等待 希望我和其他人一样 在选择用于企业应用程序的架构时 考虑到当今的趋势和新兴技术 仍然没有 100 满意或不清楚应采取的最佳方法 我想我正在寻求大众社区对方
  • jquery ajax“发布”调用

    我是 jQuery 和 Ajax 的新手 并且在 发布 方面遇到问题 我正在使用 jQuery Ajax post 调用将数据保存到数据库 当我尝试保存数据时 它将 null 传递给我的 C 方法 jQuery 看起来像这样 functio
  • 为什么C#不支持多重继承? [复制]

    这个问题在这里已经有答案了 可能的重复 C 应该包含多重继承吗 https stackoverflow com questions 191691 should c include multiple inheritance 为什么C 不支持多
  • 为了清楚起见,是否应该在返回类型上使用无用的类型限定符?

    当我们的头文件中有原型时 我们的静态分析工具会抱怨 返回类型上有无用的类型限定符 例如 const int foo 我们这样定义它是因为该函数返回一个永远不会改变的常量 认为 API 看起来更清晰const到位 为了清楚起见 我觉得这类似于
  • 如何并排显示 4 个三角形图案

    我无法让 4 个不同的三角形图案并排出现 这是一个控制台应用程序 这正是我试图通过使用嵌套 for 循环来实现的目标

随机推荐

  • 深入理解Android之Gradle

    转自 http blog csdn net innost article details 48228651 深入理解Android之Gradle 格式更加精美的PDF版请到 https pan baidu com s 1boG2cLD下载
  • SQL语句中的循环

    SQL语句中的循环 SQL语句中的循环类似于foreach循环 可以循环遍历某个表并进行新增 修改和删除的操作 SQL语句中的循环 使用SQL的游标来实现 上示例 declare ID int 声明变量 名称 类型 begin 开始 pri
  • setFocus不能生效的问题

    focusInEvent只有在对象显示出来的情况下设定setFocus才可以触发 这一点help手册里有说明 转一篇文章如下 http blog csdn net alex201030273437 article details 81937
  • CSV简单了解

    1 CSV介绍 CSV全称是Comma Separate Values 这种文件格式可以作为不同程序之间的数据交互的格式 csv就是一种纯文本文件 如 txt doc等 即是一组字符序列 字符之间已英文字符的逗号或制表符 Tab 分隔 语法
  • Python数据结构-----leetcode232.用栈实现队列

    目录 前言 方法讲解 示例 代码实现 232 用栈实现队列 前言 我们都知道队列的特征是先进先出 就跟排队一样先到先得 而栈的特征是后进后出 那这里我们怎么去通过两个栈来实现一个队列的功能呢 这一期我们一起来学习吧 方法讲解 这里需要准备好
  • 订单业务中的重要问题:超卖问题的解决方案

    订单业务中的重要问题 超卖问题的解决方案 我在做过的一些项目中都涉及到了订单的业务 如果你的项目中有关于订单的业务模块 那肯定说明你的项目中有卖商品的功能 所以有买卖场景就面临一个很常见的一个问题 那就是超卖问题 下面我就整理一下我在做项目
  • MyBatis与JDBC连接数据库所使用的url之间的差异

    1 在JDBC连接里是这样的 连接无误 2 在Mybatis里配置要这样 3 主要区别 说明 JDBC 方式连接 MySQL 不需要对 进行转义 而在Mybatis里要求一定要对 转义 4 如果是在properties文件里 不用转义的 在
  • IP静态路由实验报告

    一 将192 168 1 0 24划分为4个网段 192 168 1 0 26 192 168 1 64 26 192 168 1 128 26 192 168 1 192 26 1 取192 168 1 0 26继续划分 为主干道添加IP
  • Spring 加载、解析applicationContext.xml 流程

    概要 Spring 框架使用了BeanFactory 进行加载 xml 和生成 bean 实例 下面我们分析下Spring加载xml文件的过程 spring 版本是最新的 4 3 9 release 版本 示例 XmlBeanFactory
  • java 转换tif图片为jpg,解决转换后颜色异常问题

    java 转换tif图片为jpg 解决转换后颜色异常问题 说明 正常情况下 tif转换jpg图片会出现颜色失真 丢失部分颜色 原因是两种图片的色彩模式不同 jpg默认使用的是RGB色彩模式 TIF默认使用的是CMYK色彩模式 RGB的色域比
  • 有关“ModuleNotFoundError: No module named ‘flask._compat’”错误的解决过程

    在进行flask安装后 运行程序的过程中出现了 ModuleNotFoundError No module named flask compat 的错误 在查询了多个网站后给出了不同的答案 其报错原因是flask版本过高导致无法识别该语法
  • 仿京东 项目笔记2(注册登录)

    这里写目录标题 1 注册页面 1 1 注册 登录页面 接口请求 1 2 Vue开发中Element UI的样式穿透 1 2 1 v deep的使用 1 2 2 elementUI Dialog内容区域显示滚动条 1 3 注册页面 步骤条和表
  • 服务器i5 和e系列,e5和i5有什么区别

    两个系列的处理器主要在设计规格和面向范围方面存在区别 设计规格上 前者核心数更多 多线程能力更强 但睿频能力相对较弱 后者核心数较少 多线程能力不如前者 但睿频能力更强 面向范围上 前者主要面向服务器 嵌入式等企业设备 后者主要面向消费级硬
  • (LeetCode)全排列

    目录 题目要求 题目理解以及思路分析 代码分部讲解 第一部分 第二部分 题目要求 给定一个不含重复数字的数组 nums 返回其 所有可能的全排列 你可以 按任意顺序 返回答案 示例 1 输入 nums 1 2 3 输出 1 2 3 1 3
  • 规则引擎Drools使用 第十一篇 Drools 的高级语法之LHS增强

    前面我们已经知道了在规则体中的LHS部分是介于when和then之间的部分 主要用于模式匹配 只有匹配结果为true时 才会触发RHS部分的执行 下面我们会针对LHS部分学习几个新的用法 目录 复合值限制in not in 条件元素eval
  • 升压电路(BOOST)与降压电路(BUCK)

    一 电路中产生电流的条件是 1 电路里必须有电源供电 2 电路必须形成闭合回路 降压元器件 升降压电路构成的核心元器件 1 电感 储存能量 电感是无法突变的 工作状态是线性的 2 二极管 3 mos管 首先先分清楚mos是N mos还是P
  • Qt全局宏和变量

    1 Qt 全局宏定义 Qt版本号 QT VERSION major lt lt 16 minor lt lt 8 patch 检测版本号 QT VERSION CHECK major minor patch major lt lt 16 m
  • virtio代码分析(一)-qemu部分

    virtio内容众多 代码分布于qemu linux dpdk等中 而且分为frontend和backend 可以运行于userspace也可以运行于kernelspace 极其难以理解 不看代码只看原理性文档往往流于表面 只有真正看懂了代
  • 大数据准备——安装JDK

    1 解压Linux版本的JDK压缩包 命令行敲入 mkdir home software cd home software rz 上传jdk tar包 这里添加自己tar包的名字 如果rz命令不能使用 先执行yum install lrzs
  • C语言关键字解析

    在C语言中有32个关键字 如下表所示 释 1 声明 1 告诉编译器 这个名字已经匹配到一块内存上 2 告诉编译器 这个名字已经预定了 其他地方再也不能用它来作为变量名或对象名 2 定义 编译器创建一个对象 为这个对象分配一块内存空间 并给它