当前位置: 首页 > news >正文

【深入理解C语言】-- 关键字2

在这里插入图片描述

🐇

🔥博客主页: 云曦
📋系列专栏:深入理解C语言

💨吾生也有涯,而知也无涯
💛 感谢大家👍点赞 😋关注📝评论

文章目录

  • 前言
  • 一、关键字 - static
    • 📙1.1 修饰变量
      • 📝1.1.1 修饰局部变量
      • 📝1.1.2 修饰全局变量
    • 📙1.2 修饰函数
    • 📙1.3static总结
  • 二、关键字 - sizeof
    • 📙2.1 基本数据类型
    • 2.2 📙数据类型与"模子"
      • 📝2.2.1 C常见的内置类型
      • 📝2.2.2 如何看待数据类型
    • 2.3 📙变量的命名规则
      • 📝规则1
      • 📝规则2
      • 📝规则3
      • 📝规则4
      • 📝规则5
      • 📝规则6
      • 📝规则7
      • 📝规则8
      • 📝规则9
      • 📝规则10
    • 📙2.4 sizeof的理解
    • 📙2.5 sizeof的总结
  • 三、signed、unsigned关键字
    • 📙3.1 原反补
    • 📙3.2 二进制十进制快速转换口诀
    • 📙3.3 变量的存入和取出
    • 📙3.4 大小端
    • 📙3.5 深入理解变量的存入和取出
    • 📙3.6 为什么存储的都是补码
    • 📙3.7 数据类型的取值范围

前言

在上期我们学习了两个关键字,本期将继续深入理解另外的关键字。

一、关键字 - static

📙1.1 修饰变量

📝1.1.1 修饰局部变量

//i是局部变量,具有局域临时性
//函数调用开辟空间并初始化
//函数结束释放空间
void fun()
{//static修饰后改变了i的生命周期//但没有改变i的作用域static int i = 0;i++;printf("%d\n", i);
}int main()
{int i = 0;for (i = 0; i < 10; i++){fun();}return 0;
}

static修饰局部变量,更改局部变量的生命周期(临时变量->全局生命周期,但作用域不变)
在这里插入图片描述

📝1.1.2 修饰全局变量

  • test.c
#include"test.h"static int g_val = 100;void fun()
{printf("hello world!\n");
}
  • test.h
#include<stdio.h>extern g_val;
extern void fun();
  • main.c
#include"test.h"int main()
{printf("%d\n", g_val);fun();return 0;
}

static修饰全局变量,该变量只在本文件内被访问,不能被外部其他文件直接访问。
在这里插入图片描述

📙1.2 修饰函数

  • test.c
#include"test.h"static void fun()
{printf("hello world!\n");
}
  • test.h
#pragma once
#include<stdio.h>extern void fun();
  • main.c
#include"test.h"int main()
{fun();return 0;
}

static修饰函数,该函数只能在本文件内被访问,不能被外部其他文件直接
在这里插入图片描述

虽然static修饰的函数不能被直接访问,但可以通过间接来访问:

  • tast.c
#include"test.h"static void fun()
{printf("hello world!\n");
}void F()
{fun();
}
  • test.h
#pragma once
#include<stdio.h>extern void F();
  • main.c
#include"test.h"int main()
{F();return 0;
}

在这里插入图片描述

📙1.3static总结

  • 在static修饰函数时:提高了项目的维护、提供安全保证。
  • 总的来说:static是C语言为用户提供安全保证的一个关键字。

二、关键字 - sizeof

📙2.1 基本数据类型

C数据类型

2.2 📙数据类型与"模子"

📝2.2.1 C常见的内置类型

C常见内置类型
int
short
long
long long
char
float
double

📝2.2.2 如何看待数据类型

  1. 定义变量的本质是:在内存中开辟一块空间,用于保存数据。
  2. 定义变量是需要类型的,而类型决定了:开辟空间的大小。
int main()
{printf("%d\n", sizeof(int));//4printf("%d\n", sizeof(short));//2printf("%d\n", sizeof(long));//4printf("%d\n", sizeof(long long));//8printf("%d\n", sizeof(char));//1printf("%d\n", sizeof(float));//4printf("%d\n", sizeof(double));//8return 0;
}

