preface

C and C++ are the primary language foundation for learning audio and video technology, so it is necessary to learn and review the C language foundation learned before.

The body of the

A previous article has introduced a lot of knowledge about C, let’s continue.

The structure of the body

In both C and Java, you can’t just have a few basic data types, but you also need a kind of concept, which in Java is object-oriented, which is classes, and in C you need structures.

Struct allows C to create a custom data type using the struct keyword, which is also very easy to understand, as follows:

#include <time.h> #include <stdlib.h> struct Book{ char title[50]; char author[50]; char subject[50]; int book_id; }; int main() { struct Book androidBook; Strcpy (androidbook.title," first line of code "); Strcpy (androidBook. The author, "Guo Lin"); strcpy(androidBook.subject,"android"); androidBook.book_id = 100; printf("book info : title = %s \n " "author = %s \n " "subject = %s \n " "id = %d \n", androidBook.title,androidBook.author,androidBook.subject,androidBook.book_id); return 0; }Copy the code

Note here that if Chinese is not displayed, you need to set the IDE encoding, you can set the non-UTF-16, the default is UTF-8, the above code print is:

Since structs don’t define get/set functions like Java classes, we use strcpy or strcpy when we get a struct member. The call.

Structure pointer

If a structure is of a custom type, you can define a pointer to a structure that points to that type. This is also very simple. The main point is to obtain a structure member from a pointer. It’s the same. Here’s the code:

#include <stdio.h> #include <time.h> #include <stdlib.h> struct Book{ char title[50]; char author[50]; char subject[50]; int book_id; }; int main() { struct Book androidBook; Strcpy (androidbook.title," first line of code "); Strcpy (androidBook. The author, "Guo Lin"); strcpy(androidBook.subject,"android"); androidBook.book_id = 100; printf("book info : title = %s \n " "author = %s \n " "subject = %s \n " "id = %d \n", androidBook.title,androidBook.author,androidBook.subject,androidBook.book_id); Struct Book *pBook; pBook = &androidBook; printf("book info : title = %s \n " "author = %s \n " "subject = %s \n " "id = %d \n", pBook -> title, (*pBook).author, pBook -> subject, pBook -> book_id); return 0; }Copy the code

Here the pBook pointer is used and printed as follows:

A domain

It has to be said that the memory usage of C is very important. For example, in this bit field, some information in the structure does not need to be stored in a complete byte, that is, 8 binary bits, then the information can be stored in binary, reducing the memory usage. For example, to store a switch variable, you only need 0 and 1, as shown in the following code:

struct Bean{ unsigned a:1; Int :7; unsigned b:6; // A member variable is not stored in 2 bytes, so by default it is also empty 2 bits unsigned c:7; // The range is 0 to 127}; int main() { struct Bean bean; struct Bean *pBean; bean.a = 0; //64 cannot be saved to b correctly, b will be full of 0 bean.b = 64; bean.c = 100; Printf ("bean values are %d %d %d \n",bean.a,bean.b,bean.c); pBean = &bean; pBean -> a = 1; pBean -> b = 62; pBean -> c = 129; Printf ("bean values are %d %d %d \n",pBean -> a,pBean ->b,pBean -> c); return 0; }Copy the code

The above comments are clearly written, so the print can be expected as follows:

So this bit field here is only useful for holding information that is small, that is, less than 8 bytes, unpacked.

The appropriate

It is a special data type that allows different data types to be stored in the same memory location, but it is possible to define a common with multiple members. Only one member has a value at any time, as you can see from the sample code:

union Data{ int i; float f; char str[20]; }; int main() { union Data data; // Data. I = 10; Data. F = 2.9 f; strcpy(data.str,"android"); printf("data.i : %d \n",data.i); printf("data.f :%f \n",data.f); printf("data.str : %s \n",data.str); // This is the correct data. I = 10; printf("data.i : %d \n",data.i); Data. F = 2.9 f; printf("data.f :%f \n",data.f); strcpy(data.str,"android"); printf("data.str : %s \n",data.str); return 0; }Copy the code

The code above defines the Commons and the wrong and correct ways to access them. Take a look at the print:

Since the Commons can only be valued by one member, it’s easy to understand that the first access must be wrong.

typedef

This is easy to understand. You can see the type definition in its name, which is to give the type a new name. There is also a keyword that can be implemented, and that is #define, which is a preprocessing instruction.

