初识C语言(四)

news2024/9/30 10:42:20


目录

前言

十一、常见关键字(补充)

(1)register —寄存器

(2)typedef类型重命名

(3)static静态的

1、修饰局部变量

2、修饰全局变量

3、修饰函数

十二、#define定义常量和宏

十三、指针  

总结


前言

上一篇文章介绍了函数,数组,操作符,常见关键字和操作符,今天再从一些关键字开始,介绍以后的内容。


十一、常见关键字(补充)

(1)register —寄存器

计算机上的数据存储到哪里呢,硬盘和内存可以存储,寄存器也可以存储,而在内存和寄存器之间还有个高速缓存也可以进行存储。

现在基本上有这几种存储,而它们的内存单位为:

网盘,上线就送几T哈哈,一般为都以T为单位,而硬盘是520G,以G为单位,内存8G/16G,以G为单位,高速缓存以xxM,以M为单位,而寄存器则以字节为单位,这些大小的单位是可以用价格进行比较的,这一看网盘就便宜,寄存器最贵,为什么内存小了而价格会贵?因为它的速度非常快,越快越贵。速度越快造价就越高空间就越小。寄存器是集成到cpu(中央处理器)上的,它跟内存没有关系,也是一种独立的空间。

(2)typedef类型重命名

typedef unsigned int uint;
int main( )
{
    unsigned int age;
    uint age2;
    return 0;
}

顾名思义,类型重命名,上面的代码如果我们想要一个 无符号整形,那么就可以用typedef,这里面的意思就是用一个uint的新名称来重新命名unsigned int,之前要定义一个变量要在前面写unsigned int,而当用uint重命名之后,就可以用uint+类型名来定义,以后uint就代表unsigned int,所以非常方便,以后一些复杂的变量类型都可以用typedef来重新命名,改的时候也好改,只要改一句就可以。不需要都改,那样非常麻烦。

(3)static静态的

有三种用法:

1、修饰局部变量

2.修饰全局变量

3.修饰函数

1、修饰局部变量
void test( )
{
    int a =0;
    a++;
    printf("%d\n",a);
}

int main( )
{
    int i =0;
    while(i<10)
    {
        test( );
        i++;
    }
    return 0;
}

这里的程序是打印十个1, while循环从0开始,内部进行test函数,而test函数创建了a=0这个变量,a加1,打印1,i+1,而a这个变量作用域生命周期结束,进行销毁,这样运行十次,所以就打印十个1。

void test( )
{
    static int a =0;
    a++;
    printf("%d\n",a);
}

而当我们在变量a前面加上一个static关键字,那么结果就会发生变化,结果会从1到10依次输出, while循环从0开始,内部进行test函数,而test函数创建了a=0这个变量,a加1,打印1,而出test这个函数的时候,变量a不会销毁,a就会依次增加,才会输出1到10。

内存一般分为栈区,堆区和静态区,栈区一般都是存放一些局部变量,函数参数以及一些临时的变量,而堆区一般是动态内存分配,malloc,calloc,realloc,free等,而静态区是存放静态变量以及全局变量,放在栈区的是进入作用域创建,出了作用域销毁释放,下一次进来的时候就要重新创建;静态区里的数据创建后直到程序结束了之后才会释放,所以下一次进来的时候并不会重新创建,因为之前的值没有被销毁回收。

局部变量被static修饰后,这种变量就放在了静态区,放在静态区的变量,创建好后直到程序结束后才释放,本质上是static的修饰改变了局部变量的存储位置,由于存储位置的差异,执行效果就会发生差异,而且被static修饰是不影响作用域的,但是声明周期发生了变化,可以说是变长了。

2、修饰全局变量
//第一个文件
int a = 2024;


//第二个文件

extern int a;
int main( )
{
    printf("%d\n",a);
    return 0;
}

在源文件里面写两个C文件,在第一个文件中定义全局变量a为2024,在第二个文件中通过声明外部符号来声明a,从而调用a的值,打印出a的值,毋庸置疑,这里打印出来的就是2024。

//第一个文件
static int a = 2024;


//第二个文件

extern int a;
int main( )
{
    printf("%d\n",a);
    return 0;
}

而当在定义全局变量a的时候,在前面加上static静态关键字,就会发现这里面会报错,编译器会说无法解析外部符号a,无法解析外部命令。

