C language scraps-01


Brother Tao's 100th original

I. Introduction

In the past few days , I was porting the code of an embedded project to another platform and found that many places use the C89 standard.

In 1999, the C language standardization committee released the C99 standard, which introduced many features, including variable-length arrays, flexible array members (used in structures), improvements to IEEE754 floating-point numbers, initializers for designated members, internal Associative functions, macro definitions that support indefinite number of parameters, and long long int and complex number types are added to the data types.

So I recently found a relatively new C language book and turned it over, and found that many of the more remote grammars are rarely used, including some content in the C99 standard, so I want to organize this part of the content, but also let myself Reorganize this ancient language.

Second, a small test

1. Flexible array members

Without explaining the concept, let's first look at a code example:

// 一个结构体,成员变量 data 是指针
typedef struct _Data1_ {
    int num;
    char *data;
} Data1;

void demo6_not_good()
{
    // 打印结构体的内存大小
    int size = sizeof(Data1);
    printf("size = %d \n", size);

    // 分配一个结构体指针
    Data1 *ams = (Data1 *)malloc(size);
    ams->num = 1;

    // 为结构体中的 data 指针分配空间
    ams->data = (char *)malloc(1024);
    strcpy(ams->data, "hello");
    printf("ams->data = %s \n", ams->data);

    // 打印结构体指针、成员变量的地址
    printf("ams = 0x%x \n", ams);
    printf("ams->num  = 0x%x \n", &ams->num);
    printf("ams->data = 0x%x \n", ams->data);

    // 释放空间
    free(ams->data);
    free(ams);
}

On my computer, the print result is as follows:

It can be seen that the structure has a total of 8 bytes (int type occupies 4 bytes, pointer type occupies 4 bytes).

The structure of datathe members is a pointer variable , for it requires a separate application can use a space. And after the structure is used, it needs to be released first data, and then the structure pointer ams, the order cannot be wrong .
Is it a bit troublesome to use this way?

Therefore, the C99 standard defines a grammar: flexible array member (flexible array) , directly upload the code (if the following code encounters a warning when compiling, please check the compiler's support for this grammar):

// 一个结构体,成员变量是未指明大小的数组
typedef struct _Data2_ {
    int num;
    char data[];
} Data2;

void demo6_good()
{
    // 打印结构体的大小
    int size = sizeof(Data2);
    printf("size = %d \n", size);

    // 为结构体指针分配空间
    Data2 *ams = (Data2 *)malloc(size + 1024);

    strcpy(ams->data, "hello");
    printf("ams->data = %s \n", ams->data);

    // 打印结构体指针、成员变量的地址
    printf("ams = 0x%x \n", ams);
    printf("ams->num  = 0x%x \n", &ams->num);
    printf("ams->data = 0x%x \n", ams->data);

    // 释放空间
    free(ams);
}

The print result is as follows:

There are several differences from the first example :

  1. The size of the structure becomes 4;
  2. When allocating space for the structure pointer, in addition to the size of the structure itself, it also applies for the space required by data;
  3. No need to allocate space separately for data;
  4. When releasing space, just release the structure pointer directly;

Is it easier to use? ! This is the benefit of flexible arrays.

Syntactically speaking, a flexible array refers to an array with an unknown number of last elements in the structure, and it can also be understood as a length of 0, so this structure can be called variable-length.

As mentioned earlier, the array name represents an address, which is a constant address constant. In the structure, the array name is just a symbol, it only represents an offset, and does not occupy specific space.

In addition, the flexible array can be of any type . Everyone has a lot of experience in the example here. This usage is often seen in many communication processing scenarios.

2. Macro definition of indefinite parameters

The number of parameters defined by a macro can be undefined , just like calling the printf print function. When defining, you can use three dots (...) to represent variable parameters, or you can add the option before the three dots. The name of the variable parameter.

If you use three dots (...) to receive variable parameters, you need to use VA_ARGS to represent variable parameters when you use it , as follows:

#define debug1(...)      printf(__VA_ARGS__)

debug1("this is debug1: %d \n", 1);

If you add a parameter name in front of the three dots (...), you must use this parameter name when you use it, and you cannot use VA_ARGS to represent variable parameters , as follows:

#define debug2(args...)  printf(args)

debug2("this is debug2: %d \n", 2);

However, if the number of variable parameters is zero, processing may be problematic!

Take a look at this macro:

#define debug3(format, ...)      printf(format, __VA_ARGS__)

debug3("this is debug4: %d \n", 4);

There is no problem with compilation and execution. But if you use the macro like this:

debug3("hello \n");

Compile time error occurs: error: expected expression before ‘)’ token. why?

Take a look at the code after the macro expansion ( __VA_ARGS__empty):

printf("hello \n",);

See the problem, right? There is an extra comma after the format string ! In order to solve the problem, the preprocessor provides us with a method: use the ## symbol to automatically delete this extra comma .

So there is no problem if the macro definition is changed to the following.

#define debug3(format, ...)     printf(format, ##__VA_ARGS__)

Similarly, if you define the name of a variable parameter yourself, add ## in front of it, as follows:

#define debug4(format, args...)  printf(format, ##args)

Three, cheer for yourself

This article is just the beginning. I will continue to collect information later. The ultimate goal is to summarize the grammar and usage of the C language into a booklet. I hope I can stick to it!


Good articles should be forwarded ; the more you share, the luckier you are!

Star official account , you can find me faster!


If you want to reprint this article on your website, just keep the author, source of the article and the QR code above.

If you want to reprint this article on your official account, please private message or leave a message, I will open Changbai for you.



Recommended reading

[C language]
C language pointer-from the underlying principles to fancy skills, with graphics and code to help you explain
the underlying debugging principles of the original gdb so simple
and step-by-step analysis-how to use C to implement object-oriented programming to
improve the code for a powerful tool : Macro definition-From entry to abandonment,
use setjmp and longjmp in C language to realize exception capture and coroutine

[Application Programming] It is
said that the software architecture should be layered and divided into modules, and what should be done specifically (1) It is
said that the software architecture should be layered and divided into modules, and what should be done specifically (2)
IoT gateway development: based on MQTT message bus Design process (on)
IoT gateway development: design process based on MQTT message bus (below)
my favorite way of communication between processes-message bus

[Operating System]
Why do spacecraft and missiles prefer to use single-chip computers instead of embedded systems?

[Internet of Things]
Things about encryption and certificates
go deep into the LUA scripting language, so that you can thoroughly understand the principle of debugging

[Nonsense] Based
on my failed career experience: a few tips for technicians who are new to the workplace

Guess you like

Origin blog.csdn.net/u012296253/article/details/115366870