c语言修炼第一章--初识c语言(1.3)

news2024/9/22 19:45:27

目录

前言:                                                                                                     

1.关键字

1.1常见关键字:

1.1.1typedef类型重定义

1.2.static

1.2.1static修饰局部变量

1.2.2static修饰全局变量

1.2.3static修饰函数

1.3#define定义常量和宏

1.3.1#define定常量

1.3.2#define定义宏

2.指针

2.1.什么是内存

2.1.1地址是如何产生的

2.2指针

2.2.1指针变量的大小

3.结构体

3.1为什么会有结构体呢

3.2结构体的语法形式

3.3结构体成员.和->

3.3.1 结构体成员.使用 


前言:                                                                                                     

小伙伴们大家好!来和菜菜酱一起学习初识c语言最后一部分叭!ok,废话不多说直接开始叭

1.关键字

1.1常见关键字:

auto   break   case  char  const  continue  default     sizeof  static 
do  double  else      enum   extern  float    for  goto   union  unsigned
if  int  long  register  return  short  signed   switch     typedef

c语言提供了丰富的关键字,这些关键字是语言本身预先设定好的,用户不能创建关键字也不能用关键字命名为变量名!!!

1.1.1typedef类型重定义

#include<stdio.h>
typedef unsigned int u_int;
int main()
{
	//unsigned int n = 13;
	u_int n = 13;
	if (n)
	{
		printf("haha\n");
	}
	return 0;
}

让我们一起来分析一下代码叭!最开始n的类型为unsigned int类型,但是我们发现这个类型写起来好麻烦,有什么方法可以把这个类型名变得简单一点吖?这个时候我们的主角typedef就该上场了!typedef unsigned int  u_int,typedef重新把unsigned int 命名为u_int。这种就好比我叫张三,然后家里人会喊小名三三。三三是我张三也是我!在这里u_int是unsigned int 的小名。在代码中直接使用u_int是可以的哦。来看看运行结果叭

总结一下:typedef可以将类型重命名!可以起到简便作用! 

1.2.static

static的三个作用:

  • static可以修饰局部变量---静态局部变量
  • static可以修饰全局变量---静态全局变量
  • static可以修饰函数---静态函数
1.2.1static修饰局部变量

酱酱们还记得关于变量的生命周期和作用域嘛?在那节中我们说过全局变量的生命周期和作用域是整个工程局部变量的生命周期进入作用域生命周期开始,出作用域生命周期结束。局部变量的作用域指的是函数的有效区域

#include<stdio.h>
void test()
{
	int n = 6;
	n++;
	printf("%d ", n);
}
int main()
{
	int a = 0;
	while (a <5)
	{
		test();
		a++;
	}
	return 0;
}

以这个代码为例,在test函数中变量n是局部变量,它的作用域是test整个大括号,它的生命在周期是进入大括号开始,出大括号结束。所以每次调用test函数,n的值都是从6开始,n++之后n的值改为7并打印!此时代码的结果显而易见啦,我们一起crtl+f5运行一下代码叭

 没错结果就是5个7!我们再来看看那要是调试结果叭

 第一次进入test函数(进入函数内部调试要按f11)n最开始的值为6,n++之后值为7。我们再按f10会发现返回到了while里                                                                                                                    

                                   

 然后再重复之前的动作,再次按f11进入test函数

 此时我们发现刚进入n的值先是为随机值,再次按f10。此时n的值重新为6

 当n++之后n的值为7,并且此时再次再屏幕上打印7。后面就一直再重复2至7号的动作!

我们在int n前面加上一个static修饰结果又会是什么样的呢?一起来看看吧!

#include<stdio.h>
void test()
{
	static int n = 6;
	n++;
	printf("%d ", n);
}
int main()
{
	int a = 0;
	while (a <5)
	{
		test();
		a++;
	}
	return 0;
}

 直接ctrl+f5运行看看结果吧!

     

 哦豁,可之前的结果不一样欸,这是为什么呢?我们来调试一下代码!              

 这个代码的执行程序和之前的一样,我们主要来看看第二次进入test函数n的值为多少吧!

 此时我们可以观察到进入test函数之后直接跳过static int n =6,

