C/C++相关概念和易错知识点(6)(字符串函数)

C语言/C++指针知识点总结详解 C++指针1、什么是指针2、指针定义和赋值3、引用指针变量4、指针作函数参数5、字符串与指针6、函数与指针7、指向指针的指针8、const指针相关【难点】9、void类型指针10、有关指针数据类型的小结 1、什么是指针 如果把某一块已经开辟的内存空间比作房间,那么指针就是一把钥匙。房间有大有小,而钥匙就那么大,所以指针所占用的字节为4字节。这把钥匙可以根据你的设定来让它开哪个房间,但是,最多只能开... 阅读详情

前言:这篇博客主要用于字符串函数的实现,而淡化了相应的语法细节,具体的使用细节可以在C语言相关概念和易错语法(5)中查看,这篇博客中只会重复比较重要的。

size_t引用的头文件(选其一):<stddef> <stdio> <stdlib> <string> <time> <wchar>

NULL引用的头文件(选其一):<stddef> <stdlib> <string> <wchar> <time> <locale> <stdio>

字符串函数和内存函数共有注意事项:传的所有参数均不能为NULL

1.strlen

标准格式:size_t strlen(const char* str);    

(1)size_t是无符号数导致的陷阱

对strlen返回值的任何操作均为无符号数(正数),因此在遇到1-2这种算式时,size_t类型对应计算结果是个很大的数字,因为其补码首位并不代表符号位

315b04c893cc40dc919e6095b4d81ca2.png

当然,你可以使用强制类型转换来达到你原来想要达到的目的,但前提是你必须知道要这么做。

(2)strlen传递空指针导致程序的错误

strlen不能传入空指针,因此在自己实现strlen函数的同时要注意使用assert来进行断言,使函数更加安全

128da5ac16e84400a764c7a42695ae13.png

以下是利用递归模拟实现strlen函数的方法:


#include <stdio.h>

#include <assert.h>

size_t my_strlen(const char* arr)
{
	assert(arr);
	
	if (!*arr)
	{
		return (size_t)0;

	}
	else
	{
		return (size_t)1 + (size_t)my_strlen(arr + 1);
	}
}

int main()
{

	char arr[] = "Hello,world!";

	printf("%d\n", (int)my_strlen(arr));

	return 0;
}

(3)由strlen延伸的函数strnlen

标准格式:size_t  strnlen(const char* str, size_t num)

这个函数不太常用,但根据其它该类型的函数,你也可以猜出它的功能:

i有限定作用,决定strnlen计算大小的最大值

ea36cc547dae423da3fb65544b300df7.png

2.strcpy

标准格式:char * strcpy ( char * destination, const char * source )

返回的是char * destination中的char*

(1)这个函数需要注意的是在copy时源字符串包括\0都会被拷贝

(2)不能传NULL

在这里只有p1是空指针,p2是常量字符串

(3)目标数组一定要给大小且大小一定要合适,否则拷贝可能会出现越界访问的情况

可以看到,arr1被越界访问,原有字符全部被替换,\0也被#替换,导致printf在打印时也出现越界访问

下面是模拟实现strcpy的代码:


#include <stdio.h>

#include <string.h>

#include <assert.h>


char* my_strcpy(char* arr2, const char* arr1)
{

    assert(arr2 && arr1);
 
	char* str = arr2;

	while (*arr2++ = *arr1++);

	return str;
}


int main()
{

	char arr1[] = "Hello,World!";

	char arr2[20] = "####################";

	my_strcpy(arr2, arr1);

	printf("%s\n", arr2);

	return 0;


}

实现效果如下

需要注意的是,while括号内部的表达式都会正常执行,执行之后的返回值作为while评判的值,如果为0(假)就停止,这里当读到最后一个\0时,表达式先执行,所以arr1中的\0成功被赋给arr2,然后表达式返回0被判为假,跳出循环。

(4)strcpy延伸函数strncpy

标准格式:char * strncpy ( char * destination, const char * source, size_t num )

