分分钟带你了解字符串、内存函数【C语言】

浅谈怎样才算学好了一门语言(初级篇) 前言 前一段时间,偶尔和同事聊到招聘的事情,互相之间都在抱怨,现在的人呐,自己啥情况都不晓得。 负责招聘的同事A君说,在招聘网上辛辛苦苦筛选了一波简历,电话约了过来面试,结果“问啥啥不会,就要13K”。这种奇葩比比皆是,简直让人啼笑皆非。 我就插了一句嘴,简历上写的那些那些人总会的吧,也没有你说的那么差吧? A君回了一句:你都不晓得,个个简历上都写精通XXX,熟练掌握XX技术。叫过来一面试,... 阅读详情

本篇文章介绍一些字符串函数和内存函数,灵活使用这些函数可以提高你的的编程效率,并且可以让代码变得精练,接下来我们来了解一下这些函数,再模拟实现一些常用的函数。

目录

字符串函数

strlen

strcpy / strncpy

strcat /strncat

strcmp /strncmp 

strstr

strtok

strerror

内存操作函数

memcpy

memmove

memset


字符串函数

strlen

strlen函数的使用相信大家已经不陌生了,是用来求字符串长度的一个字符串函数,这里我们主要来模拟实现一下他的功能。

1.计数器法

size_t my_strlen_count(const char* arr)
{
	assert(arr);
	int count = 0;
	const char * p = arr;
	while (*p++ != '\0')
	{
		count++;
	}
	return count;
}

2.指针减指针法

size_t my_strlen_point(const char* arr)
{
	assert(arr);
	const char* start = arr;
	const char* end = arr;
	while (*end != '\0')
	{
		end++;
	}
	return end - start;
}

3.递归法

size_t my_strlen_recursion(const char* arr)
{
	assert(arr);
	const char * p = arr;
	if (*p != '\0')
	{
		return 1 + my_strlen_recursion(p+1); //将p的位置后移一个单位。
	}
	else return 0;
}

使用strlen的注意事项:

1.strlen的返回值是再字符串'\0'前面出现的字符个数(不包含'\0')

2.strlen参数指向的字符串必须以'\0'结束,要不然strlen无法停止或计算有误

3.strlen的函数返回类型的size_t类型(无符号整形)

这里我介绍几种不同定义方式的字符数组情况:

1.char arr[]=“abcdefg”

这种情况下,arr数组中不仅存放了abcdefg这几个字符,而且在g的后面默认放了一个'\0',strlen计算的值正常。

2.char arr[]={'a','b','c','d','e','f','g'};

这种情况,如果使用strlen函数测量字符串会使strlen计算出随机值,因为这个数组中没有具体设定'\0'作为结束标志,所以会出现计算错误的情况。

 如图,这里我们将abcdefg(a的ascii码值为97)存放到0x008FF954的内存中,可是strlen却测出19的长度,因为strlen并没有在源字符串中测到'\0'('\0'的ascii码为0),strlen从0x008FF967的地址处测到了'\0',所以返回值是19。当我们在使用这种初始化的时候,一定不要忘记在字符串的末尾放上一个'\0'!!!

3.char arr123[10] = { 'a','b','c','d','e','f','g'};

我们知道,限定了大小的数组,如果没有初始化,数组会自动给我们初始化为0,所以在我们指定了大小之后,arr123中剩下未被我们初始化的元素会被自动初始化为'\0'。


strcpy / strncpy

strcpy是一个将源头的字符串拷贝到目标字符串的函数,会是实现覆盖的作用,这里我们来看看他的使用。

这个函数的功能还是比较简单的,接下来我们就来模拟实现它吧。

char* my_strcpy(char* destination, const char* source)
{
	assert(destination && source);
	char* start = destination;
	while (*destination++ = *source++)
		;
	return start;
}

这里我们用start存放目的地的起始地址,拷贝完之后将起始地址返回就可以了,这样返回值可以实现函数的链式访问。

这里的我们仍然要注意:

1.源字符串必须以'\0'结尾。

2.strcpy会将源字符串中的'\0'也拷贝到目标空间中。

3.我们要保证目标空间必须足够大,以确保能存放源字符串。

4.目标空间必须可变,所以源字符串不能被const修饰。


strncpy

strncpy的功能和strcpy的功能相差无几,只是多了一个参数count,这个参数表示strncpy拷贝几个字节。

 我们来看一下如何使用:

 这里有一个注意事项:

如果源字符串的长度小于count,则拷贝完源字符串之后,会在目标的后面追加'\0',直到count个。

第10-14个字符全被拷贝为了'\0'


 strcat /strncat

strcat函数就是将一个字符串追加到另一个字符串的后面,strcpy是拷贝一个字符串,而这个函数可以理解为追加一个字符串。我们来看看具体使用。

这个函数也比较简单,接下来我们来看看这个函数是如何实现的吧。

这个函数的实现与strcpy其实差不多,这里给出一点思路。

1.找到目标字符串的中\0'。

2.将源字符串的内容拷贝到以'\0'为起始位置的目标空间.。(这部分就跟strcpy相似了)

char* my_strcat(char* dest, const char* source)
{
	assert(dest && source);
	char *p= dest;
	while (*dest)dest++;
	while (*dest++ = *source++);
	return p;
}

注意事项:

1.源字符串必须以'\0'结尾,这是必须的。

2.目标空间必须要足够大,能容纳下追加的字符串。

3.它会覆盖掉源字符串的'\0',并且将直接的'\0'拷贝过去。


strncat

strncat函数也只是加上了拷贝的数目count,即从源字符串到目标字符串追加多少个字符。

接下来我们来看看如何使用这个函数。


strcmp /strncmp 

strcmp是字符串比较函数,用来比较到出现另一个字符不一样或者一个字符串结束或者num字符全部比较完(注:不是比较字符串长度的)。这个函数的使用还是比较多的,用于我们字符串的匹配等等。

如果字符串1>字符串2  返回大于0的数;

如果字符串1=字符串2  返回0;

如果字符串1<字符串2  返回小于0的数;

接下来看看如何使用strcmp的

(strcmp)字符串比较函数的实现
1.比较*p1是否等于*p2,如果相等则两个指针向后移动,直到都为'\0'则return 0;

2.如果碰到*p1>*p2或*p1<*p2则判断return大于0或小于0的数。