直接来到n++并且此时n的值没有变成随机值也没有变成6,而一直是7.。再次f10,我们发现n++之后n的值为8。

 我们可以得出一个结论:被static修饰的局部变量在编译期间就创建好了,出作用域没有被销毁,在程序彻底结束时才会销毁。而不加static修饰的局部变量出作用域就被销毁每次再进作用域会产生新的值!!!可是为什么会这样呢?此时我们就需要了解一下原理啦

在c/c++代码学习中把内存划分为三个区域:栈区,堆区,静态区

                                                 

                   

 

栈区的特点是:进入作用域创建,出作用域销毁(也就是把内存还给操作系统)

堆区的特点:进行动态分配(后期会讲噢)

静态区的特点:创建好之后直到程序结束才会销毁。

了解这些完毕我们再来解答,static修饰局部变量(生命周期边长,但作用域不变)本来局部变量在栈区,被static修饰之后存储到了静态区。即static修饰局部变量改变了变量的存储位置,使得局部变量生命周期变长了直到程序结束才结束,但依旧是局部变量。

1.2.2static修饰全局变量

直接上代码!!!

 当我们写这样一段代码时,感觉好像好像没问题。然后crtl+f5运行一下

                         

然后就发现代码运行出错了,发出警告Add未定义。为什么会这样呢?我们 不是在add.c源文件里定义了Add函数嘛,Add函数不是全局变量嘛为什么还会报错呢?这是因为在跨文件是使用全局变量之前要进行声明!使用关键字extern声明其类型函数名参数类型等!

 

                   

此时我们会发现代码就可以成功运行啦!超棒哒!接下来我们试试加上static修饰叭

 还是之前的代码!ctrl+f5运行叭

 哦豁!为什么又失败了我们不是用extern声明了外部符号嘛为什么加上static修饰之后会报错呀!解释:全局变量之所以能够跨文件使用,是因为其具有外部连接属性!被static修饰之后外部连接属性变成了内部链接属性!被修饰的全局变量只能在内部源文件使用不可以跨文件是使用呐而且感觉被static修饰的全局变量作用域变小了,但是它的位置不变噢!

所以此时我们应当将代码改为

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
static int Add(int a, int b)
{
	return a + b;
}
int main()
{
	int m = 0;
	int n = 0;
	scanf("%d%d", &m, &n);
	int k = Add(m, n);
	printf("%d ", k);
	return 0;
}

此时就是使用啦!

1.2.3static修饰函数

还是用上面的代码为例。函数和全局变量一样具有外部链接属性,可以进行跨文件使用!但是被static修饰之后,外部链接属性变为内部链接属性!只能在内部源文件内使用不可以在其他源文件里使用!这是不是和全局变量一样呐!

1.3#define定义常量和宏