之前是普通的全局变量,因为全局变量是具有外部链接属性的(局部变量是无链接属性的),所以第二个文件可以通过链接来使用a,但是如果全局变量被static修饰,这个外部链接属性就变成了内部链接属性,这个全局变量就只能在自己所在的源文件内部使用。

a一旦加上static,就只能在它所在的文件内使用,就像限制了它的使用范围,最终影响的是全局变量的作用域,使得全局变量的作用域变小了。

3、修饰函数
//第一个文件
int Add(int x,int y)
{
    return x+y;
}

//第二个文件
extern int Add(int x,int y);
int main( )
{
    int a =10;
    int b =10;
    int c =Add(a,b);
    printf("%d\n",c);
    return 0;
}

在调用函数的时候,不同文件也要声明外部函数,从而才能运行。 

//第一个文件
static int Add(int x,int y)
{
    return x+y;
}

//第二个文件
extern int Add(int x,int y);
int main( )
{
    int a =10;
    int b =10;
    int c =Add(a,b);
    printf("%d\n",c);
    return 0;
}

函数本身具有外部链接属性的,被static修饰后,外部链接属性就变成了内部链接属性,就只能在函数所在的源文件内使用,使作用域变小了。这与上面的修饰全局变量的作用一样。

十二、#define定义常量和宏

C语言中很常见就是#define,我们可以用来它来定义符号或者宏,比如在下面定义一个值M,这个M的值为100,这是一个符号,同时是一个常量值,而不是常量。

#define M 100
int main( )
{
    printf("%d\n",M);
}

同时,define还可以进行定义宏,下面MAX就是一个宏

#define MAX(x,y) (x>y?x:y)

int main( )
{
    int a =10;
    int b =20;
    int m =MAX(a.b);
    //就相当于 int m = (a>b?a:b);
    printf("%d\n",m);
}

 但我们在主函数里面调用宏的时候,参数就会发生替换,通过宏体进行替换,从而返回值。一般宏是用来进行较为简单的处理的,函数一般则是进行复杂一些的。

十三、指针  

内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中间进行的,所以为了更有效的使用内存,就把内存划分为一个个小的内存单元,每个内存单元的大小为1个字节,为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。

要了解指针,首先要理解内存,内存是计算机上的一种存储介质(存储空间),程序在运行中会载入内存,我们可以打开任务管理器来查看各个程序占用的内存,程序中如果需要数据存储,也会申请空间。

如何有效的使用内存,在生活中,我们的高楼也许会有几层或者几十层,如何更加高效而又准确的管理,是的,每个楼层每户人家都有一个编号,也就是门牌号,通过门牌号就可以定位家在哪里,就非常的好管理一个门牌号就对应一个房间。内存其实也参考了这个思路。

假设图中的一个大长方形就是一个内存空间,里面的一个小格子就是一个内存单元,同时给每个内存单元进行相应编号,未来通过编号就可以找到相应的定位内存单元,实践中,一个内存单元的大小是一个字节。计算机中,内存的编号也会叫做地址,地址叫做指针。

如果访问一个内存单元,那内存单元的地址(指针)如何产生:32位的机器为例,里面有32根地址线,地址线如果通电,由于电信号有高电平和低电频,转化为就是0和1,转换为数字信号,32根地址线就会产生:

00000000000000000000000000000000

00000000000000000000000000000001

........

1111111111111111111111111111111111111

32个全0到32个全1,也就一一对应内存单元,最多产生2的32次方这样的二进制序列,就可以作为2的32次方个地址,就可以管理2的32次方个内存单元,也就是2的32次方个字节的内存空间。也就是2的32次方字节,转换就是 4,294,967,296 byte,也就是4个GB的内存。内存的编号,地址,指针其实就是一个东西。

#int main( )
{
    int a =1;
    printf("%d\n",a); 
    return 0;   
}

 上述代码定义了一个命名为a的常量,而它会向内存申请一个四个字节的空间,用之前的图像来说就是占用了四层小格。每一个字节都有一个自己的编号。

int main( ) 
{
    int a =1;
    printf("%p\n",&a);//打印a的地址
    return 0;
}

上述代码就打印出了a的地址,但是拿出的是a所占四个字节地址中第一个字节的地址,(&a取出的是a所占内存中4个字节中第一个字节的地址)。

当得到地址了,可以先把地址(十六进制)存到一个变量中去,将来用的时候用就可以,就类似于现实中的家庭地址一样,将来要邮快件的时候就可以通过地址来邮过去。