注意:strncpy拷贝时有num参数确定要拷贝多少个字符,源字符串大小<num时,默认补\0,

中途遇到\0会停止对source的访问,默认将剩下要求的个数的元素全部改为\0

源字符串大小>num时,不会拷贝\0,这点要和strcpy区分

3.strcat

标准格式:char * strcat ( char * destination, const char * source );

根据这3个函数,可以总结出参数部分一般源在后,目标在前

(1)strcat覆盖目标字符串\0,并将源字符串包括\0一并追加过来,之后停止 strncat回将指定大小的字符追加过来,但最后还会补一个\0,追加的大小相当于num+1,如果追加的个数刚好是sizeof arr,最后会有两个\0,因为无论什么情况,strcat都会再加上一个\0

(2)追加找的是destination的\0,如果在你的字符串中有\0,会直接从\0开始追加并把后面的值全部覆盖

(3)destination一定要指定大小,不然很大可能会越界访问

下面是模拟实现strcat的代码


#include <assert.h>


#include <stdio.h>


#include <string.h>


char* my_strcat(char* arr1, const char* arr2)
{

	assert(arr1 && arr2);

	int i = 0;

	int j = 0;

	int sz1 = (int)strlen(arr1);

	int sz2 = (int)strlen(arr2);


	for (i = 0; i < sz1; i++)
	{
		if (!arr1[i])
			break;

	}//i就是要追加的位置,也表示前面有多少个字符


		while (arr1[i++] = arr2[j++]);


	return arr1;

}


int main()
{

	char arr1[20] = "Hello,";

	char arr2[] = "World!";

	printf("%s\n", my_strcat(arr1, arr2));


	return 0;
}

(4)strcat延伸函数strncat

标准格式

char * strncat ( char * destination, const char * source, size_t num );

strncat中追加的num源字符串大小时,只会将源字符串到\0追加,不会再多加\0

其他功能均与前面的函数相似,不再阐述

4.strcmp

标准格式:

int strcmp ( const char * str1, const char * str2 );

(1)arr1 - arr2,大于就返回大于0的数,小于就返回小于0的数

(2)strcmp不是比较字符串的长度,而是比较对应下标字符的ASCII码值谁大。比如"abcdef"和"acb",后面的字符串比前面的字符串大,因为同为下标1时,c的ASCII值比b大。

下面是strcmp的模拟实现



#include <assert.h>


#include <stdio.h>


#include <string.h>


int my_strcmp(const char* arr1, const char* arr2)
{

    assert(arr1 && arr2);

	int i = 0;

	int j = 0;//不能只用一个i,arr1[i++] == arr2[i++]这种行为未定义,属于无效代码

	while (arr1[i++] == arr2[j++])//当两者不等时,i和j依然会继续进行一次++操作,因此i和j在任何情况下都会大1
	{
		if (!arr1[i - 1]|| !arr2[i - 1])//防止越界访问,这里i已经多加了一个1,所以是i-1,不能用i--,这样会导致i连续减2次
			break;

	}

	i--;

	j--;

	return arr1[i] - arr2[j];
}




int main()
{
	char arr1[] = "Hello!";

	char arr2[] = "Hola!";

	printf("%d\n", my_strcmp(arr1, arr2));


	return 0;
}

(3)strcmp的延伸函数strncmp

标准格式:

int strncmp ( const char * str1, const char * str2, size_t num );

strncmp只比较num个字符,这个函数比较简单,不再阐述

5.strtok

标准格式:

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

(1)这个函数要学会使用,主要用于分割字符串,达到分离信息的目的,可借助for的巧妙之处一次性达到目的

(2)分割过程忽略连续的分隔字符,且分隔字符串中字符的顺序没有任何影响

(3)分割字符串中最好不要有\0,\0之后的字符不会起效

同样,被切割字符串也要注意\0的位置,\0之后的字符都会被忽略

下面是strtok的模拟实现:



#include <stdio.h>


#include <string.h>


#include <assert.h>


