C语言的灵魂——指针

最新工作中,遇到一个关于指针应用的问题,感觉对指针运用太不熟悉了,所以把指针拎出来再看了一次,在此做一些笔记,便于后续温习;本帖先说遇到的问题,再说重读C指针的的知识点;


一、遇到问题:
问题场景:
        进程A接收到进程B 的查询msg消息后,将应答结果发送给进程B,但进程B没有收到消息;
        
原因分析:  
        1) 进程A使用的发送函数接口,不正确;或消息没发送成功;
            ——接口函数没有问题;消息发送成功了,有log打印;
        2)进程A发送消息构建的数据不正确;
    ——有可能;因为发送的数据为:header+msg_data,均为结构体;

        a. ucMsgRecvAPP成员初始化时,其源数据为14字节(包含'\0'),而代码中使用strcpy_s()函数进行拷贝11字节;且尾部没有写入'\0';所以该处可能会出现错误;

            ——应该使用memcpy_s() 函数来拷贝字符串(B进程名);

        b. 消息结构体初始化有问题:原理代码中,是直接依据send_buff偏移初始化pmsg_data 数据,未使用指针,但不成功;

            ——正确做法为: uchar send_buff[sizeof(MSG_HEADER_ST) + sizeof(MSG_DATA_ST)] = {0};

            MSG_HEADER_ST *pmsg_header = (MSG_HEADER_ST  *)send_buff;                        // 定义初始化消息头的指针变量;

            MSG_DATA_ST *pmsg_data = (MSG_DATA_ST *)send_buff[sizeof(MSG_HEADER_ST)];   // 定义初始化消息数据的指针变量;

这样就可以通过指针变量,来分别初始化消息头和 带发送的数据了;

而pmsg_header 指向的是待发送的消息体send_buff(包含消息头+应答数据);  
typedef struct _msg_header_st        // msg header;
{
	uint uiMsgType;
	uchar ucMsgRecvApp[12];
	uchar ucMsgSendApp[12];
	uint uiMsgData;
	uint uiMsgLen; 
	uint uiSeq;
}MSG_HEADER_ST;
typedef struct _msg_data_st            // msg send data_st
{
	uint uiUpdateTime;
	uint uiUpdateProcess;
}MSG_DATA_ST;

    3)进程A发送消息的接收进程名,和接收消息的进程B名字不匹配;

        ——有可能;接收进程名拷贝时不正确;

解决方法:

    详见原因分析解答;


二、C指针知识点:(问题+实例形式)

0. 数据在内存中是如何存储,如何读取?
    ——程序中,一般是通过变量名来对内存单元进行存取操作的。原因如下:
    1)比如程序中定义一个变量,在对程序进行编译时,编译系统根据程序中定义的变量类型,分配一定长度的内存空间;
(而在内存中,每一个字节都有一个编号,即“地址”,在地址所标示的内存单元中存放这数据;)
    2)程序经过编译以后就将变量名转化为变量的地址,对变量的存取都是通过地址进行的。(变量名和地址的对应关系)

1. 内存单元的地址、内存单元的内容区别是?
——内存单元的内容,是内存单元地址所指向的数据,比如定义变量时,变量的值;而地址则是编译系统根据定义变量的类型对给这个变量分配的内存单元的首地址;

2.  指针是什么?
——C中,地址即为指针;因通过指针能够找到以它为地址的内存单元;
指针:(地址) 一个变量的地址,称为该变量的“指针”;
指针变量:(变量) 一个变量专门用来放另一个变量的地址,则称该变量为“指针变量”;

3. 直接访问和间接访问区别是?
——按照变量的地址,存取变量值的方法叫做“直接访问”;将变量i,存储在另一个指针变量中,通过指针变量来访问该变量,叫做“间接访问”;
——&:取地址运算符; *指针运算符或“间接访问”运算符;

4. 指针和指针变量区别?
——变量的指针,即为变量的地址; 存放变量地址的变量,是指针变量;

5. 定义指针变量时,为何需要指定基类型?
——因为不同类型的数据,在内存中所占的字节数是不相同的;(int 2字节,float 4字节;)
——基类型:即指针变量所指向的变量的类型;

6. C中,实参和形参之间数据传递是单向的“值传递”方式;

7. 引用数组元素的方法有那些?
——下标法和指针法;
  指针法质量高,(因为占用内存少,运行速度快)

8. *pointer++: 因++ 和 * 为统一优先级,结合方向从右向左;所以:*(pointer++)
    1)先对pointer的原值进行 *运行,输出结果后;
    2)再对pointer的值进行++运算;

9. 若定义的指针变量所指向的单元不可预见,对其赋值,则可能给一个存储重要数据的存储单元赋值,就会破坏系统的正常运行;
比如:   char *temp;
    *temp = *p;













猜你喜欢

转载自blog.csdn.net/llzhang_fly/article/details/80782006