  • Typedefs are used only as aliases for type symbols. #define can be aliases for types as well as numeric values, such as defining π as 3.14.

  • Typedefs are interpreted by the compiler execution, and #define statements are handled by the precompiler.

Input and output

Input and output are keyboard and screen. There are three types of methods involved. The code is as follows:

Int main() {//scanf and printf float f; Printf (" Enter a float value \n"); scanf("%f",&f); Printf (" The input value is %f \n",f); //getchar and putchar int c; Printf (" Enter a char value \n"); c = getchar(); putchar(c); //gets and puts char STR [100]; Printf (" Enter a string "); gets_s(str,10); puts(str); return 0; }Copy the code
  • Scanf () and printf() are used to read from the standard keyboard and format the standard output to the screen.

  • Getchar () and putchar(), used to read a character and output a character.

  • Gets () and puts(), which are used to read and output strings.

File to read and write

In fact, FILE read and write and above said input and output is the same, including the API design idea is similar, here is mainly a FILE pointer is used to control the FILE, directly look at the code can:

Int main() {// Write FILE *fp = NULL; // return a FILE pointer fp = fopen("C: Users\wayee\CLionProjects\Ctest\test. TXT ","a+"); // Write a file with fprintf, where the first argument to fp is fprintf(fp,"fprintf add \n"); // Writes the file through fputs, where fp is the second parameter fputs("fputs adds \n",fp); fclose(fp); FILE *p = NULL; p = fopen("C:\Users\wayee\CLionProjects\Ctest\test.txt","r"); // Need a buffer char buffer[255]; Fscanf (p,"%s",buffer); Printf (" read by fscanf: %s \n",buffer); Fgets (buffer,255,p); Printf (" read by fgets: %s \n",buffer); fgets(buffer,255,p); Printf (" read by fgets: %s \n",buffer); fclose(p); return 0; }Copy the code

TXT file is as follows:

Print the following:

Fscanf and fgets are used to read files.

The preprocessor

C language has a preprocessor, this is relatively special, at least in Java does not have this concept, said to compile to compile, so this preprocessor means what, in fact, is a text replacement tool.

C’s preprocessor, known as CPP, does the processing at the actual compiler, and all preprocessing commands start with #.

In fact, it is very easy to understand, nothing more than to determine whether a macro is defined, or conditional judgment, preprocessing in C code compilation has a very important role.

In addition to the above, there are several preprocessing operators that are useful in code,

Here is a simple example code to enhance memory:

#include <stdio.h> #include <time.h> #include <stdlib.h> #include <stdlib.h> #define tokenPaster(n) printf("token"#n" = %d \n",token##n) // Parameterized macro #define square(x) ((x) * (x)) int main() {message_for(Carole,Debra); // paste int token34 = 40; tokenPaster(34); // parameterized macro int j = square(5); printf("j = %d",j); return 0; }Copy the code

The printed result is:

The header file

C has the concept of a header file, with a.h extension, which doesn’t exist in Java, so why do we have a header file in C?

#include is a header file that can import a method, a variable, or a header file. #include is a header file that can import a method or a variable. Why not just use #include to import methods or variables instead of defining headers?

Conditional compilation is a lot more judgmental without the concept of headers, so let’s look at what to put in a header file:

Of course, I won’t go into details here, but I will discuss them later in the code. The main purpose of header files is to make the code file structure clearer and conditional compilation.

Variable parameter

Mutable arguments are used a lot in Kotlin, especially with functions like arrayOf, but how are mutable arguments defined and parsed in C?

This is a bit more complicated, so let’s just look at the code and comments:

Num is the number of multiple arguments... Double Average (int num,...) {// Define a va_list variable va_list vaList; Double sum = 0.0; Va_start (vaList,num); va_start(vaList,num); for (int j = 0; j < num; Sum += va_arg(vaList,int); sum += va_arg(vaList,int); } // end parsing va_end(vaList); return sum/num; } int main () {printf (" business of 2, 5-tetrafluorobenzoic = % f \ n ", business (4, 2, 3, 4, 5)); return 0; }Copy the code

Take the average of 2,3,4,5 and print:

conclusion

The study of C will probably stop here and be supplemented after learning specific projects. These two articles on C language are just to review some basic knowledge of C language. The last article is:

The Path to Audio and Video Learning –C Language (1)

You can see it together, just to review C.