在这里插入图片描述

  • C中为何有数据类型:本质是对内存进行合理划分,按需索取。
  • 类型为什么在C中有这么多:应用的场景不同,解决应用场景对应得计算方式不同,需要空间的大小是不同的。
    本质就是:用最小成本,解决各种多样化的场景问题。

其实数据类型就相当于做月饼的模具:做什么样的月饼,用什么样的模具
在这里插入图片描述

2.3 📙变量的命名规则

📝规则1

标识符最好采用英文单词或其组合,不允许使用拼音。程序中的英文单词一般不要太复杂,用词应当准确。

  • 例如:
int main()
{fun();//全称为functionreturn 0;
}

📝规则2

标识符的长度应当符合“min-length && max-information”原则。

  • 例如:
int main()
{int MaxValueUntilOverflow = 0;int MaxVal = 0;return 0;
}

名字不要过长,过长的单词简写就行。

📝规则3

  • 当标识符由多个单词组成时,每个单词的首字符要大写,这样可以区分每个单词。
  • 这种命名的方式叫作:大小驼峰。
  • 举例:
int main()
{int MaxVal = 0;return 0;
}

📝规则4

尽量避免名字中出现数字编号,如:

int main()
{int Value1 = 0;int Value2 = 0;return 0;
}

但只是尽量,在特定的场景下是可以这样写的。

📝规则5

对在多个文件之间共同使用的全局变量要加范围限定符,如:

int g_val = 100;//全称为global variable

全局变量可以在变量名前面加上g_表示全局变量。

📝规则6

程序中不得出现仅靠大小写区分的相似的标识符,如:

int main()
{int x = 0;int X = 0;foo();FOO();return 0;
}

这样的命名会导致代码的可读性变差,例如:l和数字1、I和(L的小写l)。

📝规则7

一个函数名禁止被用于其它之处。例如:

int fun(int x)
{return x * x;
}int main()
{int fun = 10;return 0;
}

函数名为fun,但在mian函数里有个fun的局部变量,这样的命名是禁止的,容易让人误解且代码可读性低。

📝规则8

所有宏定义、枚举常数、只读变量全用大写字母命名,用下划线分割单词。例如:

#define MAX_INT 10

📝规则9

局部变量中可以采用通用的命名方式,但仅限于i、j、n、k等作为循环变量使用。
使用时不可以出现以下几个形式:

int main()
{//定义变量时不能出现这样的定义int   x;char    ch;int * p;return 0;
}

定义局部变量一般来说:

  • i、j、k、n、m等表示int类型。
  • c、ch等表示字符型。
  • a、arr等表示数组。
  • p等表示指针。
  • 除了i、j、k可以表示循环的变量名以外,别的变量名尽量不要使用。

📝规则10

  • 定义变量的同时要记得初始化。定义变量时,变量的值不一定清空。
  • 像局部变量,不做初始化,它的内容就是随机值。
  • VS2022上不做初始化,内容就是随机值且VS2022会报警告
    为初始化的n
  • 在Linux系统上定义的变量不初始化,它的内容是0.
  • 定义的变量,不初始化,它的内容是什么具体看编译器,但还是希望大家定义变量时,给变量初始化一下。

📙2.4 sizeof的理解

  • 有人会认为sizeof是一个函数,但其实sizeof不是函数,它只是一个关键字(操作符)而已。
  • sizeof是用来计算一个类型的大小的。
  • sizeof要注意的是以下问题:
#include<stdio.h>int main()
{int a = 0;//sizeof a是可以这样写的printf("%d\n", sizeof a);//sizeof int是不能这样写的printf("%d\n", sizeof int);return 0;
}

直接计算类型要带(),计算变量可以不带括号。

📙2.5 sizeof的总结

sizeof是用来计算在空间占用的字节大小的一个操作符,且sizeof是一个操作符。

三、signed、unsigned关键字

