background

This series is a self-taught Android audio and video series.

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

The introduction to C will probably be divided into several chapters. Since I studied C in university and did simple JNI development later, I will briefly review and review it here.

Install the IDE

I remember a long time ago, I used Visual Studio to develop C, but I see some people recommend using Clion this IDE, the style is the same as Android Studio, simply seamless switch, here directly download from the official website, and then you will find that you need to buy, of course, here recommend the ability to buy. Here I found a place to generate the activation code:

33tool.com/idea/

Just activate it if you need to.

That’s CLion’s style, and JetBrains is pretty nice, I have to say.

Configure the environment

I’m using a Windows computer for development, so I need to configure the environment, of course, no configuration is also possible, using CLion direct run can also be compiled, but we still want to have a brief understanding.

The compiler of THE C language is called GCC, here to download GCC is very convenient, you can download through Cygwin64, select gcc-core, make and other plug-ins, and then configure the system variables, and finally in the command line interface can use GCC.

The IDE’s default Hello World program, found in console LS, is a single main.c file, this.c is the source,

Calling GCC generates an exe file,

Run exe, and we’re done with our first Hello World.

The C language

Hello World

Take a look at how C Hello World prints:

#include <stdio.h> int main() { printf("Hello, World! \n"); return 0; }Copy the code

C directly uses main() as the entry point to programs, and writes methods and variable types first, similar to the Java language. #include is used to import the header file, that is, the package;

The keyword

All languages have their own keywords. Here’s a look at some common keywords in C:

In fact, it is quite easy, loop, judgment are all common language, basic data type C is more distinguished, and Java is different, other keywords can be understood by literal meaning.

The data type

There are only two types of data types that we are familiar with in Java. One is basic data type, and the other is reference data type.

In Java, arrays, interfaces, classes, and NULL are all reference data types. The others are basic data types. In C, they are similar, but different, as shown below:

What’s special about this, I think, is that C has a function type, and this is actually a pointer to a function, which is very useful in C.

Printf format control

There are only a few basic data types in Java, but C has arithmetic types in it, and there are a lot of arithmetic types in it, and it’s easy to get confused, because C has a sizeof method that you can use to see how big the type is.

The printf function is also very particular about printing arithmetic data. It can be interpreted as reading an integer/novel of type XX in xx format and assigning it to type XX, as in the following code:

// Read a decimal integer and assign it to int printf("l1: %d \n",1225422554); // Read a decimal integer and assign it to short printf("l2: %hd \n",1225422554); // Read a decimal integer and assign it to long printf("l3: %ld \n",1225422554);Copy the code

This is a decimal integer, which is represented by %d, but is assigned to a different type, where short can hold up to 30,000 bytes.

It makes sense that L2 is wrong.

In summary, be careful about printing arithmetic types in the future.

Format control character instructions
%c Read a single character
%hd, % D, %ld Read a decimal integer and assign it to short, int, and long
%ho, % O, % LO Read an octal integer (prefixed or unprefixed) and assign it to short, int, and long, respectively
%hx, %x, %lx Reads a hexadecimal integer (prefixed or unprefixed) and assigns it to short, int, and long, respectively
%hu, %u, %lu Read an unsigned integer and assign it to unsigned short, unsigned int, and unsigned long
% f, % lf Read a decimal number and assign it to float and double, respectively
% % e, le Read an exponential decimal and assign it to float and double
% % g, lg We can read either a decimal decimal or an exponential decimal and assign it to a float or double, respectively
%s Read a string (terminated with whitespace)

C variable definition and declaration

Variable definitions and declarations are a little different in C. Variable declarations assure the compiler that a variable exists with the specified type and name.

But there are two cases:

  • The default is to create storage, for example int a creates storage when it is declared.
  • Extern int A; extern int A where a can be defined in another file. Extern int A

C defines constants

We won’t say what a constant is, but it is equivalent to a Final variable in Java. There are two main ways:

  • Use the #define preprocessor.
  • Use the const keyword.

There’s one preprocessor, one is a keyword, and I don’t really know what a preprocessor is, but I’ll talk about that later.

#define age 18

void sizeofFun();

