C语言学习和使用

作者

QQ群:852283276
微信:arm80x86
微信公众号:青儿创客基地
B站:主页 https://space.bilibili.com/208826118

参考

宏定义中的#,##
关于宏##的使用注意一点
c语言 得到结构体成员偏移
C++ 结构体中含有函数时sizeof结构体大小

按键处理

getc,fgetc,获取linux终端上下按键的,上对应1b 5b 41,下对应1b 5b 42

->^[[A
1b 5b 41 0a                    '                .[A.            
->^[[B
1b 5b 42 0a                                     .[B. 

c 结构体包含函数成员 sizeof

和类一样,如果有虚函数,则实例中多出一个虚函数列表指针,

typedef struct st_data_head
{
	int16_t		fieldID=0;	
	int16_t		fieldSize=0;
	st_data_head()
	{
		memset(this, 0, sizeof(st_data_head));
	}
}ST_DATA_HEAD;

计算结构体成员的偏移

3种方法,

#include <stdio.h>
#include <stddef.h>
 
struct stru {
    char c;
    int  i;
};
 
int main(int argc, char *argv[])
{
    struct stru s;
 
    printf("Offset of stru.i:        %ld\n", (size_t)((char*)&s.i - (char*)&s));
    printf("&((struct stru *)0)->i:  %ld\n", (size_t)&((struct stru*)0)->i);
    printf("offsetof(struct stru,i): %ld\n", offsetof(struct stru, i));
 
    return 0;
}

warning C206: missing function-prototype

单片机程序,引用DelayMs,

  while (1) {
    //ShellMain();
    printf("hello world\r\n");
    DelayMs(1000);
  }

报错,

Build target 'Target 1'
compiling main.c...
..\src\main.c(26): warning C206: 'DelayUs': missing function-prototype
..\src\main.c(26): error C267: 'DelayUs': requires ANSI-style prototype
Target not created

明明已经实现了这个函数,后来发现是头文件的预编译宏和另外一个文件重复,

#ifndef __PCA_H_
#define __PCA_H_

void DelayUs(unsigned long us);
void DelayMs(unsigned long ms);

#endif

更改为,

#ifndef __DELAY_H_
#define __DELAY_H_

void DelayUs(unsigned long us);
void DelayMs(unsigned long ms);

#endif

宏##高级用法-给结构体赋值问题

编程时遇到一个需求,这是一个结构体,

struct srioMaintenanceData
{
	unsigned int dstId;
	unsigned int hopCnt;
	unsigned int offset;
	unsigned int value;
};

在代码中,想给这个结构体赋值,

maintData.dstId = 0xFF; maintData.hopCnt = 1;
maintData.offset = SRIO_REG_DEV_ID_CAR; maintData.value = 0;

想用一个宏来替代,类似于,

SRIO_MAINT_DATA_SET(maintData, 0xFF, 1, SRIO_REG_DEV_ID_CAR, 0);

我这样定义,

#define SRIO_MAINT_DATA_SET(n, a, b, c, d) n##.dstId=a;##n##.hopCnt=b;##n##.offset=c;##n##.value=d

报错,但这不是语法错误,是编译器不支持这个操作。
这里写图片描述

Multiple markers at this line
	- pasting "maintData" and "." does not give a valid preprocessing 
	 token
	- Invalid use of macro pasting in macro: SRIO_MAINT_DATA_SET
	- in expansion of macro 'SRIO_MAINT_DATA_SET'

问题不知道怎么解决,搜了一下资料,据说vs中是不会报错的,根据C标准,用##操作后的结果必须是一个已经预定义过的符号。否则是未定义的。所以gcc和vs对于这个未定义行为表示了不同的看法,前者是给出错误,后者一笑而过。那什么是已经预定过的符号呢? 它包含了这些:头文件名, 等式, 预处理数字, 字符常数, 字符串值, 标点符号, 单个非空字符。采取一种曲线救国策略,

inline void SRIO_MAINT_DATA_SET(struct srioMaintenanceData* p, unsigned int dstId, unsigned int hopCnt, unsigned int offset, unsigned int value)
{
	p->dstId = dstId;
	p->hopCnt = hopCnt;
	p->offset = offset;
	p->value = value;
}

希望有大神可以在评论区告知怎样用宏完成结构体赋值,可能在linux内核代码里有类似操作。
2018-06-19补充:今天写windows驱动看到WDK的一个实现:

WDF_DMA_ENABLER_CONFIG   dmaConfig;
WDF_DMA_ENABLER_CONFIG_INIT( &dmaConfig,
                           WdfDmaProfileScatterGather64Duplex,
                           DevExt->MaximumTransferLength );

WDK是这样实现的,也使用的inline。表示心里略平衡一点。

VOID
FORCEINLINE
WDF_DMA_ENABLER_CONFIG_INIT(
    __out PWDF_DMA_ENABLER_CONFIG Config,
    __in  WDF_DMA_PROFILE    Profile,
    __in  size_t             MaximumLength
    )
{
    RtlZeroMemory(Config, sizeof(WDF_DMA_ENABLER_CONFIG));

    Config->Size = sizeof(WDF_DMA_ENABLER_CONFIG);
    Config->Profile = Profile;
    Config->MaximumLength = MaximumLength;
}

C语言转义字符\x

反斜杠是转译符,\x5c就是说:ASCII码十六进制是0x5c的那个字符,\x可以用16进制的方式来初始化char数组,比如char *s = "75\xA1\xE6"表示GB2312编码的75℃。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值