📙3.1 原反补

  • 相信大家已经学过原反补的概念了,我这里就简单叙述一遍:
  • 整型的原反补是相同的
  • 负数的原反补不相同,要通过计算得来,而负数的原反补计算过程为:
  1. 原码变反码 - 符号位不变其他位按位取反。
  2. 反码变补码 - 反码加1
  • 负数从补码变为原码的计算过程有两种方法:
  • 方法1
  • 倒着回去
  1. 补码变反码 - 补码-1
  2. 反码变原码 - 符号位不变其他位按位取反
  • 方法2
  • 按原码变补码的操作在进行一次:
  1. 补码变反码 - 符号位不变其他位按位取反
  2. 反码变原码 - 反码加1
int main()
{//整型的原反补是相同的int a = 10;//0000 0000 0000 0000 0000 0000 0000 1010 - 原码//0000 0000 0000 0000 0000 0000 0000 1010 - 反码//0000 0000 0000 0000 0000 0000 0000 1010 - 补码int b = -10;//1000 0000 0000 0000 0000 0000 0000 1010 - 原码//1111 1111 1111 1111 1111 1111 1111 0101 - 反码//1111 1111 1111 1111 1111 1111 1111 0110 - 补码return 0;
}

两种方法都可以,但要记住用的时候可以用方法1推,但实际上理解的时候要用方法2来理解,因为计算机使用的是方法2来进行计算的

📙3.2 二进制十进制快速转换口诀

想必大家在进行二进制转十进制或十进制转二进制的时候,计算的速度会很慢,所以给大家推荐一套二进制十进制相互快速转换的口诀
在这里插入图片描述

📙3.3 变量的存入和取出

int main()
{unsigned int a = -10;printf("%d\n", a);printf("%u\n", a);return 0;
}

上面代码的打印结果是什么呢?

答案是:10和4294967286,%d打印的是有符号数,而%u打印的是无符号数,无符号数的意思就是不把第一个比特位看成符号位了。

  • 结论:
  • 变量存和取的过程:
  • 存:字面数据要先转换为补码,在放入空间中,所以符号位,完全是看数据本身的正负号,与有无符号无关。
  • 取:取数据一定要先看数据本身类型,然后才决定要不要最高位的符号位,如果不需要直接二进制转十进制,如果需要,则先转成原码然后才能识别。(当然,最高符号位在那么,又要明确大小端)

📙3.4 大小端

VS2022的内存布局
在这里插入图片描述
大小端:
在这里插入图片描述
大小端基本概念:

  1. 大端:按字节为单位,低权值位数据存储在高地址处,就叫大端
  2. 小端:按字节为单位,低权值位数据存储在低地址处,就叫小端
  • 大小端快速知晓口诀:
  • 小端口诀:小小小
  • 大端口诀:除小小小以外的都认为是大端
  • 小小小的含义:第一个小:权值位比较小,第二个小:地址数字比较小,第三个小:小端的小。

📙3.5 深入理解变量的存入和取出

  • 存:看大小端存储
  • 取:先看大小端,再看自身类型
    在这里插入图片描述

📙3.6 为什么存储的都是补码

在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理; 同时,加法和减法也可以统一处理(CPU只有加法器)。此外,补码与原码相互转换,其运算过程是相的,不需要额外的硬件电路

📙3.7 数据类型的取值范围

这里以signed char为例:
在这里插入图片描述

所谓特定数据类型,能表示多少个数据,取决于多少个比特位对应的排列组合的个数。

  • 数据类型对应的取值大小
整型存储大小数值范围unsigned(无符号)数值范围
char1字节(byte)[-128 ~ 127][0 ~ 255]
int4字节(byte)[-2147483648 ~ 2147483647][0 ~ 4294967295]
short2字节(byte)[-32768 ~ 32767][0 ~ 65535]
long4字节(byte)[-2147483648 ~ 2147483647]0 ~ 4294967295
long long8字节(byte)±9.2233720368548E+4932[0 ~ 1844674407371E+19]
浮点型存储大小数值范围精度
float4字节(byte)[1.2E-38 ~ 3.4E+38]6位有效位
double8字节(byte)[2.3E-308 ~ 1.7E+308]15位有效位
long double16字节(byte)[3.4E-4932 ~ 1.1E+4932]19位有效位

在这里插入图片描述

相关文章:

【深入理解C语言】-- 关键字2