1.3.1#define定常量
#define _CRT_SECURE_NO_WARNINGS
#define m 10
#include<stdio.h>
int main()
{
	int arr[m] = {1,2,3,4,5,6,7,8,9,0};//此时m是一个常数
	int i = 0;
	for (i = 0; i < m; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

当我们运行代码时可以成功打印结

                                    


 #define定义的常量和const修饰的常变量不一样!#define定义的标识符常量本质是一个常量,而const修饰的常变量只是具有常属性本质还是一个变量!

1.3.2#define定义宏
#define _CRT_SECURE_NO_WARNINGS
#define Add(x,y) ((x)+(y))
//Add是宏的名字,(x,y)是宏的参数  ((x)+(y))是宏的实现体
#include<stdio.h>
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d %d", &a, &b);
	int c = Add(a, b);
	printf("%d ", c);
	return 0;
}

 在编译期间int c=Add(a,b)就已经替换为int c =((a)+(b))。ctrl+f5代码运行成功没有保证错

           

2.指针

2.1.什么是内存

内存是电脑上特别重要的存储器,计算机中的程序的运行都是在内存中进行的。

所以为了有效使用内存,把内存划分为一个个内存单元,每个内存单元的大小是一字节。

为了有效访问到每个内存单元,就给内存进行编号,这些编号称之为内存单元的地址

         

2.1.1地址是如何产生的

在计算机中有地址线(物理线)通电后产生高低电频,转换为数字信号(1/0)。

在32位机器上有32根地址线,可以产生2的32次方个编号同时也说明可以管理2的32次方的空间(即2GB)

同理得,在64位机器上有64位地址线,可以产生2的64次方个编号。

int main()
{
	int a = 10;
	printf("%p ", &a);
	return 0;
}

 int的大小为4个字节

 那么int a 在内存中的存储应该是这样,那么我们打印a的地址是打印出来的是哪个值呢?一起来调试代码叭

 为什么是00 00 00 01呢?这是因为为了方便在内存中中采取十六进制的方式!四位二进制数字可以换取得到一位十六进制数字!再来看看打印出来的地址 此时我们惊奇的发现打印出来的地址是int a四个字节地址中的第一个地址!!

2.2指针

在c语言中,把编号称为地址,把地址又称之为指针!                                                                   

当我们得到一个变量的地址该如何进行存储呢?上代码

#include<stdio.h>
int main()
{
	int a = 1;
	int* pa = &a;
	*pa = 10;
	printf("%d", a);
	return 0;
}

利用&(取地址操作符)拿到a的地址,并把a的地址存放在变量pa中。在c语言中我们把存放地址的变量称之为指针变量!pa的类型为int*类型,*说明pa是一个指针,int说明被指向的对象的类型是int类型。pa中存放着a的地址我们可以通过*解引用操作符来通过地址找到a,此时的*pa就相当于a,可以改变a原本的值!让我们一起来运行代码看看结果叭

 哦豁说明我们的分析正确欸!我们再来画图理解一下pa和a的关系叭

 在这里再说一下,指针是地址也是编号,指针变量是用来存放地址的变量!口语中所说的指针一般都是☞指针变量!

2.2.1指针变量的大小

指针变量是用来存放地址的。在(x86)32位机器上,地址是32为二进制位,这个地址要存储的话需要4个字节。在(x64)64位机器山,地址是64位二进制位,这个地址存储的话需要8个字节(因为1个字节=8个比特位)

3.结构体

3.1为什么会有结构体呢

结构体的出现是为了帮我们描述复杂对象。例如对于一本书的描述我们需要有定价,作者,书名等,对一个学生的描述我们需要有性别,姓名,年龄,学号等

3.2结构体的语法形式

上代码!

#include<stdio.h>
struct stu 
{
	char name[20];
	int age;
	char sex[5];
};
int main()
{
	struct stu s = { "张三",20,"男" };
	printf("%s %d %s ", s.name, s.age, s.sex);
	return 0;
}

从这个代码我们可以发现struct的语法形式为

struct tag
{
   tag的相关属性;
};//这里要注意一定不能漏了分号

struct tag一起组成结构体类型!结构体的初始化要用{}

3.3结构体成员.和->

还是以上面的代码为例

3.3.1 结构体成员.使用 

在使用结构成员之前先使用结构体类型创建一个变量,结构体访问对象用.   构成结构体变量.成员名

3.3.2结构体成员->

这个和上面的结构体变量又不相同!->使用指针中哒,上代码看看效果叭

#include<stdio.h>
struct stu
{
	char name[20];
	int age;
	char sex[5];
};
void print(struct stu* ps)
{
	printf("%s %d %s ", ps->name, ps->age, ps->sex);
}

int main()
{
	struct stu s = { "张三",20,"男" };
	print(&s);
	return 0;
}

在这个代码里向print函数传送的是变量s的地址,因此在print函数中要用结构体指针来接收。在打印时直接指针变量->结构体成员即可!

总结:结构体成员的两种使用方法:第一种:结构体变量.结构体成员。第二种:结构体指针->结构体成员!!!


以上就是第一章的最后一部分的内容!

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

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

相关文章

待办事项工具用哪个?每天都在用的待办工具

随着职场“内卷”程度的加深&#xff0c;越来越多的上班族感到自己每天都会面临各种繁忙的日程安排、琐碎的待办事项&#xff0c;并且工作事项和家庭事项交织在一起&#xff0c;需要各方面都兼顾到&#xff0c;这简直让人恨不得长出三头六臂。在待办的事情比较多时&#xff0c;…

艺考之路,很艰难也很幸福

点击文末“阅读原文”即可参与节目互动 剪辑、音频 / 卷圈 运营 / SandLiu 卷圈 监制 / 姝琦 嘉宾 / 小川同学 产品统筹 / bobo 录音间 / 声湃轩北京站 本期节目是拼娃时代的第三十期&#xff0c;我们请来了拼娃时代的老朋友&#xff0c;小川同学。 拼娃时代的听友们肯定…

带有10位数码管显示的语音芯片ic,节省30%MCU硬件资源WTV890-B001

随着科技的不断发展&#xff0c;WTV890-B001多功能语音芯片的推出&#xff0c;为工程师带来了极大的便利和产品体验&#xff0c;这款多功能语音芯片具有许多优势&#xff0c;其中WTV890-B001版本中&#xff0c;最引人注目的特点是它带有10位的数码管显示功能&#xff0c;无需再…

nginx配置https证书(nginx-docker版本)

1、下载证书文件 以下两种多可配置 2、nginx server下加上配置 注意&#xff1a;ssl_certificate 参数可为crt文件、或者pem文件。需要将文件docker cp进容器中&#xff0c; ssl_certificate、ssl_certificate_key 为容器内的文件路径。 listen 443 ssl;server_name 域名地…

TMS FlexCel Studio for net 7.17 cRACK

TTMS FlexCel Studio for net 100% 托管代码 Excel 文件操作引擎以及 Excel 和 PDF 报告生成&#xff0c;适用于 .NET、Xamarin.iOS、Xamarin.Android、Xamarin.Mac​​ 功能概述 使用 FlexCel Studio for .NET 创建可动态快速读写 Excel 文件的应用程序、Web 服务和移动设备应…

深入理解浏览器的缓存机制之协商缓存与强缓存

目录 什么是浏览器缓存 浏览器缓存的分类 &#x1f397;️ 强缓存 &#x1f397;️ 协商缓存 &#x1f449;&#x1f3fb; 缓存请求流程 &#x1f449;&#x1f3fb; 为什么要有Etag &#x1f449;&#x1f3fb; 缓存优先级 &#x1f449;&#x1f3fb; 启发式缓存 &a…

Midjourney教程古风人像类

古风图像的特点&#xff1a; 人物发型多为飘逸的长发&#xff0c;或是精致的盘发&#xff1b; 人物服装多为飘逸的长袍、长裙&#xff1b; 整体画风以水墨、水彩、工笔为c主&#xff0c;线条写意&#xff0c;色彩清新淡雅&#xff1b; 背景中多用花鸟、亭台楼阁、桃林等构建氛…

抖音seo矩阵系统源码|需求文档编译说明(三)

文章目录 批量剪辑工具技术源码框架 短视频SEO矩阵系统源码技术开发&#xff0c;遵循步骤抖音矩阵系统源码搭建功能 开发语言及开发环境 抖音账号矩阵系统源码搭建包括以下步骤 概要 ​​抖音seo源码&#xff0c;抖音矩阵系统如何使用源码二次开发&#xff0c;开发的功能有那些…

RT-Thread内核介绍

目录 三、RT-Thread内核介绍 3.1、内核框架 3.1.1、线程调度 3.1.2、时钟管理 3.1.3、线程间同步 3.1.4、线程间通信 3.1.5、内存管理 3.1.6、I/O 设备管理 3.2、RTT内核启动流程 3.2.1、汇编阶段 3.2.2、C阶段 3.2.3、rtthread_startup函数 3.2.4、创建主线程 三、…

jupyter notebook内核挂掉的解决方案

今天在运行notebook时报错 “jupyter notebook内核挂掉了”查找发现是下面这一句出的错&#xff0c;这是pytorch深度学习实战中的一个例程&#xff0c;读取三维体素文件并把其中的一张当作图片显示出来 plt.imshow(vol_arr[50]) 完整代码如下 import torch torch.set_printo…

决策树精讲

一、决策树的构造 决策树的构造是一个递归的过程&#xff0c;有三种情形会导致递归返回&#xff1a;(1)当前结点包含的样本全属于同一类别&#xff0c;这时直接将该结点标记为叶结点&#xff0c;并设为相应的类别&#xff1b;(2)当前属性集为空&#xff0c;或是所有样本在所有…

消息队列选型——为什么选择RabbitMQ

前言 MQ消息是目前分布式系统必不可少的组件&#xff0c;但是面对市面上众多的MQ组件&#xff0c;我们该用什么呢&#xff1f;我以实际项目的需求触发&#xff0c;介绍今天的主角——rabbitMQ。同时也会告知又有哪些优势和不足。事不宜迟&#xff0c;就开始今天的学习吧 目录…

ghost cms配置qq邮箱

背景&#xff1a; 在ghost cms中使用qq邮箱作为注册、登录、订阅等邮件发送方。 1 修改配置 在config.*.json文件中&#xff0c;添加mail配置 "mail": {"from": "xxxxxxqq.com","transport": "SMTP","options"…

Qt6 FFmpeg入门1 - 环境配置

目录 环境配置ffmpeg 下载qt 配套环境配置代码测试 环境配置 文章更新时间&#xff1a;2023/06/24 ffmpeg 下载 由于大部分的关于配置 ffmpegqt 环境的文章都停留在 2021 年&#xff0c;且许多方法均已过时&#xff0c;现在介绍一个最新的方法&#xff0c;并分析槽点供大家参考…

ElementUI在对话框中新增数据,使用rules校验规则进行校验,再点击完修改之后,在进行新增校验会报错

1.新增与修改使用同一个对话框&#xff0c;当修改完成一条数据后&#xff0c;重新打开新增的对话框&#xff0c;通过ElementUI的rules检验会报错 解决方案&#xff1a;在对应的rules校验中每个字段添加trigger: blur 即可解决上述问题,注意&#xff1a;下面的xxx代表需要校验的…

设计模式-05.01-行为型-观察者模板

观察者模式【常用】 我们常把 23 种经典的设计模式分为三类&#xff1a;创建型、结构型、行为型。前面我们已经学习了创建型和结构型&#xff0c;从今天起&#xff0c;我们开始学习行为型设计模式。我们知道&#xff0c;创建型设计模式主要解决“对象的创建”问题&#xff0c;…

工具篇7--RocketMq消息模型介绍

文章目录 前言&#xff1a;一、RocketMq是什么&#xff1f;二、RocketMq 模型介绍&#xff1a;1.RocketMq 模型图&#xff1a;2.RocketMq 生产者&#xff1a;2.1 生产者消费发送流程&#xff1a;2.2 生产者消息发送&#xff1a;2.2.1 同步发送普通消息&#xff1a;2.2.1 异步发…

AI大模型及算力要求

AI大模型对算力的要求非常高&#xff0c;需要高性能的硬件设备和分布式训练技术来支持。随着AI技术的不断发展&#xff0c;未来可能会出现更大、更复杂的模型&#xff0c;对算力的要求也将更高。今天和大家分享几个大模型及算力要求&#xff0c;希望对大家有所帮助。北京木奇移…

DETR系列:RT-DETR实战部署

上篇文章介绍RT-detr的论文内容&#xff08;RT-DETR 论文解析&#xff09;&#xff0c;本篇文章介绍算法复现、tensorRT加速、python调用部署、训练等方法。 RT-DETR实战部署 1.复现模型详情2.环境准备3.训练4.部署5.测试 1.复现模型详情 本次复现主要测试下表中RT-DETR-R50和…

Kafka集群模式核心概念

文章目录 1.Kafka集群模式下Broker|主题|分区|副本的概念1.1.Broker|主题|分区|副本的概念1.2.创建一个Topic指定3个副本数1.3.多副本的Topic详细信息描述 2.集群模式下以消费者组消费Topic中各分区消息的概念2.1.分消费者组消费各分区的概念2.2.集群模式下消息的发送和消费 3.…