int my_strcmp(const char* p1, const char* p2)
{
	assert(p1 && p2);
	while (*p1 == *p2)
	{
		if (*p1 == '\0')
			return 0;    //两个相等,如果p1或p2为'\0',表示检测到最后一个字符,返回0;
		p1++;
		p2++;
	}
	if (*p1 > *p2)
		return 1;
	else 
		return -1;

strnrcmp的使用与strcmp相似的,可以控制你想比较的数目,与上面几个函数的使用方法一样,这里就不再赘述了。


strstr

strstr函数的功能是查找str2是否为str1的子串,如果找到了就会返回第一次找到地址的地址。如果没有找到,则会返回空指针。

现在我们来使用一下strstr函数

strstr函数的实现思路:

1.使用r1、r2指针进行查找,如果发现*r1和*r2相等,即首元素相同,使用temp指针保存当前r1位置,这时则r1和r2同时向后进行对比,如果发现不同或r1为'\0'则退出,发现*r2为'\0'了,则返回temp的位置。

2.如果发现不同的情况,我们要使r1回退到temp+1的位置再进行查找。

3.如果发现*r1为’\0'还未查找出结果则返回一个NULL,表示r2不为r1的字串。

char* my_strstr(const char* arr1, const char* arr2)
{
	assert(arr1 && arr2);
	const char* r1 = arr1;
	const char* r2 = arr2;
	const char* temp = arr1;
	while (*temp)        
	{
		r1 = temp;
		r2 = arr2;
		while (*r1 && *r2 &&(*r1 == *r2))  //*r1、*r2不等于‘\0',并且*r1和*r2的值相同。
		{
			r1++;
			r2++;
		}
		if (*r2 == '\0')                  //只有当检查到*r2 == '\0'了返回地址
			return (char*)temp;           //temp是const char*类型;
		temp++;
	}
	return NULL;
}

这个函数的实现推荐大家去模拟实现一下,难度也不是太大,还是比较考验对指针的使用的。


strtok

 函数介绍:

 char * strtok ( char * str, const char * sep );

简单描述它的作用,strtok就是一个可以按照你定义的一些分隔符实现对一串字符串的分隔。

这里sep参数可以是个字符串或是一个分隔符数组。我们可以使用sep中的分隔符来分割str数组中的数据。

这里分三种情况:

①str为非空指针,则strtok会保存第一次出现分隔符的下一个地址,然后将保存的地址作为函数参数返回。

②如果传入的是NULL,则strtok会从上次保存的地址向后查找,查到到分隔符,则会记录下这个分隔符的下一个地址,并将这个地址保存,再将分隔符地址改为'\0',返回保存数据的地址。

③如果没有查找到分隔符了,strtok会返回一个空指针。

这里我们直接来看看strtok函数是如何使用的。

这里除了第一次出现的分隔符没有被置'\0',其余的分隔符全部被置换为了'\0',因为第一次传入的不是空指针,后面的循环传入的全是空指针 ,则strtok会从上次保存的地址开始向后查找,这里我们就可以推测strtock中是存放了一个static修饰的指针来存放地址。

这里我们更不能难发现,strtok会修改掉源字符串中的内容,所以我们通常会将源字符串拷贝一份然后再传入到strtok函数中进行分隔。


strerror

streeor是一个打印错误码的函数。

如果程序发生错误,则会产生一个错误码,每一个错误码会对应一个信息,而strerror的功能就是将错误码转化为错误信息,可以让我们知道出错的原因。

现在我们使用strerror来看看不同的错误码表示的意思分别是什么,比如错误码0、1、2、3。

errno

但是,错误码是动态的,我们一般不会知道发生了错误或是发生了什么类型的错误。这时我们需要知道一个全局变量errno。

errno是错误码的意思,程序发生错误时会产生一个错误码,错误码会被存放到全局变量errno中,这时我们只需要使用strerror函数打印errno就可以知道此时程序发生了什么错误。

这里我们来使用strerror打印errno中的错误信息(errno需要引头文件<errno.h>)。

 这里我们申请一个最大整形的内存,这时内存肯定不会帮我们开辟这么大的空间,所以我们使用strerror打印错误,则会打印出没有足够空间的错误信息。


内存操作函数

在有了上面一些字符串操作函数的了解下,下面的一些内存操作函数其实也就大同小异了,这里就不做太多介绍了,大家知道如何使用和可以模拟实现就问题不大了。 

memcpy

memcpy的使用与strcmp的使用相似,strcpy的操作单位是一串字符,strncpy中拷贝的是我们传入的是字符串中字符的个数,而memcpy操作的是我们传入的字节数,无论是短整型(2)个字节还是整型(4)个字节,memcpy都会按照我们传入的字节数来进行拷贝。

我们来看看如何使用memcpy。

使用起来还是很简单的,下来我们来看看如何实现memcpy这个函数。

void* memcpy(void* r1, const void* r2, size_t count)
{
	assert(r1 && r2);
	void* temp = r1;
	while (count--)
	{
		*(char*)r1 = *(char*)r2;
		r2 = (char*)r2 + 1;
		r1 = (char*)r1 + 1;
	}
	return temp;
}

memmove

如果我们想要将一个字符串中的内容自己拷贝自己,接下来就会发生这样的错误。我们想要的结果无法出现。

 我们发现,如果将arr1中的内容拷贝到arr+2中去,我们想要的是将arr1中20个字节的数据整体拷贝arr1+2的地方,实现数据的移动。

我们预测输出  1 2 1 2 3 4 5 6 7 8 9 10,

而使用memcpy后我们的结果是 1 2 1 2 1 2 1 8 9 10

很明显,这不是我们想要的,我们可以知道,是在memcpy的拷贝中,前段数据将后端数据进行了覆盖,导致拷贝出现了错误,这时我们如果想要实现自身对自身的拷贝,我们可以使用memmove函数。

接下来我们来看看memmove能不能达到我们想要的效果。

结果如上所示,memmove成功地将数据进行了移动,所以,如果有字符串内部的移动拷贝,我们可以交给memmove函数。

接下来,我们了解了memmove函数的作用,我们可以来试着模拟实习一下memmove函数的功能。

首先我们要分析为什么memmove不会覆盖掉我们要拷贝的数据。

有了上面的拷贝分析,结合memcpy的过程,实现memmove应该不会太难。

 下面我们来看如何具体实现

void* my_memmove(void* dest, const void* sou, size_t count)
{
    assert(dest && sou);
	void* temp = dest;
    if (dest == sou)
		return temp;
    if (sou > dest)   
	{
		while (count--)
		{
			*(char*)dest = *(char*)sou;
			sou = (char*)sou + 1;
			dest = (char*)dest + 1;
		}
	}
    else
	{
		while (count--)
		{              //sou+19刚好指向最后一个字节。
			*((char*)dest + count) = *((char*)sou + count);
		}
	}
	return temp;
}


memset

  • s指向要填充的内存块
  • c是要被设置的值。
  • n是要被设置该值的字符数。
  • 返回类型是一个指向存储区s的指针。

接下来我们来看看如何使用:

这个函数还是比较好使用的,通常我们使用只要我们不把要置换的字节数搞错基本没什么错误会出现。

本片博客的介绍就此结束了,本篇介绍的函数有点多,其实我们只用知道是如何使用的就行了,所以这里我也只是地将使用和实现描述了一下,这样有利于我们以后熟练地使用这些函数,提高我们的编程效率,有更多方便快捷、功能强大的函数在以后我会一一介绍给大家。

⑩电子产品拆解分析-家用无线遥控开关433Mhz ①免布线随意贴,装上就能使用解决单线开关烦恼;②遥控配对简单,无线通讯距离长,信号可穿墙; 阅读详情

相关推荐

MAS1102量产工具实战指南:从下载到开卡,附固件选择与RDT优化技巧

本文提供MAS1102量产工具的实战指南,涵盖从工具下载、短接识别到开卡操作的全过程。重点解析了固件选择策略与RDT优化技巧,帮助用户成功修复基于联芸MAS1102主控的固态硬盘,解决常见开卡错误并提升SSD性能与稳定性。

c2d3e4f的博客 2203

C语言数组

数组C语言

fear_wolf的博客 534

【UE5】虚幻引擎Gameplay框架

游戏实例(UGameInstance)会在引擎启动时实例化,并保持活跃直至引擎关闭。这是一种管理器类,在游戏中不存在实体,但会追踪数据和运行代码。在联网多人游戏中,游戏实例不会被复制,而是独立存在于服务器以及所有互联的客户端上。所有你希望在关卡加载间保持的内容都应存于游戏实例中。例如,游戏实例是管理游戏保存系统的到地方。游戏实例还可以充当任意数量的 游戏实例子系统 的管理器,这些子系统由游戏实例创建和销毁,并且与游戏实例本身具有相同的生命周期。在线子系统就属于这类子系统。

一个写程序的 1796

2022.4.19 关于字符串函数介绍

strlen size_t strlen( const char * str ); 该函数以字符串的 '\0' 作为结束标志,返回字符串中 '\0' 前出现的字符个数且不包括 '\0' 本身 注意:size_t 为无符号的整型,所以strlen返回的值为无符号的整型! 举例1: #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string.h> int main() { char arr[] ...

weixin_63888301的博客 544

QT下利用FFTW实现功率谱密度分析(周期图法)

写在前面 出于项目需求,需要在QT的msvc 2015编译环境下实现功率谱密度估计。 所以这个需求很直接的关键词就是 1. C++ 2. QT 3. 傅里叶变换 4. 功率谱密度估计 但是在网上搜索了很久,没有一个非常直接的答案。所以我觉得很有必要写一篇文章来说明,在QT msvc2015 32bit环境下如何实现功率谱密度估计。 本文并没有经过严格编辑,但代码是已经可以跑通的,如...

李时珍食疗志的博客 5223

3分钟搞懂欧式距离变换(EDT):从暴力算法到Felzenszwalb的演进史

本文系统梳理了欧式距离变换(EDT)从暴力算法到高效线性算法的演进历程。重点解析了光栅扫描算法和Felzenszwalb算法的核心思想与实现,并探讨了其在机器人路径规划中生成欧几里得符号距离场(ESDF)的关键应用,为开发者提供了清晰的算法选型与实战指南。

fern8的博客 978

初识C语言(二)

目录 字符串+转义字符+注释 (1)字符串 (2)转义字符 (3)注释 选择语句 循环语句 函数 数组 (1)数组定义 (2)数组的使用 字符串+转义字符+注释 (1)字符串 "hello world.\n" 这种由双引号(double Quote)引起来的一串字符称为字符串字面值(String Literal),或者简称字符串 注:字符串的结束标志是一个\0的转义字符。在计算字符串长度的时候\0是结束标志,不算作字符串内容。 //下面这段代码,打印的结果是什么呢?为什

weixin_51885188的博客 493

自动驾驶小车DIY:树莓派+激光雷达实现DWA路径规划(从仿真到实车)

本文详细介绍了如何基于树莓派与激光雷达,从零搭建一套完整的自动驾驶小车系统,并实现DWA局部路径规划算法。内容涵盖硬件选型、ROS环境部署、DWA算法原理与仿真,以及关键的实车调试与性能优化技巧,为创客和竞赛爱好者提供了一套低成本、高可行性的自主导航解决方案。

kiwi8的博客 530

char arr[] 和 char *arr区别

char arr[] = "hello world";//arr为数组的名称,数组中的内容在栈中, 出去数组所在的作用域,所占用的空间就被释放。 char *arr = "hello world";//arr为指针,arr占用的内存为栈中的内存, 但其指向的内存在静态存储区,静态存储区的空间在程序结束的时候,才被释放。 下面是一个小的程序,GetString01() 和Ge

yang20141109的专栏 5905

保姆级教程:用CameraX API快速搞定Android多摄像头切换与预览(附避坑指南)

本文提供了一份详细的CameraX API教程,帮助开发者快速实现Android多摄像头切换与预览功能。通过简化API设计和生命周期感知能力,CameraX大幅降低了开发复杂度,同时解决了多摄像头兼容性、预览优化等常见问题。文章包含完整代码示例和实战避坑指南,特别适合需要高效集成相机功能的Android开发者。

weixin_42699679的博客 166

48、量子系统中的信源编码

本文深入探讨了量子系统中的信源编码理论与应用,详细介绍了盲编码与可见编码、定长编码与变长编码四种主要信源编码方案。文章从经典信源编码出发,对比分析了量子场景下的压缩特性,并系统性地阐述了量子定长信源编码的构建方法及相关定理证明。同时,讨论了通用量子定长信源编码的设计思路及其在实际应用中的优势与挑战。通过理论分析与实验进展的结合,为量子信息存储、传输和处理提供了重要的理论基础和技术支持。

m2n3b4v5c6的博客 100

【C语言】字符数组的定义及使用

字符型数据是以字符的ACSII代码存储在代码单元格中的,一般占一个字节。由于ASCII代码也属于整数形式,所以C99标准中,把字符类型归纳为整形类型中的一种。用来存放字符型数据的数组称为字符型数组,在字符数组中一个元素内存放一个字符。定义字符型数组的方法与定义数值型数组的方法类似,例如:由于字符型数组是以整数形式存放的,也可以用整形数组来存放字符型数据,缺点就是浪费空间,一个字符只占一个字节,而一个整形数据占四个字节,将字符放在整形数组中会浪费空间。

Mr_star_galaxy的博客 1万+

【ZYNQ】OV5640 图像采集与显示

OV5640 是豪威(OmniVision)半导体公司推出的高性能的 CMOS 数字图像传感器,支持最高 500 万像素图像采集,支持 RAW RGB、RGB565、YCbCr422 等图像格式输出,可应用于手机、平板等电子设备。本文主要介绍如何使用 Zynq 驱动 OV5640 摄像头进行图像采集,并通过 HDMI 实时显示。

洋洋Young的博客 1433

iOS开发分分钟搞定C语言—— 字符串和指针

指针

IOS_龙的博客 1657

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

C语言指针(分分钟玩转)

何为指针 指针这玩意说白了,就是用来存储一个变量地址的东东 如图: (编辑器为vc2010) #include<stdio.h> void main(){ int a,*p; a=5; p=&a; printf("a=%d,p=%p,*p=",a,p,*p); getchar(); } 所以通过刚刚的情况,我们发现通过指针我们不仅可以获取一个变量的值还可以直接对变量的值修改 又如下面的例子: #include<stdio.h> void main(){ in

`or 1 or 不正经の泡泡 2336

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

iOS开发分分钟搞定C语言——函数

一、什么是函数? C语言源程序是由函数组成的。虽然在前面各章的程序中大都只有一个主函数main(),但实用程序 往往由多个函数组成。函数是C源程序的基本模块,通过对函数模块的调用实现特定的功能。二、函数的分类 在C语言中可从不同的角度对函数分类。 (1)从函数定义的角度看,函数可分为库函数和用户定义函数两种。 stdio.h stdlib.h. (2)库函数:由C系统提供,用户无须定义,也不

求知若渴,虚心若愚,努力前行,未来可期。 1372

C语言字符串处理全解析:从内存布局到安全编程实战

字符串是编程中的基础数据类型,用于存储和操作文本数据。在C语言中,字符串以字符数组形式存储,通过空字符'\0'标识结束,其底层原理涉及内存管理和指针操作。理解字符串的内存布局和操作机制对于编写高效、安全的代码至关重要,能有效避免缓冲区溢出和内存泄漏等常见问题。在系统编程、嵌入式开发和高性能服务器等场景中,字符串处理能力直接影响程序的稳定性和性能。本文聚焦C语言字符串的核心机制,深入探讨字符数组与指针的区别、标准库函数的安全用法,并结合动态内存管理和安全编程规范,提供一套完整的字符串处理实战指南。

weixin_31856057的博客 252

iOS开发分分钟搞定C语言 —— 函数

函数

IOS_龙的博客 668

C语言字符串数组输入的七种武器(避坑指南)

(终极忠告)字符串处理是C语言的深水区,多写多调试才是王道!记得每次malloc都要想好free,每个数组访问都要检查边界。函数会自动分配内存并复制字符串,但记得它不是标准库函数(在<string.h>中),有些编译器可能需要特定头文件。重点来了:用完记得反向释放内存!我敢打赌90%的C语言新手都不知道这个函数!不限制长度,分分钟缓冲区溢出给你看!(血泪教训)记得数组长度减一留个位置给终止符。(重要提醒)静态数组声明必须明确长度!这个坑我见过无数人掉进去。(必看结论)墙裂推荐使用fgets!

CodeHorizon的博客 467

C/C++内存管理讲解

超详细的C/C++内存管理讲解,对象都是靠自己new出来的。

weixin_53811859的博客 2135

告别strcat与strtok:手写C风格字符串的现代split与join

本文深入探讨了C语言中传统字符串处理函数strcat和strtok的安全隐患,如缓冲区溢出和线程安全问题。为提供更现代、安全的解决方案,文章详细讲解了如何从零开始手写实现split与join函数,涵盖单字符与多字符分隔符的处理、精确的内存管理以及错误处理,旨在帮助开发者告别旧有风险,掌握高效、可控的字符串分割与拼接技术。

weixin_29009339的博客 319

C语言零基础入门指南:从编译环境搭建到核心语法精讲

编程就像学游泳,光看教程不下水永远学不会。遇到bug别慌——我刚开始写个Hello World都能报10个错!记住:每个程序员都是踩着bug成长的。坚持写代码,三个月后回头看看,你会惊讶自己的进步!

xiaoqian9997的博客 1101

Go~简介与特性,分分钟搞定

Go的特点并发模型内存分配垃圾回收静态链接标准库工具链为并发而生的Go语言Go语言简介Go语言不但能让你访问底层操作系统,还提供了强大的网络编程和并发编程支持。可以进行网络编程、系统编程、并发编程、分布式编程。具有“部署简单、并发性好、语言设计良好、执行性能好”等优势。Go 从C语言继承了相似的表达式语法、控制流结构、基础数据类型、调用参数传值、指针等很多思想。因为Go语言没有类和继承的概念,所以它和 Java 或 C++ 看起来并不相同。但是它通过接口(interface)的概念来实现多态性。Go语言有一

2301_82243100的博客 913

iOS开发核心语言Objective C —— 所有知识点总结

1. OC中主要开发在什么平台上的应用程序? 答:可以使用OC开发Mac OS X平台和iOS平台的应用程序 2. OC中新增关键字大部分是以什么开头? 答:OC中新增关键字大部分是以@开头 3. OC中新增加了那些数据类型? 答:Block类型 指针类型(Class, id类型) 空类型 特殊类型(SEL, nil) 4. 面向对象特性是什么? 答:继承性,封装性,多态性

求知若渴,虚心若愚,努力前行,未来可期。 5571

cJSON内存管理实战:避免常见陷阱与正确释放策略

本文深入解析cJSON库中cJSON_free与cJSON_Delete函数的核心区别与正确使用场景,帮助开发者避免常见的内存泄漏和程序崩溃陷阱。通过实战案例,详细阐述了JSON对象树与打印字符串的所有权管理,并提供了构建健壮内存释放流程的最佳实践,确保C语言项目稳定高效。

weixin_29194255的博客 328

Objective - C —— 语言简介及特性

本分享是面向有意向从事iOS开发的伙伴们,或者已经从事了ios的开发者。如果您对iOS开发有极高的兴趣,可以与我一起探讨iOS开发,一起学习,共同进步。如果您是零基础,建议您先翻阅我之前分享的iOS开发分分钟搞定C语言系列,然后在开始Objective C语言的学习,如果您遇到问题也可以与我探讨,另外将无偿分享自己整理的大概400G iOS学习视频及学习资料,都是干货哦!可以新浪微博私信➕关

Guizy 1298
上一篇: 【C语言】指针进阶笔试练习题
下一篇: 【C语言】自定义类型——结构体(1)
Brant_zero2022
博客等级 码龄5年 582粉丝 108原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Brant_zero2022

素材免费分享不求打赏,只求关注

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值