int main() {
    const int i = 19;
    printf("age = %d  i = %d",age,i);
    return 0;
}
Copy the code

Where #define is preprocessing.

Storage class

The concept of what a storage class is does not exist in Java. It is simply a set of modifiers that define the scope and life cycle of a variable.

In front of the keywords in the section we said the auto and register the keyword, are local variables and can be stored in registers, there are 2 kinds, respectively is static and extern:

  • Static: Java static variables and methods are the life cycle of a program.

Extern: provides a reference to a global variable that can be defined in other files.

C is executed as a file, so variables are defined in order, such as the following code:

#include <stdio.h> #include "support.h" int main() {sum = add(a,b); printf("sum = %d",sum); return 0; } int a = 10; int b = 20;Copy the code

The a and B variables defined after the main() method cannot be used, but must precede the main() method:

#include <stdio.h>
#include "support.h"

int a = 10;
int b = 20;

int main() {
    int sum = add(a,b);
    printf("sum = %d",sum);
    return 0;
}
Copy the code

Extern = extern; extern = extern; extern = extern; extern = extern; extern = extern; extern = extern

#include <stdio.h>
#include "support.h"

int main() {
    extern int a;
    extern int b;
    int sum = add(a,b);
    printf("sum = %d",sum);
    return 0;
}

int a = 10;
int b = 20;
Copy the code

Extern is also an extension of scope.

Extern = extern; extern = extern; extern = extern; extern = extern; extern = extern; extern = extern; extern = extern;

#include <stdio.h>

int a = 10;
int b = 20;
int add();

int main() {
    int sum = add();
    printf("sum = %d",sum);
    return 0;
}
Copy the code

Define a, b2 variables and the add function, then in the addfun. c file:

extern int a;
extern int b;

int add(){
    return  a + b;
}
Copy the code

It would certainly not be possible to execute this add method to get a and B, since they are not in the same file, but it is possible to do so using the extern keyword.

function

Function is the same as that defined in the Java is, in fact, the return value in the former, the function name and parameter form function signatures, but said a different here, is a function declaration, in Java, you define a function must have the method body, unless it’s interface, or is unable to define success, but it is different in C, such as the following code:

// declare a Max function int Max (int,int); Int main() {printf(" Max = %d", Max (10,20)); return 0; } int Max (int num1,int num2){return (num1 > num2)? num1 : num2; }Copy the code

This kind of function declaration and function body definition is absolutely impossible in Java. In C, it can be implemented this way. Declaration and implementation can be separated.

Function parameters

If a function parameter is used, must be declared to accept the parameter values of variables, these variables are called function parameters, in the form of parameters as a local variable, is created when entering the function, exit function is destroyed, this and other Java language are the same, but there’s a call type difference, namely the value calls and call reference.

Now that you have the idea of a pointer, you can make referential calls that directly modify what the address points to.

Here we can compare the Java, all function is by value in Java calls, but also pay attention to the Java types are divided into basic types and reference types, including basic types, let alone transfer must be value transfer, but when a reference type to notice even copy and copy of which is a reference, if the parameter is the class type, The reference type of the field is a shallow copy, and the reference type of the field is still the same, so modifying the form will affect the argument passed.

An array of

An array is a contiguous chunk of memory. In fact, there is nothing to say. The definition and assignment of an array are basically the same as in Java, but there are a few differences. First, the idea of Pointers. In Java, arrays are reference data types, so defining an array variable is actually a reference to an array. In C, the array name of an array is actually a pointer to the first element of the array. With this in mind, we can look at how to pass arrays to functions:

  • The parameter is a pointer
void testArray(int *param){
    
}
Copy the code
  • The parameter is an array of defined sizes
void testArray(int param[10]){

}
Copy the code
  • The parameter is an array of undefined size
void testArray(int param[]){

}
Copy the code

Pointer to the

For Pointers, this is the soul of C, in fact very simple is the address, here is a brief overview:

A pointer to a particular type is an address to a particular data type.

Function return pointer

Now that we know about Pointers, one of the strengths of C is that its functions can return values of pointer types, but do not return the address of a local variable unless the local variable is defined static.

Take a look at the following code:

#include <time.h> #include <stdlib.h> int * getRandom(){static int r[10]; srand((unsigned) time(NULL)); for (int j = 0; j < 10; ++j) { r[j] = rand(); printf("[%d] : %d \n",j,r[j]); } return r; } int main() { int *p; p = getRandom(); for (int j = 0; j < 10; j ++) { printf("*(p + [%d]) : %d \n",j,*(p + j)); } return 0; }Copy the code

We return an array that is a pointer to the first element. Since arrays are sequential addresses, we can simply add ++ to the array pointer.

Is consistent. If r is a local variable, it will be released at the end of the function. If r is a local variable, it will be released at the end of the function.

Int * getRandom(){// remove static from int r[10]; srand((unsigned) time(NULL)); for (int j = 0; j < 10; ++j) { r[j] = rand(); printf("[%d] : %d \n",j,r[j]); } return r; } int main() { int *p; p = getRandom(); for (int j = 0; j < 10; j ++) { printf("*(p + [%d]) : %d \n",j,*(p + j)); } return 0; }Copy the code

The printed result is:

That’s not true, but why is the first value right? They’re all supposed to be released, but I don’t know why.

Static variables are stored in a static data area and are not cleared at the end of a function’s execution.

In fact, this involves the storage location of C, here not to say, because only familiar with Java, but more extension, later have the opportunity to explore.

A function pointer

It’s interesting to say that you have to know what the type of a function is, the parameter of the function, the return value, whatever you want to call the function name, so a pointer to a function is a pointer to a function, and if you’re familiar with kotlin’s advanced functions, this is easy to understand.

Look directly at the following code:

double max1(double num1,double num2){ return (num1 > num2) ? num1 : num2; Double (*p)(double,double) = *max1;} double (double,double) = *max1; double a,b,c,d; printf("input 3 numbers: \n"); scanf("%lf %lf %lf",&a,&b,&c); d = p(p(a,b),c); printf("max: %lf \n",d); return 0; }Copy the code

The pointer to p is the same type as p in kotlin :(double,double) -> double.

The callback function

In Fact, in Kotlin, we use high-level functions for callbacks. That is, we define a variable that is of a higher-order function type, and when we process the variable where it needs to be implemented, it will be called back to where it was called.

Function Pointers are similar to this, so using function Pointers to implement callback functions is easy.

Here’s a very simple example:

#include <stdio.h> #include <time.h> #include <stdlib.h> void test(int *array,size_t arraySize,int (*p)(void )){ for (int i = 0; i < arraySize; Array [I] = p(); array[I] = p(); } } int getNextValue(){ return rand(); } int main() { int array[10]; // Pass the function name directly, that is, the function pointer test(array,10,getNextValue); for (int i = 0; i < 10; ++i) { printf("value : %d \n",array[i]); } return 0; }Copy the code

The print result is as follows:

Exactly as expected. The difference between this and Kotlin is that C is passing the function pointer, the function name, as long as the method signature is the same and the return value is the same.

string

A String is a one-dimensional array of type CHAR. The last position in the array is null ‘\0’, as shown in the following example:

char ch[] = {'h','e','l','l','o','\0'}; Char ch1[] = "hello"; int main() { printf("ch size = %d \n", sizeof(ch)); printf("ch1 size = %d", sizeof(ch1)); return 0; }Copy the code

Here the length is 6:

Sizeof returns the length of the array, but sizeof is computed without \0, so string length is 5. The string length API is strlen.

char ch[6] = {'h','e','l','l','o','\0'}; char ch1[6] = "world"; char ch2[12]; Int main() {// copy strcpy(ch2,ch1); printf("ch2 : %s \n",ch2); / / stitching strcat (ch, ch1); printf("ch : %s \n",ch); Int len = strlen(ch); printf("ch str size : %d \n",len); int len1 = sizeof(ch); printf("ch size : %d",len1); return 0; }Copy the code

Here we have 3 strings, where ch is concatenated, which is definitely longer than 6, but can still be saved. Here we print:

There are other string manipulation apis, such as determining whether two strings are the same or returning the position of a character’s first occurrence in the string.

conclusion

In fact, all languages are very similar, many design ideas are common, but C Pointers or Java language can not be compared, really good, this article first learn here, the next article to continue.