char* my_strtok(char* arr1, const char* arr2)
{
	assert(arr2);//arr1可以是NULL

    //当第一次传进来arr1时,初始化一个静态变量

	static char* str = NULL;

	if (!arr1)
	{
		arr1 = str;
	}

	int sz1 = (int)strlen(arr1);

	int sz2 = (int)strlen(arr2);//字符串中最好都不要\0,strlen有限制


	if (!sz1)
		return NULL;
	
	int i = 0;

	for (i = 0; i < sz1; i++)
	{
		int j = 0;


		for (j = 0; j < sz2; j++)
		{

			if (arr1[i] == arr2[j])//在i这个位置应该分割
			{
	
				arr1[i] = '\0';

				str = arr1 + i + 1;//跳过\0,记录新的字符串的起始点

				return arr1;

			}

		}

	}

	str++;

	return arr1;

}




int main()
{
	char* p = NULL;

	char arr1[] = "192.168.200.2";

	char arr2[] = ".";

	for (p = my_strtok(arr1, arr2); p != NULL; p = my_strtok(NULL, arr2))
	{
		printf("%s\n", p);

	}

	return 0;
}

6.strerror

标准格式:

char * strerror ( int errnum );

这个函数是用来储存错误信息(在调用完一次库函数的时候),我们可以利用它来获取在调用库函数的过程中可能遇到的一些问题,一般来说要和errno配合使用,因为库函数的错误码是写在errno这个全局变量上的,注意要引用头文件<errno.h>

下面用一段模拟库函数给errno赋值的代码来说明strerror的作用:


#include <errno.h>

#include <stdio.h>

#include <string.h>

int Fun(void* p)
{

	if (!p)
	{
		errno = 1;

		return -1;

	}

	else
	{
		errno = 0;

		return 0;

	}

}


int main()
{
	int i = 0;

	Fun(NULL);

	printf("%s\n", strerror(errno));

	Fun((void*) & i);

	printf("%s\n", strerror(errno));


	return 0;
}

运行的结果是

这个错误信息是我自己设置的,因此打印的时候就会显示我设置的错误码对应的信息,在我们使用的库函数的内部,都会有这样一个操作,在当库函数执行异常时修改errno的值,以供程序员参考。值得注意的是,errno存在覆盖现象,所以要注意及时使用。

7.strstr

标准格式:

const char * strstr ( const char * str1, const char * str2 );

char * strstr ( char * str1, const char * str2 );

strstr是找到参数中后一个字符串在前一个字符串中出现的位置,找不到就返回NULL,找到就返回第一次出现的首元素的首地址

下面是模拟实现strstr的一个方法:



#include <stdio.h>


#include <string.h>


#include <assert.h>


const char* my_strstr(const char* arr1, const char* arr2)
{

	assert(arr1 && arr2);

	int sz1 = (int)strlen(arr1);

	int sz2 = (int)strlen(arr2);

	if (sz2 > sz1)
		return NULL;

	if (sz1 == sz2)
	{
		if (arr1[0] != arr2[0])
			return NULL;
	}

	if (!sz2)
		return arr1;

	

	int i = 0;

	for (i = 0; i < sz1; i++)
	{
		int j = 0;

		int k = 0;


		for (j = 0, k = 0; j < sz2; j++, k++)
		{
			if (arr1[i + k] != arr2[j])
				break;
			if (k == sz2 - 1 && arr1[i + k] == arr2[j])
				return (const char*)arr1 + i;


		}


	}

	return NULL;


}

int main()
{


	char arr1[] = "Hello,World!";

	char arr2[] = "W";

	printf("%s\n",my_strstr(arr1, arr2));

	return 0;
}

在这里,我使用的是双重for的方式,当然,你也可以使用双指针来实现这个函数,它们的本质都是BF算法,还有一种KMP算法更加高效,后面的博客我会专门讲解。

代码上的注意事项:

在前面strcpy,strcmp我都采用了一种基于while(表达式)来实现一定的技巧。这其中有一点容易混淆:

先看下面这段代码,思考为什么num是-1而不是0

