我很好奇在类似下面的情况下使用memset()在效率方面是否有任何优势.
鉴于以下缓冲区声明......
struct More_Buffer_Info
{
unsigned char a[10];
unsigned char b[10];
unsigned char c[10];
};
struct My_Buffer_Type
{
struct More_Buffer_Info buffer_info[100];
};
struct My_Buffer_Type my_buffer[5];
unsigned char *p;
p = (unsigned char *)my_buffer;
Run Code Online (Sandbox Code Playgroud)
除了少量代码之外,使用它还有一个优势:
memset((void *)p, 0, sizeof(my_buffer));
Run Code Online (Sandbox Code Playgroud)
在此:
for (i = 0; i < sizeof(my_buffer); i++)
{
*p++ = 0;
}
Run Code Online (Sandbox Code Playgroud) 据说零长度数组用于可变长度结构,我可以理解.但令我困惑的是为什么我们不仅仅使用指针,我们可以取消引用并以相同的方式分配不同的大小结构.
编辑 - 添加评论示例
假设:
struct p
{
char ch;
int *arr;
};
Run Code Online (Sandbox Code Playgroud)
我们可以用这个:
struct p *p = malloc(sizeof(*p) + (sizeof(int) * n));
p->arr = (struct p*)(p + 1);
Run Code Online (Sandbox Code Playgroud)
获得一块连续的记忆.但是,我似乎忘记了空间p->arr占用,它似乎是零大小数组方法的不同之处.
我今天遇到的代码类似于以下代码,我很好奇实际发生了什么:
#pragma pack(1)
__align(2) static unsigned char multi_array[7][24] = { 0 };
__align(2) static unsigned char another_multi_array[7][24] = { 0 };
#pragma pack()
Run Code Online (Sandbox Code Playgroud)
当在Keil编译器中搜索对__align关键字的引用时,我遇到了这个:
执行区域和输入部分的总结 在某些情况下,您需要对代码和数据部分进行操作...如果您可以访问原始源代码,则可以在编译时使用__align(n)关键字执行此操作...
我不明白"overaligning代码和数据部分"的含义.有人可以帮助澄清这种运动的发生方式吗?
我最近对代码做了一些调整,其中我不得不在函数中更改形式参数.最初,参数类似于以下(注意,结构是之前的typedef):
static MySpecialStructure my_special_structure;
static unsigned char char_being_passed; // Passed to function elsewhere.
static MySpecialStructure * p_my_special_structure; // Passed to function elsewhere.
int myFunction (MySpecialStructure * p_structure, unsigned char useful_char)
{
...
}
Run Code Online (Sandbox Code Playgroud)
之所以进行更改,是因为我可以在编译时定义并初始化my_special_structure,而myFunction从未更改过它的值.这导致了以下变化:
static const MySpecialStructure my_special_structure;
static unsigned char char_being_passed; // Passed to function elsewhere.
static MySpecialStructure * p_my_special_structure; // Passed to function elsewhere.
int myFunction (const MySpecialStructure * p_structure, unsigned char useful_char)
{
...
}
Run Code Online (Sandbox Code Playgroud)
我还注意到,当我在程序上运行Lint时,有几个Info 818引用了许多不同的功能.该信息表明"指针参数'x'(第253行)可以声明为指向const".
现在,关于上述问题,我有两个问题.首先,关于上面的代码,既然指针和MySpecialStructure中的变量都没有在函数内改变,那么将指针声明为常量也是有益的吗?例如 -
int myFunction (const MySpecialStructure * const …Run Code Online (Sandbox Code Playgroud) 我今天遇到了一些让我感到惊讶的代码.变量在.c文件中定义(在函数外部)为静态.但是,在.h文件中,它被声明为extern.以下是代码的类似示例:
.h中的结构定义和声明:
typedef struct
{
unsigned char counter;
unsigned char some_num;
} One_Struct;
typedef struct
{
unsigned char counter;
unsigned char some_num;
const unsigned char * p_something;
} Another_Struct;
typedef struct
{
One_Struct * const p_one_struct;
Another_Struct * const p_another_struct;
} One_Useful_Struct;
extern One_Useful_Struct * const p_my_useful_struct[];
Run Code Online (Sandbox Code Playgroud)
.c中的定义和初始化:
static One_Useful_Struct * const p_my_useful_struct[MAX_USEFUL_STRUCTS] =
{
&p_my_useful_struct_regarding_x,
&p_my_useful_struct_regarding_y,
};
Run Code Online (Sandbox Code Playgroud)
问: 所以我的问题是,为什么我没有收到编译器错误或警告?
代码已经在其他项目中成功运行了一段时间.我注意到指针永远不会在定义它的.c文件之外使用,并且被正确定义为静态(我删除了外部声明).我找到它的唯一原因是因为我在项目上运行了Lint并且Lint选择了它.
我的问题直接涉及到,__attribute__((noreturn))但更一般地可以涉及其他问题-例如__attribute__(noinline)。我已经看过gcc手册和Keil编译器参考指南,以确定用于__attribute__函数的正确语法。我通常看到以下内容:
void function (void) __attribute__((noreturn)); //Prototype has __attribute__
void function (void) //Definition does not.
{
while (1);
}
Run Code Online (Sandbox Code Playgroud)
我还看到了__attribute__在函数定义之前使用过的代码,如下所示:
__attribute__((noreturn)) void function (void)
{
while (1);
}
Run Code Online (Sandbox Code Playgroud)
但是,我还没有看到将其与函数原型和函数定义一起使用的示例。我认为__attribute__在两个位置同时使用会提高代码的可读性;通过查看函数原型或定义,可以知道已经应用了属性。结果如下:
__attribute__((noreturn)) void function (void) ; //Prototype has __attribute__
__attribute__((noreturn)) void function (void) //Definition has __attribute__
{ //as well.
while (1);
}
Run Code Online (Sandbox Code Playgroud)
我已经使用上述方法通过Keil armcc编译器成功编译了代码。是否有任何理由为什么我应该不带任何或器armcc GCC使用这种方法吗?
我一直在研究一些类似于以下内容的代码:
typedef struct
{
unsigned char x;
unsigned short y;
unsigned char[NUM_DEFINED_ELSEWHERE];
} My_Struct;
static My_Struct my_useful_struct; // Variables initialized elsewhere in code.
void myFunction(const My_Struct * p_my_struct)
{
/* Performs various read-only actions utilizing p_my_struct. */
}
void myOtherFunction(void)
{
static My_Struct * p_struct = &my_useful_struct;
myFunction(p_struct);
}
Run Code Online (Sandbox Code Playgroud)
我的代码编译没有任何问题,但在审查时我被告知,除非我对 p_struct 进行类型转换,否则这可能会导致在某些平台(即 8051)上出现未定义的行为。然而,我什至从未收到过有关编译器的警告。 在将指针传递给函数时不进行类型转换(const My_Struct *)是否会导致未定义的行为?
我使用指向的指针声明上述函数的原因const是因为我希望能够处理指向 const 的指针和指针。 在上述情况下不进行类型转换是一种不好的编码习惯吗?
感谢您的帮助!
有人可以告诉我为什么C编译器在使用a Compound Assignment和a Prefix Dec/Inc时输出错误?[但C++不]
int myVar = 5;
(--myVar) -= 4;
// C : error C2106: '-=' : left operand must be l-value
// C++: myVar=0;
Run Code Online (Sandbox Code Playgroud)
我知道错误说的是什么......
但是,我无法理解为什么C编译器无法识别myVar为l值而是C++?
关于如何在C中将结构转换为char [],我有点困惑.
我的CDMA调制解调器不支持发送变量 - 它只能理解ASCII字符.我需要进行转换操作.
假设我有一个像这样的sMSG结构:
struct sMSG
{
int a;
int b[];
char c[];
double d;
float f;
};
Run Code Online (Sandbox Code Playgroud)
所以,我必须做一个字符串 char str[] = "sMSG_converted_into_ASCII_chars";
我想知道是否有人会帮我解决这个问题.
提前致谢.
我想使用getopt()来解析命令行提供的参数,但是我遇到了非常简单的测试用例的问题.我有以下代码(几乎,但不完全相同,作为POSIX标准定义中的示例提供).
int main(int argc, char *argv[]) {
int c;
int rmsflg = 0, saflg = 0, errflg = 0;
char *ifile;
char *ofile;
//Parse command line arguments using getopt
while (((c=getopt(argc,argv, ":i:rso:")) != 1) && (errflg == 0)) {
switch(c){
case 'i':
ifile="optarg";
break;
case 'o':
ofile="optarg";
break;
case 'r':
if (saflg)
errflg++;
else {
rmsflg++;
printf("Root Mean Square averaging selected\n");
}
break;
case 's':
if (rmsflg)
errflg++;
else {
saflg++;
printf("Standard Arithmetic averaging selected\n");
}
break;
case …Run Code Online (Sandbox Code Playgroud)