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

c语言round函数显示未定义_学C语言写自己的K语言:C语言内存管理与错误处理。...

C语言可以直接操作内存。这是一把双刃剑。如果不想造成混乱,唯一的解决办法就是去了解它熟悉并应用它。

一、void关键词。

  1. void 的字面意思是“空类型”
  2. void *则为“空类型指针”,void *可以指向任何类型的数据。

二、C语言内存的印象。

b039fa709f74a6c693a5000e4f57f6bd.png
  1. 代码(code area),存放函数体的二进制代码;
  2. 数据(data area),存放未初始化的全局变量和静态变量。程序结束后由系统释放;
  3. BBS(Block Started by Symbol),存放已初始化的全局变量、静态变量、字符串常量。程序结束后由系统释放;
  4. 堆(heap area),存放程序运行中动态分配的存储空间。堆是低地址向高地址扩展的数据结构,是一块不连续的内存区域。在标准C语言上,使用malloc等内存分配函数是从堆中分配内存,同时需要手动分配释放内存。未及时释放产生内存泄漏;
  5. 栈(stack area),存放程序临时创建的局部变量,其中还包括函数调用时其形参,调用后的返回值等。栈是由到高地址向低地址扩展的数据结构。块执行结束时这些存储单元自动被释放,栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

三、C语言内存操作函数。

  • malloc函数,向系统申请分配指定 size 个字节的内存空间。
  • calloc函数,向系统申请分配 count 个长度为 size 一共为 count 乘以 size 个字节长度的连续内存空间,并将每一个字节都初始化为 0。
  • realloc函数,更改已经配置好的内存空间到指定的大小。
  • free函数,表示用来释放已经动态分配的内存空间。free()可以释放由malloc()calloc()realloc()分配的内存空间,以便其他程序再次使用。
#include <stdio.h>
#include <malloc.h>

int main()
{
	// malloc, void *malloc(size_t_Size).
	int* a = (int*)malloc(4);
	printf("1. malloc, a is %d.n", *a);
	*a = 56000;
	printf("2. malloc, a is %d.n", *a);

	// calloc, void *calloc(size_t_Count, size_t_Size).
	// 用来定义数组。默认值为0。
	int* b = (int*)calloc(3, 4);
	printf("3. calloc, b[0] is %d.n", b[0]);
	b[0] = 10;
	printf("4. calloc, b[0] is %d.n", b[0]);

	// realloc, void *realloc(void *_Block, size_t_Size).
	// 内存空间变小,产生溢出。
	realloc(a, 2);
	printf("5. realloc, a is %d.n", *a);

	// free, void free(void *).
	free(a);
	free(b);
	// 显示使用未定义变量的错误。
	// printf("7. free, a is %d, b[0] is %d.n", *a, b[0]);
}

/*

控制台输出
————————————————————
1. malloc, a is -842150451.
2. malloc, a is 56000.
3. calloc, b[0] is 0.
4. calloc, b[0] is 10.
5. realloc, a is -33695040.

*/

四、错误处理。

我们学习其它语言,发现错误处理非常重要,但C 语言没有提供对错误处理的直接支持。C语言允许你访问底层数据,在发生错误时,大多数的 C 或 UNIX 函数调用时返回1或 NULL,同时会设置一个错误代码errno,该错误代码是全局变量,表示在函数调用期间发生了错误。您可以在 errno.h 头文件中找到各种各样的错误代码。

  • perror() 和 strerror(),C 语言提供了 perror()strerror() 函数来显示与 errno 相关的文本消息。
  1. perror() 函数,显示你传给它的字符串,后跟一个冒号、一个空格和当前 errno 值的文本表示形式。
  2. strerror() 函数,返回一个指针,指针指向当前 errno 值的文本表示形式。
#include <stdio.h>
#include <errno.h>
#include <string.h>

extern int errno;

int main()
{
	FILE* pf;
	int code;
	char err[256];

	fopen_s(&pf, "not_exist.file", "rb");
	if (pf == NULL)
	{
		code = errno;
                // VS里使用strerror_s替代strerror。
		strerror_s(err, 256, code);
		printf("file open is err, %d, %s.", code, err);
	}
	else
	{
		fclose(pf);
	}
	return 0;
}

/*

控制台输出
————————————————————
file open is err, 2, No such file or directory.

*/

五、命令行参数。