&#x1f407; &#x1f525;博客主页&#xff1a; 云曦 &#x1f4cb;系列专栏&#xff1a;深入理解C语言 &#x1f4a8;吾生也有涯&#xff0c;而知也无涯 &#x1f49b; 感谢大家&#x1f44d;点赞 &#x1f60b;关注&#x1f4dd;评论 文章目录 前言一、关键字 - static&…...

Java进阶(3)——手动实现ArrayList 源码的初步理解分析 数组插入数据和删除数据的问题

目录 引出手动实现ArrayList定义接口MyList<T>写ArrayList的实现类增加元素删除元素 写测试类进行测试数组插入数据? 总结 引出 1.ArrayList的结构分析&#xff0c;可迭代接口&#xff0c;是List的实现&#xff1b; 2.数组增加元素和删除元素的分析&#xff0c;何时扩容…...

若依前端npm run dev启动时报错

本文主要解决问题:若依前端npm run dev启动时报错,解决办法。 目录 1、第1种解决方案(亲测有效) 2、第2种解决方案(亲测有效) Error: error:0308010C:digital envelope routines::unsupportedat new Hash (node:internal/crypto/hash:67:19)at Object.createHash (node…...

实战项目:基于主从Reactor模型实现高并发服务器

项目完整代码仿mudou库one thread one loop式并发服务器实现: 仿muduo库One Thread One Loop式主从Reactor模型实现⾼并发服务器&#xff1a;通过模拟实现的⾼并发服务器组件&#xff0c;可以简洁快速的完成⼀个⾼性能的服务器搭建。并且&#xff0c;通过组件内提供的不同应⽤层…...

iTOP-RK3568开发板ubuntu环境下安装Eclipse

eclipse 是使用 Java 语言开发的&#xff0c;一个 Java 应用程序&#xff0c;这意味着 eclipse 只能运行在 Java虚拟机上。倘若没有安装 JDK&#xff08;Java Development Kit&#xff09;&#xff0c;即使在 ubuntu 上安装了 eclipse&#xff0c;也不能运行&#xff0c;所以要…...

大气热力学

大气稳定度 大气稳定度又称为大气层结稳定度(贺德馨,2006)。大气层结指的是大气温度和湿度在垂直方向上的分布&#xff0c;对大气中污染物的扩散起着重要的作用。在静止大气中&#xff0c;假定气团受到垂直方向的扰动后&#xff0c;有一个向上的微小位移&#xff0c;如果大气层…...

【RabbitMQ】消息队列-RabbitMQ篇章

文章目录 1、RabbitMQ是什么2、Dokcer安装RabbitMQ2.1安装Dokcer2.2安装rabbitmq 3、RabbitMQ入门案例 - Simple 简单模式4、RabbitMQ的核心组成部分4.1 RabbitMQ整体架构4.2RabbitMQ的运行流程 5、RabbitMQ的模式5.1 发布订阅模式--fanout 1、RabbitMQ是什么 RabbitMQ是一个开…...

W5100S-EVB-PICO 做UDP Server进行数据回环测试(七)

前言 前面我们用W5100S-EVB-PICO 开发板在TCP Client和TCP Server模式下&#xff0c;分别进行数据回环测试&#xff0c;本章我们将用开发板在UDP Server模式下进行数据回环测试。 UDP是什么&#xff1f;什么是UDP Server&#xff1f;能干什么&#xff1f; UDP (User Dataqram …...

Redis如何处理内存溢出的情况?

当Redis的内存使用达到上限时&#xff0c;会出现内存溢出的情况。Redis提供了几种处理内存溢出的机制&#xff1a; 内存淘汰策略&#xff1a;Redis提供了多种内存淘汰策略&#xff0c;用于在内存不足时选择要移除的键。常见的淘汰策略包括&#xff1a; LRU&#xff08;Least Re…...

高效数据传输:轻松上手将Kafka实时数据接入CnosDB

本篇我们将主要介绍如何在 Ubuntu 22.04.2 LTS 环境下&#xff0c;实现一个KafkaTelegrafCnosDB 同步实时获取流数据并存储的方案。在本次操作中&#xff0c;CnosDB 版本是2.3.0&#xff0c;Kafka 版本是2.5.1&#xff0c;Telegraf 版本是1.27.1 随着越来越多的应用程序架构转…...

【探索Linux】—— 强大的命令行工具 P.3(Linux开发工具 vim)

阅读导航 前言vim简介概念特点 vim的相关指令vim命令模式(Normal mode)相关指令插入模式(Insert mode)相关指令末行模式(last line mode)相关指令 简单vim配置&#xff08;附配置链接&#xff09;温馨提示 前言 前面我们讲了C语言的基础知识&#xff0c;也了解了一些数据结构&…...

AgentBench::AI智能体发展的潜在问题一

从历史上看,几乎每一种新技术的广泛应用都会在带来新机遇的同时引发很多新问题,AI智能体也不例外。从目前的发展看,AI智能体的发展可能带来的新问题可能包括如下方面: 第一是它可能带来涉及个人数据、隐私,以及知识产权的法律纠纷的大幅增长。要产生一个优秀的AI智能体,除…...

【2023年11月第四版教材】《第5章-信息系统工程之软件工程(第二部分)》

《第5章-信息系统工程之软件工程&#xff08;第二部分&#xff09;》 1.3 软件设计1.4 软件实现&#xff3b;补充第三版教材内容&#xff3d; 1.5 部署交付 1.3 软件设计 1、结构化设计SD是一种面向数据流的方法&#xff0c;它以SRS和SA阶段所产生的DFD和数据字 典等文档为基础…...

OpenCV(二)——图像基本处理(二)

目录 2.图像的几何变换 2.1 图像平移 2.2 图像缩放 2.3 图像旋转 2.4 仿射变换 2.5 透视变换...

Redis—缓存

目录标题 缓存雪崩发生场景解决方案针对Redis宕机的缓存雪崩解决方案 缓存击穿发生场景解决方案 缓存穿透发生场景解决方案布隆过滤器 数据库和缓存数据一致性 缓存雪崩 大量缓存数据在同一时间过期&#xff08;失效&#xff09;或者 Redis 故障宕机时&#xff0c;如果此时有大…...

第三章 图论 No.10无向图的双连通分量

文章目录 定义Tarjan求e-DCCTarjan求v-DCC395. 冗余路径1183. 电力396. 矿场搭建 定义 无向图有两种双连通分量 边双连通分量&#xff0c;e-DCC点双连通分量&#xff0c;v-DCC 桥&#xff1a;删除这条无向边后&#xff0c;图变得不连通&#xff0c;这条边被称为桥 边双连通分…...

Java学习手册——第二篇面向对象程序设计

Java学习手册——第二篇面向对象 1. 结构化程序设计2. 面向对象 第一章我们已经介绍了Java语言的基础知识&#xff0c;也知道他能干什么了&#xff0c; 那我们就从他的设计思想开始入手吧。 接触一个语言之前首先要知道他的大方向&#xff0c;设计思想是什么样的&#xff0c; 这…...

Redis实战:Redis的安装及简单使用

本片将介绍 Redis 的安装及简单使用 文章目录 1、Redis安装1.1、Windows下Redis的安装1.2、Linux下Redis的安装1.3、Mac下Redis的安装&#xff08;使用Homebrew&#xff09; 2、Redis使用2.1、启动服务端客户端2.2、Redis简单命令 3、Redis命令大全 1、Redis安装 1.1、Windows…...

Linux学习之初识Linux

目录 一.Linux的发展历史及概念 1.什么是Linux UNIX发展的历史&#xff1a; Linux发展历史&#xff1a; 2. 开源 商业化发行版本 二. 如何搭建Linux环境 Linux 环境的搭建方式主要有三种&#xff1a; 1. 直接安装在物理机上 2. 使用虚拟机软件 3. 使用云服务器 三. …...

神经网络基础-神经网络补充概念-29-为什么使用深层表示

概念 深层表示&#xff08;Deep Representation&#xff09;是指在深度神经网络的多个隐藏层中逐层提取和学习数据的特征表示。 使用深层表示的原因 高维特征提取&#xff1a;深层神经网络可以从原始数据中自动学习高维抽象特征。每个隐藏层都对数据进行一些变换&#xff0c…...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

12.找到字符串中所有字母异位词

&#x1f9e0; 题目解析 题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义&#xff1a; 若两个字符串包含的字符种类和出现次数完全相同&#xff0c;顺序无所谓&#xff0c;则互为…...