int a =1;
int * pa =&a;

上述创建了一个a 的变量,又通过pa来表示接收a的地址,而地址又叫指针,所以把pa叫做指针变量,指针变量是存放指针的一个变量。*说明pa是指针,int说明pa指向的是类型为整形的变量,&a说明是a的地址。

现在就可以通过pa来找到a了:

int a =1;
int * pa =&a;
* pa = 20;

 *pa叫做解引用操作,作用就是通过pa中的地址找到a,*pa就是a,这就找到了a。这时候通过pa地址找到了a,同时改为20,就相当于a=20,所以a就又原来的1变为了20。通过地址改变a,并不改变pa里的任何东西。

有两种理解方式,一是指针就是地址,二是指针一般指的是指针变量,指针变量是用来存放地址的,而地址在32位机器上,是32位bit位,指针变量就是存放的是32bit的地址,一个字节8个bit,所以32位机器指针变量的大小是4个字节,在64位机器上,是64个bit位,指针大小为8个字节。


总结

指针很重要,后续会详解,介绍马上完事了,祝大家越来越牛

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2179413.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

5250 Fantasy RPG Icons Pack 幻想RPG游戏图标合集

这里是集合 - 幻想RPG图标 它包括50个主题图标。文件:PNG。 在档案中,带有背景的图标(512512)和没有背景的单个对象(大小取决于主题)。仅具有背景技能的技能。 2024年2月更新(+500个图标): RPG蔬菜图标; RPG游戏中的蜘蛛战利品图标; RPG海战战利品图标; RPG怪物战利…

匿名管道 Linux

管道 首先自己要用用户层缓冲区&#xff0c;还得把用户层缓冲区拷贝到管道里&#xff0c;&#xff08;从键盘里输入数据到用户层缓冲区里面&#xff09;&#xff0c;然后用户层缓冲区通过系统调用&#xff08;write&#xff09;写到管道里&#xff0c;然后再通过read系统调用&…

新手上路:Anaconda虚拟环境创建和配置以使用PyTorch和DGL

文章目录 前言步骤 1: 安装 Anaconda步骤 2: 创建新的 Anaconda 环境步骤 3: 安装最新版本的 PyTorch步骤 4: 安装特定版本的 PyTorch步骤 5: 安装最新版本的 DGL步骤 6: 安装特定版本的 DGL步骤 7: Pycharm中使用虚拟环境解释器第一种情况&#xff1a;创建新项目第二种情况&am…

Linux Shell编程最重要的十个核心概念

对于每个Linux学习者而言&#xff0c;Shell编程的重要性不言而喻。它是连接用户与系统操作的桥梁&#xff0c;能够培养命令行的熟练度和解决问题的能力。通过Shell编程&#xff0c;学习者可以深入理解系统管理和日常任务自动化的精髓&#xff0c;提高工作效率。此外&#xff0c…

应急响应(1)-同事电脑

一、现象 重要时间节点&#xff0c;同事反馈桌面有鼠标移动、随机断网&#xff1b;发现登录账户多了一个&#xff0c;由于电脑长时间没有更改过密码&#xff0c;导致忘记密码无法登录。随机联系进行应急处理。 二、排查 2.1、密码重置/删除 由于同事忘记密码导致无法进行登录…

Linux文件系统入门详解-总结大章

我们先看一张图&#xff1a; 这张图大体上描述了 Linux 系统上&#xff0c;应用程序对磁盘上的文件进行读写时&#xff0c;从上到下经历了哪些事情。 这篇文章就以这张图为基础&#xff0c;介绍 Linux 在 I/O 上做了哪些事情。 文件系统 什么是文件系统 文件系统&#xff0…

EKF学习笔记

扩展卡尔曼滤波&#xff0c;也就是EKF&#xff0c;常用于在动态系统中对状态的估计。比如&#xff0c;在机器人领域&#xff0c;EKF则常常用于对状态&#xff08;位置&#xff0c;方向&#xff09;的估计&#xff0c;也就是我们常说的数据融合&#xff0c;结合运动模型和观测数…

vscode使用yarn 启动vue项目记录

第一次启动yarn项目&#xff0c;这个是公司的老项目&#xff0c;遇到了点问题&#xff0c;记录下首先是我一般使用的是npm命令&#xff0c;所以没有安装yarn vscode安装yarn vscode进入到该项目文件夹下&#xff0c;输入命令&#xff1a;npm install -g yarn 安装成功后&…

