admin管理员组

文章数量:1794759

C语言学习和使用

C语言学习和使用

作者

QQ群:852283276 微信:arm80x86 微信公众号:青儿创客基地 B站:主页 space.bilibili/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℃。

本文标签: 语言