执行程序时,可以从命令行传值给 C 程序,这些值被称为命令行参数。命令行参数是使用 main() 函数参数来处理的,其中,argc 是指传入参数的个数,argv[] 是一个指针数组,指向传递给程序的每个参数。

下面示例来自菜鸟教程。

#include <stdio.h>
int main(int argc, char* argv[])
{
	if (argc == 2)
	{
		printf("The argument supplied is %s.n", argv[1]);
	}
	else if (argc > 2)
	{
		printf("Too many arguments supplied.n");
	}
	else
	{
		printf("One argument expected.n");
	}
}

/*

控制台输出
————————————————————
One argument expected.

*/

C语言的一些标准库就不介绍了。

下一章,学C语言写自己的K语言:编译器简介。

让我们在这里,遇见明天的自己!姜友华

相关文章:

  • .net oracle 连接超时_Mysql连接数据库异常汇总【必收藏】
  • 对校招生培养工作的建议_美团高管对应届生建议:选中行业、选中职业、选中公司...
  • python中最难的是什么_Python 最难的问题你猜是什么?
  • origin数据平滑_Origin使用
  • github python 画图_传说中的画图神器Plotnine,Python中的ggplot2
  • 炉石传说投弹机器人怎么获得_炉石传说:9职业胜率最高卡组推荐 其中这套连99%的玩家都没用过...
  • ios 平滑移动view_在 iOS 中使用 OpenGL ES 实现绘画板
  • 怎么把照片上传到画板_摄影技巧:全黑背景的照片怎么出?怎么拍出高大上的照片...
  • 八皇后时间复杂度 回溯_LeetCode--回溯法心得
  • 运维平台_舜通云-智能光伏运维平台
  • 查询子串_Entity Framework Core Like 查询揭秘
  • 开关电源中的磁性元件书籍_超详细!开关电源电路方案选择指南!
  • 单位和流明_流明 | 你值得这世间所有美好
  • 什么是多态python_Python的多态是什么
  • python谁发明的1003python谁发明的_PAT乙级1003-Python
  • 30秒的PHP代码片段(1)数组 - Array
  • Angular Elements 及其运作原理
  • CSS选择器——伪元素选择器之处理父元素高度及外边距溢出
  • iOS仿今日头条、壁纸应用、筛选分类、三方微博、颜色填充等源码
  • Javascript基础之Array数组API
  • JS实现简单的MVC模式开发小游戏
  • open-falcon 开发笔记(一):从零开始搭建虚拟服务器和监测环境
  • sessionStorage和localStorage
  • ubuntu 下nginx安装 并支持https协议
  • 阿里云应用高可用服务公测发布
  • 关于 Linux 进程的 UID、EUID、GID 和 EGID
  • 如何胜任知名企业的商业数据分析师?
  • 实现简单的正则表达式引擎
  • 使用 5W1H 写出高可读的 Git Commit Message
  • 一些关于Rust在2019年的思考
  • 阿里云API、SDK和CLI应用实践方案
  • #LLM入门|Prompt#1.8_聊天机器人_Chatbot
  • #调用传感器数据_Flink使用函数之监控传感器温度上升提醒
  • $emit传递多个参数_PPC和MIPS指令集下二进制代码中函数参数个数的识别方法
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (阿里巴巴 dubbo,有数据库,可执行 )dubbo zookeeper spring demo
  • (附源码)ssm跨平台教学系统 毕业设计 280843
  • (解决办法)ASP.NET导出Excel,打开时提示“您尝试打开文件'XXX.xls'的格式与文件扩展名指定文件不一致
  • (转)jdk与jre的区别
  • (转)编辑寄语:因为爱心,所以美丽
  • ./configure,make,make install的作用(转)
  • .Net Redis的秒杀Dome和异步执行
  • .Net 高效开发之不可错过的实用工具
  • .NET/C# 获取一个正在运行的进程的命令行参数
  • .net6解除文件上传限制。Multipart body length limit 16384 exceeded
  • .NET程序员迈向卓越的必由之路
  • .net连接oracle数据库
  • [ 转载 ] SharePoint 资料
  • []Telit UC864E 拨号上网
  • [Algorithm][动态规划][路径问题][不同路径][不同路径Ⅱ][珠宝的最高价值]详细讲解
  • [Asp.net mvc]国际化
  • [codevs 2822] 爱在心中 【tarjan 算法】
  • [CSS] - 修正IE6不支持position:fixed的bug
  • [hdu2196]Computer树的直径
  • [LeetCode]—Copy List with Random Pointer 深度复制带“任意指针”的链表