这就涉及到后置减的执行逻辑了,这里比较细节,但又确实很重要

(1)num值2传给while作为表达式的返回值,为真,但在进行下一步操作前(执行while内部表达式之前)num--为1

(2)执行了内部表达式(空表达式)num的值依然是1,这时num再传给while值1作为表达式的返回值,为真,但在进行下一步表达式之前num--为0

(3)在执行完空表达式后num的值是0,这时传给while值0作为表达式的返回值,为假,应该跳出循环,但就像前面两步一样,在进行“跳出循环”操作前,num--为-1,于是,num在经历这样的操作后最终值是-1

其根本原因是num--是后置减,返回值是在减操作前就传过去了,然后紧接着就会进行减操作,该操作和前面的传回表达值的操作相绑定,也就是说无论外界什么情况,无论发生什么,num最终都会减1

C++中size_t类型详解:探究其特性与用途,附带源代码示例 本文介绍了C++中的size_t类型,以及它的特性和用途。我们通过示例代码展示了size_t类型的具体应用场景,希望能够帮助读者更好地理解和使用size_t类型。size_t是C/C++中定义的一个无符号整数类型,用于存储内存块的大小、数组元素的个数以及对象的大小等信息。在本文中,我们将深入了解size_t类型的特性和用途,并提供相应的源代码示例。在上述代码中,我们使用sizeof运算符计算了数组arr的长度,并将结果赋值给size_t类型的变量length。三、size_t类型示例代码。 阅读详情

相关推荐

002_[string.h]c标准库函数之<string.h>

话说c中有很多标准库函数,其中最具特色的就是字符串相关的库函数,而这类函数也是最让人头大的,当然,熟悉后就不大了,头就小了,哈哈,以下是自己的温习记录以及心得,拿出来与同行们分享下,希望有错误的地方大家给指出来,3Q,话不多说,我们开始......

qq_47325567的博客 791

size_t