河南人社厅:注册满两年可按条件认定副高

河南省工程系列建筑专业中高级职称 申报评审标准 总则 一、为培养造就高素质、社会化的工程建设领域专业技术人才队伍&#xff0c;充分发挥工程建设领域专业技术人才在科技发展和经济建设中的作用&#xff0c;推动技术创新、科技成果转化和实现高新技术产业化&#xff0c;根据…

CSS给一行按钮统一设置间隔

使用css的&#xff0b;&#xff08;相邻兄弟选择器&#xff09;&#xff0c;找到指定元素后面的相邻元素。 <div class"btn-list"><button class"btn">按钮1</button><button class"btn">按钮2</button><butto…

Arthas memory(查看 JVM 内存信息)

文章目录 二、命令列表2.1 jvm相关命令2.1.11 memory&#xff08;查看 JVM 内存信息&#xff09;举例1&#xff1a;查看 JVM 内存信息 本人其他相关文章链接 二、命令列表 2.1 jvm相关命令 2.1.11 memory&#xff08;查看 JVM 内存信息&#xff09; 基本用法&#xff1a; mem…

第一讲-环境安装

PyCharm安装 官网下载 https://www.jetbrains.com/pycharm/ 点击Download跳转到下载界面,会有专业版跟社区版两个选择,专业版需要购买,可自行在淘宝上买个激活码。一般开发社区版够用了。 这是专业版: 这是社区版:

WinRAR技巧:如何给多个压缩包设置同一个密码

RAR压缩包是大家经常使用的文件&#xff0c;并且可以进行加密&#xff0c;也是一种文件加密方式&#xff0c;那么当你有很多文件都需要压缩加密&#xff0c;b并且想要设置同一个密码&#xff0c;防止以后忘记密码&#xff0c;该如何高效的完成这个工作呢&#xff1f;今天分享如…

vue2中使用tailwindCss 详细教程

1、先看官方文档&#xff1a;https://www.tailwindcss.cn/ 2、先安装&#xff1a;npm install -D tailwindcss ---------------通过 npm 安装 tailwindcss&#xff0c;然后创建你自己的 create your tailwind.config.js 配置文件。 npm install -D tailwindcss 3、初始化文件…

解决Java调用通义接口出现依赖爆红与API-key找不到(日常小记)

1.依赖dashscope-sdk-java爆红 解决方法&#xff1a; <dependency><groupId>com.alibaba</groupId><artifactId>dashscope-sdk-java</artifactId><exclusions><exclusion><groupId>org.slf4j</groupId><artifactId…

跑批系统设计

需求分析 将大批量的数据&#xff0c;从一个地方&#xff0c;迁移到另外一个地方&#xff0c;如何处理 主要的涉及到的问题 亿级数据怎么存怎么防止重复调度怎么做到负载均衡同一个节点&#xff0c;任务怎么并行如何动态调整并发度机器节点挂了怎么办 概要设计 数据存储 …

springboot整合MybatisPlus+MySQL

上一篇&#xff1a;springboot整合sentinel和对feign熔断降级 文章目录 一、准备二、主要工作三、具体步骤3.1 准备数据库环境3.20 pre引入依赖3.2 引入依赖3.3 bootstrap.yml配置mybatisplus3.40 pre引入service、mapper3.4 引入实体类、service、mapper 四、测试目录结构 五…

数据结构 ——— 单链表oj题:移除链表中所有 val 的元素

目录 题目要求 手搓简易单链表 代码实现 题目要求 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回新的头节点 手搓简易单链表 在实现以上逻辑函数前&#xff0c;要先手搓一个单链表出来&#xff…

iOS--App启动过程及优化

前言 App启动是用户对于一个app的第一印象&#xff0c;因此如何使用户在最短的时间打开进入app显得格外重要。启动优化因此成为了App调优至关重要的一项。 只有具体了解了App的启动过程&#xff0c;我们才能对其进行优化。 App启动过程 App启动分为冷启动和热启动 热启动&…

公司申请商标注册需要什么材料

申请商标注册的&#xff0c;应当向商标局提交《商标注册申请书》及其它文件&#xff0c;具体要求是&#xff1a; 1、申请人必须按一类商品一件商标一份申请的原则&#xff0c;提交《商标注册申请书》一份。也即一份申请书上填报的商品或服务只能限定在《商标注册用商品和服务国…