memset 结构体内指针_C++零基础:指针

最好的C++教程_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili​www.bilibili.com
9a0c18ff3af717302faab9caaf46b431.png

敲黑板,指针,pointer,是C++中最重要的概念,是计算机可以提供给用户的最重要的资源——cherno曰。

指针是什么?指针就是一个整数,表示的是内存中的一个地址。所有的代码都必须放在内存中才能执行,大部分的操作呢,也就是从内存读数据以及向内存中写数据。而内存,可以理解为一个长条的数组,那么指针就存放这个数组中存放的内容的地址。

来写C++中的第一个指针:

#include <iostream>
#include "log.h"

int main() {

	//const char* ptr = nullptr;
	//const char * ptr = NULL;
	const char * ptr = 0;
	if (ptr)
		Log(ptr);

	std::cin.get();
}

这第一个指针ptr的值是NULL,或者是nullptr,或者可以直接写成0,表示的是指针的地址是0,地址0本身是一个无效地址,但是ptr的值为0是没有问题的,表示这个指针指向的地址是无效的。也即是说,“指针是无效的“对于指针而言是一种正常的状态。

另外要注意的是,指针的类型,指针的类型表示的是指针指向的那一块内存中存放的数据类型,也即应该如何理解和处理一块内容。指针自己就是一个内存地址,如果是char*,表示去读指针对应的地址的一个字节;如果是int *,那么就去读4个字节;如果是结构体,那么读的更多一些。这个例子中是void,表示不在乎这个指针指向的类型。

看下一个例子:

#include <iostream>
int main() {

	
	int var = 9;
	void* ptr = &var;
	std::cin.get();
}

定义了一个变量var,然后使用指针获得这个变量var在内容中的地址。

2c68655a8f1694af66849c72efabfdef.png

在调试模式下,可以看出,相对应的0x001cfef0确实存放的是整数9。从这个例子中,再次体会下什么是指针。指针就是一个存放整数(这个例子是0x001cfef0)的变量,不同于一般整型变量的是,它存放的这个整数是内存的地址。至于这个整数可能有多大,取决于很多,它可能是16位,32位或者64位。

另一方面,指针的类型并不影响内存中的内容。只是当我们操作(读取或者写入)的时候,会帮助编译器确认到底需要操作多大的内存空间。譬如来改一下代码:

c7400cd0727a3bd4ad31ff79fca6c302.png

另外,下面这段代码出错,int类型不能转换为double。

int main() {

	
	int var = 9;
	var = (double)var;
	double* ptr = &var;
	std::cin.get();
}

下面试一下指针类型确实有影响的情况。

eead5f726e5db4c3a31ccb1a9ab867ff.png

此时报错,因为指针是void型的,编译器不知道到底应该处理几个字节的内存空间。10可以是char类型,可以是int,可以是double,可以是long long。所以报错。此时,应该修改指针类型。

接下来看指针另外的用法。

3608dd34d52c2d830151900302b0c695.png

这里,使用了new和memset,顾名思义,new用来创建,实际上是调用了底层的malloc,分配内存空间。这里强调一下,此时的buffer是一个指针,这个指针指向内存中的一段长度为10的char类型数组的首地址。这个buffer指针本身还是一个32位,也即4个字节的变量,但是指向的内容是10个字节。接下来,memset用来将这一段内存的内容设置为0。效果如图。可以改一下,将这一段设置为2.

666d4ac6d07fa4a4dadf2f201d945ce9.png

还可以再改改,

87b868c7e5ae96abad34d9232b7b60c6.png

从这些例子中可以看出,memset是以字节为单位的。

可以对比一下,

89e9fd7e1a92dad1f2cbca9c2ebb0cc9.png

关于指针,还有一点可能比较难理解以及容易弄错的地方应该是指向指针的指针。譬如,

970a189249a4ff951f41097fad1940f3.png

此时ptr是指向buffer的指针,可以看到它的内容就是buffer的值,也即0x002afbdc就是buffer自己在内存中的位置;而这个位置中存放的就是0x00008123;而0x00008123中放着的就是数组内容了。

另外值得注意的是,ptr不能为void类型,这也可以理解,指向指针的指针,char**相当于是(char*)*,所指向的指针类型不可能是(void*)。

再另外,注意大小端。:)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一句句解释分析细致讲解一下这段代码void netconf_entry(void) { int state = 0; int event = 0; UINT8 * pPacket = NULL; UINT32 dataLen = 0; char *pData = NULL; UINT8 ret = 0; struct np_module netopeer_module; struct np_module server_module; memset(&netopeer_module,0,sizeof(struct np_module)); memset(&server_module,0,sizeof(struct np_module)); state = Ros_GetCurState(); event = Ros_GetMsgId(); switch( state ) { case NETCONF_PROCESS_INIT: switch( event ) { case MSG_MasterPowerOn: case MSG_SlavePowerOn: //printf("netconf_entry MSG_SlavePowerOn\n"); Ros_SetNextState(NETCONF_PROCESS_RUNNING); break; case MSG_INIT_PROTOCOL_OK: Ros_SetNextState(NETCONF_PROCESS_RUNNING); break; default: break; } break; case NETCONF_PROCESS_RUNNING: switch( event ) { case MSG_DriverOK: netconf_init(); break; case MSG_NETCONF_TO_DCN: nc_verb_verbose("netconf_entry recv netconf to dcn msg\n"); break; case MSG_ALARM_TO_NETCONF: NcProcessAlarmMsg(); break; case MSG_LIBNETCONF_TO_NETOPEER: ncRcvLibnetconfMsgProc(); break; case MSG_NETCONF_LLDP_TIMER: Ros_SetTimer(netconfLLDPTimerID, NETCONF_MSG_TIME_LLDP, 0); ncLldpchange(); break; case MSG_NETCONF_15MIN_PERF_TIMER: Ros_SetTimer(netconf15MINPerfTimerID, NETCONF_MSG_15MIN_TIME_PERF, 0); packageOptInfo15Min(); packageIfStatisInfo15Min(); break; case MSG_NETCONF_24H_PERF_TIMER: Ros_SetTimer(netconf24hPerfTimerID, NETCONF_MSG_24H_TIME_PERF, 0); packageOptInfo24H(); packageIfStatisInfo24H(); break; case MSG_NETCONF_MEM_CHECK_TIMER: printS("MSG_NETCONF_MEM_CHECK_TIMER TIMEROUT\n"); memory_line_check(0); break; case MSG_NETCONF_TIMER: oam_perf_netconf_show_value_entry(); break; default: break; } break; default: break; } return EXIT_SUCCESS; }
07-14

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值