之前在《内存拷贝的注意事项》一文中提到过size_t,可能许多人对这个类型不太熟悉没有用过或者根本不敢去用,最近看到一篇文章对这个类型讲的比较详细,便翻译过来让不熟悉的同学可以知道它产生的原因以及如何使用。   原文地址: Why size_t matters 前言:使用size_t可能会提高代码的可移植性、有效性或者可读性,或许同时提高这三者。 在标准C库中的许多函数使用的参数或者返回值都是表示的用字节表示的对象大小,比如说malloc(n) 函数的参数n指明了需要申请的空间大小,还有memcpy(s1,

Wang20122013的博客 2744

iOS反编译-hook微信之艾特所有人

all。

2501_90243249的博客 759

关于size_t

专门用于表示对象的大小、内存分配的长度以及数组的索引。它是标准库中广泛使用的类型,确保代码的可移植性和平台兼容性。

jikelk的博客 693

基于openwrt平台搭建局域网技术验证之四

1、测试目的 验证l2tp客户端模式的可行性。 提供vpn-l2tp模式的客户端功能。 2、参考资料 参考链接1:https://www.lucktang.com/191.html 3、测试过程 测试过程需要用到的资源: 路由器俩个 win7系统电脑俩台 ③ 交换机一个 ④ 网线三根 测试组网如下图所示: 组网说明: R0公司路由器 S1 交换机 R1 路由器1 R2 路由器2 PC1 个人电脑1 PC2 个人电脑2 (R0) lan口接(S1)...

caofengtao1314的专栏 1960

Pyinstaller 打包 Pyzbar 时缺失 DLL 文件的排查与修复指南

本文详细解析了使用Pyinstaller打包Pyzbar库时,因缺失关键DLL文件导致程序闪退的常见问题。文章提供了从问题复现、错误诊断到最终修复的完整解决方案,核心在于通过修改.spec配置文件,手动将缺失的libzbar-64.dll等文件添加到打包过程中,确保生成的可执行文件能独立运行。

wdx012345的博客 504

认识 size_t 和指针类型的大小

size_t 类型定义在 C++ 中的 cstddef 头文件中,该头文件文件是 C 标准库的头文件 stddef.h 的 C++ 版。它是一个与机器相关的 unsigned 整型类型,其大小足以保证存储内存中对象的大小。

Doublelv 的博客专栏。 1万+

ArcGis布局视图中Excel表格无边框插入与图例符号边框定制技巧

本文详细解析了在ArcGis布局视图中实现Excel表格无边框插入与图例符号边框定制的专业技巧。通过源头净化Excel表格、精准粘贴以及分解图例并单独设置边框属性,有效解决了地图报告中常见的视觉粗糙问题,帮助用户提升专题图与报告的精致度与专业感。

weixin_29292535的博客 305

C/C++相关概念和易错知识点(7)(memcpy和memmove、文件函数)

由于char 只有8个bit位的存储空间,所以它最多能表示256个数字(包含0),但在signed char中,由于存在原反补的存储规则,导致01111111是最大的正数,对应过来是127,如果再加,就会是10000000,除符号位按位取反+1得到1 00000000,截断后本应是0,但这和0000000冲突了,也就是说0会出现两次,因此规定在这种情况下,127+1 = -128。(2)有效数字,一般情况下,科学计数法的有效数字都是1.xxxx形式,所以自动忽略1,回算时再主动添加上去,

SGlow0708的博客 2478

测站坐标系统 -- 东北天(ENU)坐标系、站心坐标系

测站坐标系统以观测站(或地面上某一个观测点为中心建立坐标系统,将这类坐标系称为测站坐标系统。测站坐标系通常以用户所在的位置点P为坐标原点三个坐标轴分别是相互垂直的东向北向和天向,因而测站坐标系又称为东北天(ENU)坐标系。由于测站坐标系以站心为坐标原点,因此也称为站心坐标系。如图所示,测站坐标系的天向与大地坐标系(LLA经纬度坐标系)在此点的高程方向一致。测站坐标系固定在地球上,本质上是一种地固坐标系。(1)以站心为坐标原点。(2)Z轴与站心点的椭球法线重合,向上为正。

qq_43381998的博客 1万+

Python之afdx包语法、参数和实际应用案例

Python 的 afdx 包是针对 AFDX 协议的轻量级开发工具,专注于 AFDX 数据帧的解析、构造、发送/接收、协议合规性校验等核心能力,广泛应用于航空电子设备测试、仿真、数据监控等场景。

王国平的博客 982

C/C++相关概念和易错知识点(5)(嵌套和回调、错误码、内存函数)

用一种简单不混淆的话来说,放入成员变量时,截至要研究的地址处结构体占用的字节大小就是偏移量大小,在完全不放数据时,偏移量为0,放入一个char的数据后,char末尾处偏移量为1,但称这个char放在0偏移处,因为char的起始位置位于偏移量为0的位置。注意i在重复使用,这两个i的生命周期都一样,从程序开始到程序结束,但这两次出现的i的作用域不同,由struct创建的i相当于全局变量,整个程序都能使用,但后面struct内部的i作用域只能在括号{}内使用,因此它们不会相互影响。栈区用于创建临时变量,函数等。

SGlow0708的博客 1344

热视觉2:使用Python和OpenCV从图像中测量温度

这篇博客将介绍学习热/中远红外视觉的基础知识,gray8 和 gray16 图像(即最常见的热成像格式)之间的差异,学习如何使用Python和OpenCV从热图像中的每个像素点测量温度,并以不同的调色板显示结果。以及如何实时计算视频流和UVC热像仪的每个像素温度。

qq_40985985的博客 6712

C/C++相关概念和易错知识点(59)(C/C++缓冲区同步刷新、IO流)

cin和cout是绑定的,意思是调用cin就会先刷新输出缓冲区,调用cout就会先刷新输入缓冲区,这和前面我们遇到的效率问题类似。

SGlow0708的博客 1242

手把手教你学simulink(24.4)--Simulink在机器人视觉场景下的应用——基于视觉的物体跟踪与抓取

该系统集成了图像处理、目标检测、运动估计、路径规划、抓取控制和视觉反馈等多个功能模块,能够实现实时处理视觉数据、检测并跟踪移动物体、规划最优路径并控制机械臂进行精确抓取。本项目的目标是使用Simulink和MATLAB设计一个基于视觉的物体跟踪与抓取系统,该系统能够实时处理图像数据,检测并跟踪移动物体,规划最优的抓取路径,并控制机械臂进行精确抓取。为了验证系统的性能,我们在Simulink中搭建了基于视觉的物体跟踪与抓取系统的仿真模型。

MHD0815的博客 256

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

C/C++相关概念和易错知识点(31)(npos、string的基本使用)

但由于string的设计相对来说很复杂(string设计在STL之前,时间太早不太成熟,设计出现了很多冗余的接口),平时使用的时候就主要使用关键的几个,保证功能的实现即可,所以这篇文章会分享一些基础的有用的接口。用来查询字符串允许的最大长度,几乎没什么用,因为一般情况不会触及到这个最大值,下面是在x64下允许存储的最大长度,相当于有符号long int能存的最大值,需要8589934592G的空间,这是不可能达到的。但是我们要注意的是这里面有很多的构造函数,在使用的时候是去找最匹配的。

SGlow0708的博客 1835

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

C/C++相关概念和易错知识点(38)(array、模板)

对于普通函数,就算我们不去调用它,编译器在编译阶段是会比较深入的去检查的,这里由于"a"是常量字符串,不能修改,所以交给arr的指针不能*arr,因此要用const char*,所以报错了。函数模板的特化和类模板的特化用法上都很好理解,实际就是针对一些很特殊的类型做特殊的处理,注意要写template<>,这其实是声明这是个模板,没有模板参数就不写,在函数名或类名后要写实例化的类型。在优先级上,如果已经定义了普通函数,就会最优先调用普通函数,其次找特化,如果实在没有,就会去实例化模板函数。

SGlow0708的博客 1291

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

C/C++相关概念和易错知识点(12)(字符数组的修改、sscanf、sprintf)

对于这个变量有一个特殊操作就是&arr,这个操作是取出整个数组的地址,整个数组的地址是首元素的地址,所以&arr和arr得到的值是相同的。arr这个指针还有个常属性,即arr存储的值不能被修改,类似于const int* p,这就导致arr的指向的空间区域在一开始就确定了,不能被修改了。在上面这张图中,我们可以看到如果我们想要将"Hello"存到数组,直接赋值操作是不行的,因为就像上面所说的,这个临时变量同样具有常属性,这个临时变量我们是看不到的,如果有变量接收就把这个临时变量的值赋给这个变量。

SGlow0708的博客 3188

C/C++相关概念和易错知识点(11)(二级指针、数组指针、函数指针)

我们知道,数组指针是对整个数组取地址,即&arr,假设这个指针表示为int (*parr) [10] = &arr,那么*parr得到的就是*(&arr)即arr,相当于首元素地址,也就是int*,所以首元素的地址也可表示为int* p = *parr。注意数组指针的本质是指针,它存储的值是数组的首元素地址,象征着它指向的对象是一个数组。&arr是对整个arr取地址,是二维数组的指针,第一次解引用得到arr,首元素(数组)的地址,即一维数组指针,第二次解引用是对元素数组解引用,得到首元素(整型)的地址。

SGlow0708的博客 1246

C/C++相关概念和易错知识点(33)(string的模拟实现)

借助复用我们可以进一步实现erase,当从pos开始全部删除时用swap,其余情况分成两段insert,最后加起来,这里我提前用了operator+,operator+很好实现,只是我这里讲解的顺序不一样。当存储字符少于15个的时候(实际开了16个字节,预留一个给\0),就存到_buff里,多了就全部移到_str中。比较运算符重载我们其实只需要实现其中的一两个,其它全部用上层逻辑联系起来,可以很快实现。利用复用,我们的代码可以非常简约,但是实际上执行的复杂度是没有改变的,大部分的代码是很简单的,

SGlow0708的博客 673

C/C++相关概念和易错知识点(55)(异常、智能指针)

如果arr1开辟失败要抛异常,如果arr2开辟失败也要开辟异常,arr3同理,而且还可能出现arr1和arr2都开辟好了,但arr3开辟失败,这个时候还要处理arr1和arr2的释放。,如连接服务器我们不会一次就成功,需要多尝试几次,不能一失败就终止程序。我们可以看到fun2抛出异常后,会层层往上找,fun2是在fun1的try语句内,所以会被fun1的catch捕获,catch后的语句正常执行,当调用函数时,创建了Ptr类的对象,资源获得立即初始化,这个对象掌管着堆区开辟的数组,当返回函数栈帧时,

SGlow0708的博客 1279

C/C++相关概念和易错知识点(4)(指针与内存)

b和c是int类型,b+c也是int类型,int数据放到short里面发生截断,最终表达式是short类型,起决定性的是等号左边的变量的类型,sizeof计算的就是short的大小。(这里有点绕,需要好好消化)二维数组本质上是以一维数组为元素的数组,所以二维数组传参传的就是一维数组的地址(首元素地址),创建 int arr[3][4]就用int(*p)[4](数组指针)来接收,p每加1就跳一行4个元素,如果要读取某一行的具体的某个元素,就需要先对p解引用得到一行p元素的地址,再解引用得到单个元素的地址。

SGlow0708的博客 1074

C/C++相关概念和易错知识点(32)(迭代器、string容量调整)

这个区别和指针的const规则类似,只不过指针是根据const和*的相对位置来区分的,迭代器iterator就一个单词,不存在相对位置的概念,所以使用const_放在iterator前面表示区分。,虽然我们知道\0也是字符串的一部分,本质上说也不算越界,但是考虑到实际使用没正常人会去对这个\0动手脚(如果单独改了这个\0,就会导致字符串没有\0,会引发一系列隐患),我们发现扩容后,size直接跳到100,意味着0~99的数据都能被正常访问,在默认情况下,扩容后的空位补\0,你也可以指定字符。

SGlow0708的博客 925

C/C++相关概念和易错知识点(2)(负数取模、左右移)

其次,这些知识点是从我自己的角度出发整理的,因此我认为的重点可能和你不同,有的内容可能不完整或有错误,希望大家多多包涵,如果能指出我的错误,我会非常感激!如果不做任何处理,后续打印的数字会无法对齐,因此使用printf("%3d")或printf("%-3d"),3表示最小位宽,使打印的数字右对齐或左对齐,默认右对齐,前面加上负号变成左对齐。每根地址线能够表示0和1,因此总共能储存2的64或32次方个地址。严格来说,我们所说的指针是指针变量,真正的指针其实是地址,因此我们要区分日常用语和概念的定义的区别!

SGlow0708的博客 702

C/C++相关概念和易错知识点(29)(变量的存储、new和delete混用分析)

我们发现如果这个时候直接去调用operator delete[]、operator delete、delete、free就会导致释放的内存起始位置发生了位移,这就会导致报错,而delete[]就会先从前4个字节开始,先读取个数,然后。注意数组是开辟了空间的,会发生复制操作,就算是常量字符串储存在代码段,也要拷贝过来。如果类没有显式实现析构函数,那么就意味着不会多开辟那4个字节,也就不会报错,这个时候混用不会导致程序崩溃。当我们创建类的数组时,使用new[],因为使用它可以在开辟空间的时候。

SGlow0708的博客 1047

C/C++字符串,数组,指针,引用相关知识总结

C/C++字符串,数组,指针,引用相关知识总结

Sabrisimba的博客 1073
上一篇: C/C++相关概念和易错知识点(5)(嵌套和回调、错误码、内存函数)
下一篇: C/C++相关概念和易错知识点(7)(memcpy和memmove、文件函数)
-SGlow-
博客等级 码龄3年 1513粉丝 118原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值