C language - first introduction to C language

Preface

Students who are new to C language must not know what C language is? , what is the use, then you are at the right place, this series will take you to get started with C language, from getting started to "burying it", just kidding, as the title says, this tutorial first has a preliminary understanding of C language, you can see Understand what others write and have a general framework. Then, I will start to explain. This chapter is mainly an outline of the initial C language.

1. What is C language

What is C language ?

  • Language : Chinese, Japanese, English, etc. Language is a natural language, a language used by people to communicate with each other.
    Computer language: By analogy, it is the communication between humans and computers.

  • C language is a general computer programming language that is widely used in low-level development . The design goal of the C language is to provide a programming language that can be easily compiled, handle low-level memory, generate a small amount of machine code, and can run without any runtime environment support. Although the C language provides many low-level processing functions, it still maintains good cross-platform characteristics.

2. The first C language program

  • After we understand what C language is, we need to understand how to use an integrated development environment to complete the first C language program.

  • What is an integrated development environment?

  • Integrated development environment (IDE, Integrated Development Environment) is an application used to provide a program development environment, generally including tools such as code editors, compilers, debuggers, and graphical user interfaces.

  • Like vscode is an editor. It is not an integrated development environment, but it can add many plug-ins to edit and generate various forms of code.

  • Like vs2022 is an integrated development environment, which is very convenient to use in daily life, but the storage space is relatively large. After all, it has advantages and disadvantages, and the two are not compatible.

  • But I personally don’t recommend using those ancient compilers such as VC++, DEV++...

Next we will start to formally write the first C language program

  1. Go to the official website to download VS2022, don’t go to other places to download pirated versions! ! ! Click to enter the official website

Insert image description here

  • Click on personal free download, it is enough to learn and download.
  1. Open download

Insert image description here

  1. Open the software and create a new project

Insert image here Description
Insert image description here
Insert image description here

Insert image description here
Insert image description here
Insert image description here
Insert image description here

  • In the learning of C language, the first program for most people is hello word!, how do we print it out hello wordand start our journey of learning programming? Follow me to learn together.

Insert image description here

  1. We know that all characters and symbols in C language are in English.
  2. Code in C language mainstarts from the first line of the function.
  3. The main function is the entry point of the program. mainThere is only one function in a project.
  4. The code in the code printfis introduced by the compiler's header file and can be used directly.
  5. <stido.h>is a header file, the suffix is .c​​source file, and the suffix .his ​​header file.
#include<stdio.h>
int main()
{
    
    
	printf("hello world!\n");
	return 0;
}
  • Some people may see that what I write here int main(){ ... return 0}is usually written like this, and it is also the most common way of writing.
    There is also another way of writing: void main(){ }. This way of writing is relatively old and will not be used now.

3. Data type

We have written our first C language program. Next, let’s talk about the data types in C language.

Before understanding data types, let's first explore why we need to write a program ?

  • It is to use programs to solve some problems in life. In real life, our various data have many different types . In order to express various values ​​in life more abundantly , so many data types are set in C language programs .
char        //字符数据类型
short       //短整型
int         //整形
long        //长整型
long long   //更长的整形
float       //单精度浮点数
double      //双精度浮点数
  • What is the byte size of each type?
    What the picture below shows is:

Insert image description here

Common units in computers: bit, byte, KB, MB, GB, TB, PB.

  • Their unit conversion is:

1 byte = 8 bit
1 KB = 1024 byte
1 MB = 1024 KB
1 GB = 1024 MB
1 TB = 1024 GB
1 PB = 1024 TB

4. Variables, constants

In life, some values ​​are constant (such as: pi, gender, ID number, blood type, etc.), and some values ​​are variable (such as: age, weight, salary, etc.), and the concepts of variables and constants are introduced. .

First, let’s talk about variables :

1. Variables

The syntax is : type + name. code show as below:

int age = 150;
float weight = 45.5f;  //浮点数默认为双精度浮点数,在后面加个f,说明是单精度浮点数类型
char ch = 'w';

1.1 Naming variables

  1. It can only consist of letters (including uppercase and lowercase), numbers, and underscores.
  2. Cannot start with a number.
  3. The length cannot exceed 63 characters.
  4. C language is case sensitive.
  5. Variable names cannot be 关键字named.
  6. Variable names should be as meaningful as possible.

1.2 Classification of variables

Variables are divided into local variables and global variables

#include <stdio.h>
int global = 2019;//全局变量
int main()
{
    
    
    int local = 2018;//局部变量
    //下面定义的global会不会有问题?
    int global = 2020;//局部变量
    printf("global = %d\n", global);
    return 0;
}

Insert image description here

Summarize:

globalThere is actually nothing wrong with the definition of local variables above !
When local variables and global variables have the same name, 局部变量they are used first.

1.3 Use of variables

After understanding what a variable is, now we have to use this variable specifically. Let's take a look.

#include <stdio.h>
int main()
{
    
    
    int num1 = 0;
    int num2 = 0;
    int sum = 0;
    printf("输入两个操作数:>");
    scanf("%d %d", &num1, &num2);
    sum = num1 + num2;
    printf("sum = %d\n", sum);
    return 0;
}

Insert image description here
When vs compiles, you will find that we will appear here 4996警告.

  • Why does this warning appear?
    It's because Microsoft has its own definition of scanf_s when entering functions in vs , and it is unsafe to use the scanf function.

How to eliminate this warning?

  • The first method is to scanf()change it to scanf_s(), scanf()which is also provided by vs. This method is very simple, but the cross-platform code will make the portability worse. This method is not recommended.
  • The second method is to .cadd it to the file #pragma warning(disable:4996)so that this warning will not be prompted.
  • Follow the step-by-step operation below
    • First download the everthing software, click to open after downloading
    • Search newc++file.cpp, open files

Insert image description here

  • Paste this line in #define _CRT_SECURE_NO_WARNINGS 1, and don’t forget to add [1] after it

Insert image description here

  • This method can solve our problem once and for all~~

Create a .cfile again and you will see that line automatically appears.

Insert image description here

1.4 Scope and life cycle of variables

Now that we know how to use variables to write programs, let’s take a look at the scope and life cycle of variables.

Scope:

Scope is a programming concept. Generally speaking, the names used in a piece of program code are not always valid/usable. Generally speaking, the variable names used in a piece of code are not always valid. The scope of code that limits the availability of this name is the scope of the variable name.

Now that we understand the basic concepts, let’s demonstrate it in the code.

  • You can see that the program reports an error, saying [undefined identifier]. It can be seen that this scope has a limited scope.
int main()
{
    
    
	{
    
    
		int a = 10;
		printf("a = %d", a);
	}
	printf("a = %d", a);

	return 0;
}

Insert image description here

  • The above is the scope of local variables
  • As can be seen from the code below, no error is reported at all, because the scope of the global variable is from the time the variable is defined to the end of the entire program, and the entire variable will be destroyed, and this variable a is in this code block It will be destroyed after it ends, so we can't access this variable later.

Insert image description here

  • For the scope of global variables, you can also use it like this, define the b variable under the file add.c, then we test.cdefine the variable b in this file, and externdeclare it with this

Insert image description here
life cycle:

The life cycle of a variable refers to the period of time between the creation of the variable and its destruction.

The life cycle of local variables is : the life cycle begins when entering the scope and ends when leaving the scope.

The life cycle of global variables is : the life cycle of the entire program


Now that we’ve talked about variables, let’s talk about constants.

2. Variables

There are several types of constants in C language:

  • literal constant
  • constmodified constant variable
  • #define defined identifier constant
  • enum constants
#include <stdio.h>
//举例
enum Sex
{
    
    
    MALE,
    FEMALE,
    SECRET
};
//括号中的MALE,FEMALE,SECRET是枚举常量

//#define的标识符常量 演示
#define MAX 100

int main()
{
    
    
    //字面常量演示
    3.14;//字面常量
    1000;//字面常量

    //const 修饰的常变量
    const float pai = 3.14f;   //这里的pai是const修饰的常变量
    pai = 5.14;//是不能直接修改的!

    printf("max = %d\n", MAX);

    //枚举常量演示
    printf("%d\n", MALE);//0
    printf("%d\n", FEMALE);//1
    printf("%d\n", SECRET);//2
    //注:枚举常量的默认是从0开始,依次向下递增1的
    return 0;
}

A constant is a quantity that does not change, so it is called a constant.

5. String

1. Concept

  • Before talking about strings, let's take a look at the following first. Because what is stored and represented in the computer is binary, what we print out will also be a binary.
  • First define a character variable ch of type char, and then print it out as %c, %d, and %s respectively. You can see that the displayed results are different.
  • %c prints a character, %d prints the value of this character in the ASCLL code table, and the last %s prints the string ch.

Insert image description here

  • Then let’s talk about strings

Concept: A string of characters enclosed by double quotes is called a string

2. Find the length of the string [strlen]

After talking about the basic concepts of strings and understanding what a string is, let’s take a look at how to find the length of a string.

  • For strings, everyone should know that the end mark is a \0 escape character. We will talk about escape characters in the next module. This \0means that the string has ended. But when calculating the length of the string, this \0is not included in the calculation.
  • In other words, finding the length of a string counts \0how many characters appear before it in the string.

So how do we find the length of a string?

  • Here we need to use a function in the [string.h] header file called, which strlen()can calculate the length of a string, that is, the length before \0. We will talk about this function in detail later.
printf("len = %d\n", strlen("abc"));

Insert image description here

We mentioned earlier that the char type can define a character variable. Not only that, here, we can also define a character array. What is a character array? It means that all characters are stored in this array. Let’s look at a specific definition.

char arr[] = "abcdef";
  • The above is the basic definition of character array
  • Next, let’s look at another way. The following one is also a way to define a character array.
char arr2[] = {
    
     'a','b','c','d','e','f' };
  • As you can see, the contents of these two character arrays are the same. So whether their printed and calculated lengths are the same, let's take a look.

Insert image description here

  • Obviously, judging from the above results, they are different. Why is this? Let’s learn about it through a diagram

Insert image description here

  • From the above picture, we should be able to clearly see why the second arr2 array appears [hot, hot, hot] when printing. It should be the same if you try it in the compiler yourself.
  • Because the content value of the second array is given to 'f', it is not a complete string, but the first array is given a complete string, so it automatically has a '\0', and the second array The array is gone, so what is printed out later will only be a random value, and the traversal will not end until it encounters a \0.
  • So we can see that the length is also affected. The length of the arr1 array is 6, but the length of the arr2 array is the length after adding some random characters, which seems inaccurate.

3. Escape characters [including written test questions]

  • So what are escape characters? Let’s take a look through the code
int main()
{
    
    
	printf("abcndef");
	printf("abc\ndef");
}

Insert image description here

  • We can see from the running results that nif this is added in front of it \, its meaning will change. In the escape character, it is called [\nline feed], so you can see that it is printed to [abc] A line break occurred, and def was printed on the next line.

  • Then we will see a path that prints a test.c
  • Judging from the running results, a path is not actually printed, but a lot of spaces appear.
  • Careful friends should be able to find that the first character t of this test and the \ of the path are the same color, and they are both faded. Among the escape characters, this is called [\thorizontal tab character], which is also displayed on our keyboard. [Tab key], one tap can open 4 spaces.

Insert image description here

  • So when printf outputs something, don’t write some escape characters. What are the escape characters in C language? Let’s take a look.

Use a table to present it to everyone:

escape character Definition
? Used when writing multiple question marks in a row to prevent them from being parsed into three-letter words
\ ’ Used to represent character constants
\“ Used to represent double quotes inside a string
\ \ Used to represent a backslash, preventing it from being interpreted as an escape sequence character
\a Warning character, buzzer
\b backspace character
\f paper feed character
\n newline
\r Enter
\t horizontal tab
\v vertical tab
\ddd ddd represents 1 to 3 octal digits. Such as: \130X
\xdd dd represents 2 hexadecimal digits. For example: \x30 0

Let’s talk about the key points

  • The first is two or three. Look at the first line of code. If what you printf is ['''], then the compiler will report an error. You originally wanted to print a [']. What should you do at this time? Just add a \ in front, which becomes an escape character, and then you can output it like the running result.
  • Then the third one is the same, so I won’t explain it in too much detail here.

Insert image description here

  • Then there is the printing path we just mentioned. How can we print out this path? That's right, you just need to add another [\], which means a backslash. Let's take a look in the code.
  • As you can see, this path has been completely printed out.

Insert image description here

  • Finally, let’s talk about the last two points about octal and hexadecimal.
  • Same, first give the running results

Insert image description here

  • Regarding [\ddd], it represents octal, that is, calculated through octal. If you use %d to print out the result of the calculation, if you use %c to print out the ASCLL code symbol corresponding to the number.

  • The same is true for hexadecimal, the /xdd value is decimal, and the same is true when looking at the print above.

  • For [\x3a], use a*160

  • Then let’s talk about a written test question about escape characters

printf("%d\n", strlen("c:\test\628\test.c"));
  • What is the result? Answers vary
  • The real answer is [14], why? let's take a look

analyze

  • First of all, in the first step, we have just learned about escape characters. [\t] must represent a character, so 18 is excluded.
  • Then in the second step, I believe that what everyone is most confused about is this \628. This is actually the \ddd we mentioned above, but can this be counted? At this time, you have to think about whether octal can contain 8. Octal is a number from 0 to 7, so there will be no 8, so this [\62] counts as an escape character.
  • Finally we can get the answer as [14]

6. Notes

First we need to understand what annotations are and what they can be used for.

  1. Comments can temporarily block code that you don’t need or don’t want to delete yet. When the program is executed, the commented code will be skipped directly and will not run.
  2. If there is some obscure code in some programs , the code you write may need some comments so that people who read your code later can know what this code means. In this case, you can put it above this code Or write some comments below so that future generations can understand the code you wrote.
int main()
{
    
    
	//下面是创建一个整型变量并赋值10
	int a = 10;
	int b = 100;
	//C++ 注释风格 - C99

	/*	C语言的注释风格
	int c = 10;
	int d = 20;
	printf("ff");
	*/	// - 嵌套的话此处结束注释
	//不支持嵌套注释

	return 0;
}
  • Let's analyze it. For double slash //, this is the comment style for C++ in C99. So what is the comment style of C language? That is/**/
  • But I also added a sentence later, that is, this annotation method in C language cannot be nested. For example, if you add a /**/ to the outer layer, return 0; will not be annotated. why? Because the one above matches the one above first, it will not go to the one below /*.return 0;

7. Select statements

  • In C language or other programming languages, there are three structural methods: [Sequence], [Selection] and [Loop]
  • So what is this selection statement? That is, you sometimes face two or more choices, and different choices correspond to different results.

Let’s take a look at the code specifically.

int main()
{
    
    
	int input = 0;
	printf("你要好好学习吗(1/0)\n");
	scanf("%d", &input);
	if (input == 1) 
	{
    
    
		printf("拿一个好offer\n");
	}
	else 
	{
    
    
		printf("回家种田\n");
	}
	return 0;
}
  • The above code is a selection statement. You can enter your choice in the terminal and ask if you want to study hard. If you choose 1 to study hard, then you can get a good offer ; but if you choose 0 to be miserable, then you can only go home and farm.

8. Loop statements

Then let’s talk about another form, which is the loop statement

  • What is a cycle? A loop is when you do something over and over again until a certain condition is met before exiting.

Then let’s take a look at it through a piece of code

int main()
{
    
    
	int line = 0;
	printf("好好学习\n");
	while (line < 20000)
	{
    
    
		printf("写代码:%d\n", line);
		line++;
	}
	if (line == 20000)
		printf("好offer\n");
	return 0;
}

Insert image description here

  • And for loops, there are not only while, but also do…while(), forthese, we will talk about in the follow-up

9. Function

A function actually encapsulates a function into a module, and then this module can be called multiple times to simplify the code.

  • Let’s look at this piece of code first
  • This is a code for summing two numbers. It inputs two data and then outputs their sum.
  • But imagine that if we want to find the sum of two other numbers, we have to input it again, and then the summation code has to be written again. This only increases the amount of code and makes the entire program very redundant. What should we do? What about simplification? Yes, just use functions.
int main()
{
    
    
	int num1 = 0;
	int num2 = 0;
	int sum = 0;
	printf("请输入两个操作数字:>");
	scanf("%d %d", &num1, &num2);

	sum = num1 + num2;
	printf("sum = %d\n", sum);
	return 0;
}
  • Let’s take a look at what it looks like after simplification using functions
  • This code uses three summations and obtains three summation results.
int Add(int m, int n)
{
    
    
	return (m + n);
}
int main()
{
    
    
	int sum1 = 0;
	int sum2 = 0;
	int sum3 = 0;

	sum1 = Add(1, 2);
	sum2 = Add(3, 4);
	sum3 = Add(5, 6);

	printf("sum1 = %d\n", sum1);
	printf("sum2 = %d\n", sum2);
	printf("sum3 = %d\n", sum3);
	return 0;
}

Insert image description here

10. Array

1. Definition of array

  • First of all, we know the concept of numbers, but when we need a bunch of numbers, where do we store these numbers? That's right, it is stored in something called an [array].
  • So how to store it? Let’s take a look.
int a[10] = {
    
     1,2,3,4,5,6,7,8,9,10 };
  • First of all, you need to declare what type the array is, whether it is integer, character, floating point, etc. In the case of an array, these data can be stored, and then add a variable after it, and you []can write in parentheses what you are going to do for it. How much space does this array open up? For example, if it says 10 above, then the maximum number of data that can be stored in this array is only 10. But if you don't write it, you can store more. I will teach you a method later. How to calculate the size of this array without giving the specific size of the data?
  • Here it is given first. You can take a look first. sizeof() is a unary operator, which is used to calculate the space byte size occupied by the operand you use.
int sz = sizeof(a)/sizeof(a[0]);
  • As mentioned earlier, in addition to storing integer data, arrays can also store character and floating-point data.
char b[] = {
    
     'a','b','c'};
double c[] = {
    
    2.5,6.9,7.7,1.5 }

2. Subscript of array

Now that we know how to declare arrays, how do we get the arrays we declare?

  • C language stipulates that each element of the array has a subscript, and the subscript is accessed starting from 0. The following is 下标the element with subscript 8 in the a array that we access, and it will be printed as 9
//下标访问数组元素
printf("%d\n", a[8]);
  • You can see the details clearly by looking at the diagram.
    Insert image description here

  • As you can see, the size of the arr array here is 10. What will happen if we access the subscript 18? Let’s check it in the compiler.

  • As can be seen from the figure, the total subscript is only 9. If you access it, an out-of-bounds access will occur, and what you access will be a random value.

Insert image description here

3. Use of arrays

  • Take a look at the code. We first defined an integer array with a size of 10, and then initialized its content to 0. Then we entered some data through scanf in a while loop, and put them into the array one by one through subscripts. Then, it's still the same, loop through the array, and call printf to print out the data inside.
  • This is one way to use arrays. We will explain the rest in detail in the array chapter later.
int main()
{
    
    
	int arr[10] = {
    
     0 };
	//0 ~ 9 - 输入10个值给数组
	int i = 0;
	while (i < 10) 
	{
    
    
		scanf("%d", &arr[i]);
		i++;
	}

	i = 0;
	while (i < 10) 
	{
    
    
		printf("%d ", arr[i]);
		i++;
	}
	return 0;
}

Insert image description here

11. Operator

There are many operators in C language. Here we will give a brief introduction and will explain them in detail later.

1. Arithmetic operators

Insert image description here

  • Here we focus on [division] and [remainder]
  • First look at this code, what will the result be?
int a = 7 / 2;
printf("%d\n", a);
  • The running result is 3, because the left and right sides of the operator are integers , so integer division is performed, including the following paragraph. The running result is 3, just because of the float floating point number, there are 6 more 0s after the decimal point.
float f = 7 / 2;
printf("%f\n", f);
  • Then how to turn it into floating point division, that is, to get the answer of 3.5, you only need to change any number 7 or 2 to a floating point number, for example, 7.0/2.0, at least one operand is executed as a floating point number It's floating point division

let's take a look at the results

Insert image description here

  • Then let’s take a look at the [remainder] operator
int main()
{
    
    
	// % 取余操作符,关注的是除法后的余数
	int a = 7 % 2;	//商3余1
	printf("%d\n", a);
	return 0;
}
  • What you get is the remainder after dividing one integer by another integer.

Insert image description here


2. Shift operator

Insert image description here

  • Let’s understand this first. I won’t go into details for now. I will explain it in detail in the operator chapter.

Move left to expand,
move right to shrink


3. Bit operators

  • It's called shift above, and it's called position here. Is there a big difference? The difference is huge. They are two completely different concepts.
    Insert image description here

  • This will also be explained in detail in later chapters.


4. Assignment operator

Insert image description here

  • Regarding the assignment operators, the first one should be familiar to everyone, it is our common assignment operation, and the following ones are compounded by some [addition, subtraction, multiplication, division, remainder and shift]. You can try it yourself in the compiler.

5. Unary operator

Let’s focus on the monocular algorithm

Insert image description here

  • The first is this negation operation. In C language, there are only two types of expressions: true and false. 0 represents false, and 非0represents true.
  • So look at the code below. This a is [true], so the "haha" statement will be executed. But if you replace a with 0, then !ait is [true] and the "hehe" statement will be printed.
//C语言是如何表示真假的呢?
//0表示假,非0表示真
//-1 表示的就是真
int main()
{
    
    
	//把假变成真,把真变成假
	int a = 10;
	if (a)
		printf("haha\n");
	if(!a)	//这个不执行
		printf("hehe\n");
	return 0;
}
  • Then [get positive] [get negative] is very simple. When you see the following code, the opposite number of a will be printed.
int a = -10;
printf("%d\n", +a);
printf("%d\n", -a);
  • Then for the address taking and asterisk operator, we will introduce it in the pointer part below.
  • Then let’s take a look at the sizeof() operator. Is sizeof() a function? No, sizeofit's an operator
int a = 10;
char c = 'w';
int arr[10] = {
    
     0 };	
printf("%d\n", sizeof(a));		//4
printf("%d\n", sizeof(c));		//1
printf("%d\n", sizeof(arr));	//40
  • As for the sizeof() operator, it is used to calculate the size of the memory space occupied . The unit is bytes, so the output of the above code is the size of the memory space occupied by integers, characters and an array.
  • Because these variables are defined using variable types such as int and char, you can directly use sizeof() to pass in the types of these variables , and the results will be the same.
printf("%d\n", sizeof(a));			//4
printf("%d\n", sizeof(int));		//4
printf("%d\n", sizeof(c));			//1
printf("%d\n", sizeof(char));		//1
  • Since this is an operator, why do we need the parentheses? Wouldn't it be better to just remove it, otherwise it will cause ambiguity, like the following
printf("%d\n", sizeof int);
  • When we run it on the compiler, we can see that it cannot run~~
  • This actually better illustrates that sizeof is an operator, not a function, and the parentheses can be omitted.
  • Then we can draw the conclusion: variables can be bracketed, but types cannot be bracketed.

As we mentioned above, when we do not set the number of initial elements for an array, we can use sizeof() to calculate how many elements there are in the array.

  • It is as follows, sizeof(arr) is the size of the entire array, sizeof(arr[0]) is the size of an element, of course you can also write it as [sizeof(int)], because the size of an element in an integer array is certain It is 4 bytes, which is the size of bytes occupied by int.
printf("%d\n", sizeof(arr));;
int sz = sizeof(arr) / sizeof(arr[0]);
printf("%d\n", sz);

Then let’s talk about [pre-, post-] and [pre-, post-++]

  • These two are actually the same, let’s take a look at [pre-, post-++]
  • For prefixing ++, ++ is assigned first, so the following a will give the value after ++ to b, and then it can also ++, so the final output is 11 11
int a = 10;
int b = ++a;	//先++后赋值
// a = a + 1
// b = a

printf("%d %d\n", a, b);	//11 11
  • It's different for the postfix ++. On the contrary, c will first give its value to d, and then ++ it by itself, so what d gets is 10, and after c is done with ++, it will be 11.
int c = 10;
int d = c++;	//先赋值后++
// d = c;
// c = c + 1

printf("%d %d\n", c, d);	//11 10

Insert image description here

  • Then let’s talk about [preposition, postposition –], the same reason
int a = 10;
int b = --a;	///先--在赋值

printf("%d %d\n", a, b);	//9 9

int c = 10;
int d = c--;	///先赋值后--

printf("%d %d\n", c, d);	//9 10

Insert image description here

  • Then the same goes for this section. The first thing to print a– must be the previous value, and then the next thing to print is the value after –, which is 9.
int a = 10;
printf("%d\n", a--);	//先使用,后--
printf("%d\n", a);

Regarding pre- and post-position ±, I always like to ask some interview questions to confuse you. In fact, it makes no sense at all. Let’s take a look.

int a = 1;
int b = (++a) + (++a) + (++a);
printf("%d\n", b);

Insert image description here

  • From the perspective of VS, the running result of this code is 12, but in the Linux gcc compiler, the running result is actually 10

  • If a piece of code runs with different results in different compilers, it means that there is something wrong with this piece of code. To be precise, there is ambiguity.

  • Let’s talk about the last one of the unary operators, forced type conversion

  • First, let’s look at these two lines of code. What do you think this will output?

int a = 3.14;
printf("%d\n", a);
  • Because 3.14 gave an integer variable a, only integers will be retained. At this time, please look at the Warning I drew with a red pen below, saying that [converting from "double" to "int"], data may be lost.
  • What should we do at this time? You can add an (int) in front of 3.14 to force the number to an integer, which is the line of code I commented out above. If you try running it again at this time, the Warning will not be reported.
    Insert image description here

6. Relational operators

Insert image description here

  • For the first four, just use them directly and compare them intuitively. Let’s talk about the next two
  • That is to say, it compares whether two numbers are equal or not. This should be distinguished from [=] in [Assignment Operator]. One compares two numbers or variables, and the other performs assignment operations. There is no confusion. Got it
int a = 10;
int b = 20;

if (a == b)
	printf("haha\n");
if(a != b)
	printf("hehe\n");
  • At this time, some students asked, in addition to comparing numbers, can strings be compared? Let’s take a look.
char arr1[] = "abcdef";
char arr2[] = "abcdef";
if (arr1 == arr2)
	printf("==\n");
else
	printf("!=\n");

Insert image description here

  • It can be seen that the two character arrays are obviously the same, but they took the second branch and printed [!=]. There is actually a problem here. why? We will talk about this later. The array name is the address of the first element of the entire array. In fact, [==] compares their addresses.
  • For string comparison, there is a special function in C language called strcmp(). It belongs to the [string.h] header file like strlen(). If the two compared are equal, it will return 0, the former is greater than the latter, returns a number > 0, the latter is greater than the preceding, returns a number < 0, so you only need to judge the size of the sum 0
//两个字符串不可以用“==”来判断是否相等,使用strcmp(库函数)
char arr1[] = "abcdef";
char arr2[] = "abcdef";
if (strcmp(arr1,arr2) == 0)
	printf("==\n");
else
	printf("!=\n");

In this case, the result will be correct

Insert image description here


7. Logical operators

Insert image description here

  • Logical and [&&] means and, logical or [| |] means or. 1 if true, 0 if false
  • For logical AND, the result is 1 only if both numbers are 1. As long as one of them is 0, the result is 0.
int a = 5;
int b = 4;
int c = a && b;
printf("c = %d\n", c);
if (a && b)
	printf("hehe\n");

Insert image description here

  • It can be seen from the above code and running results that because a and b are not 0, their results are 1, and then the following if judgment can be entered. If any one of a and b is changed to 0, the result will be 0. , and then it will not enter the following judgment
  • For logical OR, as long as one of the numbers is 1, it is 1, and only if both numbers are 0, it is 0.
  • So the following display result is 0, and there is no judgment of this if condition.
int a = 0;
int b = 0;
int c = a && b;
printf("c = %d\n", c);
if (a || b)
	printf("hehe\n");

Insert image description here


8. Conditional operator

  • The following is a simple if branch judgment, and then assigns a value to b
int a = 10;
int b = 0;
if (a > 5)
	b = 3;
else
	b = -3;
printf("b = %d\n", b);
  • But for the ternary operator, there is no need to be so troublesome, just this sentence is enough
  • The specific meaning is to determine whether a is greater than 5. If so, assign b to 3. If not, assign b to -3.
a > 5 ? b = 3 : b = -3;
  • But there is a simpler way to write it. It is also judged in the same way, and finally the value obtained is given to b on the left.
b = (a > 5 ? 3 : -3);

9. Comma expression

Let’s first talk about its operation rules: it is calculated from left to right, and the result of the entire expression is the result of the last expression.

  • A comma expression is listed. You can try to calculate it yourself. The variables involved in the operation will change every time an expression is passed. Finally, the printed values ​​of a, b, and c have also changed.
int a = 3;
int b = 5;
int c = 0;
int d = (a += 2, b = b - c + a, c = a + b);
		//a = 5	 b = 10			c = 5 + 10 = 15
printf("d = %d\n", d);
printf("%d %d %d\n", a, b, c);

Insert image description here


10. Others

[Subscript reference operator]

  • What is the subscript reference operator? That is [ ], the array size we specified when defining the array
int arr[10] = {
    
     0 };
arr[4] = 5;
printf("%d\n", arr[4]);
  • For the above code, we call arr4 the two operators of [ ]
  • Let’s recall the [+] operator. This is a binary operator. For example, 2 + 3, then 2 3 can be said to be the two operators of + . For us, 2 + 3 can be written as 3 + 2, Since binary operators can be interchanged in this way, can [subscript reference operator] be used? The answer is yes! ! !
  • We can also write the above code like this
int arr[10] = {
    
     0 };
4[arr] = 5;
printf("%d\n", 4[arr]);

The next thing is this operator called [Function Call]

int Add(int x, int y)
{
    
    
	return (x + y);
}
int main()
{
    
    
	int c = Add(2, 3);	//()是函数调用操作符,操作数是:Add 2 3
	printf("c = %d\n", c);
	return 0;
}
  • It is very clear that it is the two parentheses outside the function. We also mentioned this when talking about the sizeof() operator above. For sizeof(), although it has (), it cannot be regarded as a function. It will also be an operator
  • Then for the function call operator, see the Add function above, () is the operator, then the operand is Add 2 3

12. Common keywords

1 Introduction

Now that we understand the common operators in C language, let’s take a look at the keywords in C language

  • First of all, for keywords, the two points we need to pay attention to are

    1. Keywords are used directly, we need to understand
    2. Variable names cannot be keywords

  • As can be seen from the following, there are still quite a lot of keywords in C language

Insert image description here

  • First let’s talk about [auto] separately. It is quite special because in the compiler, when you define a variable, it exists by default.
  • Auto, translated as automatic, refers to automatic variables in C language. All local variables you define are automatically created and automatically destroyed, so local variables are all modified by auto.
  • Just like the integer variable a below, no error will be reported if you add auto in front of int or not. The reason is that all local variables are auto.
//auto int a = 10;
int a = 10;	//auto可以省略

2. The underlying principles of data storage

  • Regarding registers, it involves data storage. Let’s talk about it in detail so that everyone can first understand the underlying principle.

First of all, you need to know where the data in the computer is stored.

①Memory ②Hard disk ③Cache ④Register

Then let’s take a look at this picture
Insert image description here

  • For the registers in the computer, the space is actually very small, and the unit is only bytes, but its reading and writing speed is very fast, and it can interact directly with the CPU [central processing unit]

  • Then the space becomes larger as you go down. Memory is now generally 8G, 16G, and larger, 32G, not like 2MB long ago; for hard drives, when we go to the market to buy them, they are also 500G, 1 T size

  • Our register, because its reading speed is very fast, so the CPU directly gets the data from the register, but what should we do if the register memory is not large enough at this time? If you can't install so much, the cache as we know it, that is, the Cache, will provide memory for the register. If there is not enough in the cache, then the memory will continue to provide it . In this way, the overall operating efficiency of the computer is improved.

  • The following is the usage of the keyword [register]. Adding this keyword when defining the variable b means [recommending] the compiler to put this variable in a register. It should be noted here that it is only a suggestion, not to put it directly. enter

  • You can check some information on how to use it specifically. I won’t go into too much detail here.

//建议把b放到寄存器中
register int b = 10;

3. typedef keyword

The first is this [typedef]. This keyword is used for renaming, and is more commonly used on structures.

typedef struct Linknode{
    
    
	int data[MaxSize];
	struct Linknode* next;
}LNode;
  • Of course, it is not only applied to structures, but also can be renamed for some data types, such as the following [unsigned int]. Later, when you use [uint] to define variables, it will be the same as [unsigned int].
typedef unsigned int uint;

int main()
{
    
    
	unsigned int num1 = 0;
	uint num2 = 0;	//与num1一样
	return 0;
}

4. static keyword

Finally, let’s talk about the static keyword

  • Here is a talk about the static keyword in C language. First of all, you need to understand what the static keyword can be used to modify. It can mainly be used to modify the following three
    • Modify local variables
    • Modify global variables
    • modified function
4.1. The static keyword modifies local variables

First, let’s take a look at static modification of local variables.

void test()
{
    
    
	int a = 3;
	a++;
	printf("%d ", a);
}
int main()
{
    
    
	int i = 0;
	while (i < 10)
	{
    
    
		test();
		i++;
	}
	return 0;
}
  • What do you think the above program will output? Seeing the main program, a while loop is used to control the i variable. When i = 10, the edge will not enter the loop, so it will loop 10 times. Then look at the internal test() function. Every time this function is called in the loop, Define a variable a, then change it to 4 after ++, and then output
  • So the result of running this program is that it will output 10 4s.

Insert image description here

  • Then we modify the defined variable a and set it as a static variable, that is, add a static modification in front of int
  • So what do you think the above program will print out at this time?
static int a = 3;
  • First, you need to understand the characteristics of static variables and the differences between other ordinary variables.

① Ordinary local variables are placed on the stack area of ​​​​the memory. When entering the local scope, the variable is created, and the variable
is destroyed when leaving the local scope. ② When static modifies the local variable, the local variable opens up space in the static area. At this time, the local variable Variables are not destroyed when they go out of scope. The next time they enter the scope, the data left over from the last time will be used (the storage location is changed, from the stack area to the static area, which changes the life cycle of the variable)

  • Knowing this, you should know what the printed result is. 4~13Every time you enter this test() function, this variable a will no longer be executed, that is, it will only be defined when you enter this function for the first time, and then It will always exist, and it will not be destroyed until the end of this program, so what this variable a retains every time is the result after the last ++

Insert image description here

  • After seeing the above results, I believe you also have a preliminary understanding of static variable modified members. Ordinary local variables are stored in the stack area. But for static variables, do you know where it is stored?
  • That's right, as for the static area, let's use the picture below to understand how variables are stored in computer memory.
4.2. The static keyword modifies global variables

add.c:

int g_val = 2022;

test.c:

extern int g_val;	//声明外部符号
int main()
{
    
    
	printf("%d\n", g_val);
	return 0;
}
  • The above global variable declaration and the [extern] keyword call declare a variable, but what happens if the g_val variable is defined as a static variable? let's take a look

Insert image description here

  • As you can see, this external command cannot be parsed

    Global variables have external link attributes. If the global variable is modified by static, the external link attribute becomes an internal link attribute , and other source files will no longer be able to find this symbol through the link.

  • So it can be concluded that local variables modified by static can only be used inside the .c file where they are located~

4.3. The static keyword modifies functions
  • In fact, the concept is the same. If you don't use static modification, then you can use the extern keyword to make an introduction, then it is an external link. But if you use static modification, then this function can only be used in the original source file, not It can be used for external files. This is an internal link.

Insert image description here

  • As you can see, for the same reason, this is an internal link and cannot be accessed from the outside, even with the extern keyword.

13. #define defines constants and macros

  • First let’s talk about this #define to define constants
#define MAX 100
int main()
{
    
    
	printf("%d\n", MAX);
	int a = MAX;
	int arr[MAX] = {
    
     0 };

	printf("%d\n", a);
	return 0;
}
  • Seeing the above code, I used #define to define a MAX constant with a value of 100. In the main function, you can use this constant directly to print and assign values ​​to it.

  • Of course, in addition to defining integer data constants, other types are also possible, such as strings.

#define STR "abcdef"
printf("%s\n", STR);

After talking about using #define to define constants, let’s talk about macro definition, which is also declared using #define.

  • Below is a summation function and how to write macro definition summation
//函数
int Add(int x, int y)
{
    
    
	return x + y;
}
//宏
#define ADD(x,y) ((x) + (y))	//为了保持整体性

In addition to the sum function, you can actually define other functions. For example, to compare the larger value of two numbers, you can write it as follows, using a ternary operator.

#define MAX(x,y) ((x) > (y) ? (x) : (y))

14. Pointer

1 Introduction

  • Regarding pointers, many students have heard from others when they first started learning C language that pointers are difficult and difficult. Operations such as accessing memory and taking addresses are both dangerous and difficult.

2. Concept and introduction of memory

  • As for pointers, they are directly related to the memory in the computer, so let’s talk about memory-related knowledge first and let everyone understand the underlying knowledge first.

  • Regarding memory, you should have heard about it in daily life, such as the memory sticks we buy for computers and notebooks, and the memory of our mobile phones. For this memory , it is usually 8G or 16G, which is similar to the memory. The corresponding one is the hard drive , which is usually 500G or 1T

  • In a computer, memory is a continuous storage space, but this cannot be allocated to each part for use. At this time, the memory is divided into small memory units. In order to effectively access each part of the memory unit, the memory unit is numbered, and these numbers are called the address of the memory unit.

Insert image description here

  • From the above diagram, you can intuitively see how the memory is stored in the computer. The size of each memory unit is one byte, and then they are numbered, so that when the outside world needs to access it, , you can specify an access based on this memory number. Each of these numbers is actually called an address.

After knowing the basic concept of address, let's go to the compiler to see how this address is divided.

  • First, let’s look at the simplest sentence of code, which is to define a variable a. We all know that int integer variables occupy 4 bytes in memory. Let’s put a breakpoint on this code and enter the memory window to take a look. after all
int main()
{
    
    
	int a = 4;
}

Insert image description here

  • Enter this [&a], and you can see the 4 memory units opened for variable a in the memory. The first address starts from [0x00CFF814]. The integer variable occupies 4 bytes. Look at the 4 I framed, For each byte it has its own number, &a is the address of the first byte.

Insert image description here

  • So how do we use code to get this address?
&a		//	拿到的值第一个字节的地址
  • Let's take a look again through the debugging window. Obviously, we got the results we wanted

Insert image description here

  • Or if you don’t want to go to the debugging window to see it, that’s okay too.
  • We can print it directly with printf. You can see that %p is used here, which is specifically for address access. If you are %d, what comes out is the formatted number.

Insert image description here

  • After talking about memory and address, the next step is the real pointer, but in fact, for the address, it is a pointer. The pointer is an alias for the address. Let's take a look at how the pointer is defined.
int a = 4;
int* pa = &a;
  • As you can see, I added a [*] asterisk after the int type, which means that this is a pointer type variable. This pa is a [pointer variable], because as mentioned above, a pointer is an alias for an address, so this The equation is established. The pointer variable pa can receive the address of a and also stores the address of a.

Insert image description here


  • Since this pointer variable stores the address of the variable, is it possible to access this address through this pointer variable and print it out? The answer is yes, this involves our next knowledge point, which is pointer dereference

  • Use the [*] operator

*pa
  • As defined above, pa is a pointer variable. *pa actually finds the space where this address is stored through the address stored in pa. What is obtained at this time is actually the variable a. Because this address is obtained, all the variables in this space are The starting point of storage is the content of variable a. Let’s take a look at it by running

Insert image description here

summary

①The pointer is actually the address, and the address is the number of the memory unit
②When the address is stored, it can be placed in a variable, which is the [pointer variable]
③The pointer we are talking about is actually called [pointer] in professional terms Variable]
④[*] Asterisk dereference can quickly access the location where the variable is stored in the memory through the address where the variable is stored, and then obtain the content.

3. The size of the pointer variable

  • To find the size of a variable, use sizeof()this keyword
int a = 10;
printf("%d\n",sizeof(a));
printf("%d\n",sizeof(int));
  • The above code prints 4 4. What about the following code?
int a = 10;
int* pa = &a;
printf("%d\n",sizeof(pa));
printf("%d\n",sizeof(int*));
  • Obviously, it’s also 4 4

Insert image description here

  • In the upper left corner of the compiler, there are x64 and x86. This thing is called [Running Environment]. Now I changed it to 64 bit,

Insert image description here

  • Obviously, the same code produces different values ​​under different operating environments.

Insert image description here

  • Pointer variables store addresses, so the size of the pointer variable depends on how much space is needed to store an address.

You must see that it is not an address, but actually a stored address line. Yes, it is the address line on the hardware.

  • The computer we use is actually hardware. If it is hardware, it needs to be powered on. In fact, there is such an [address line] on our computer. The 32-bit and 64-bit we mentioned above can also correspond to this Among the address lines, because in a 32-bit environment, there are 32 address lines; in a 64-bit environment, there are 64 address lines.
  • When we have 32 address lines, there will be an electrical signal after powering on. This electrical signal is 0/1. So what exactly do these electrical signals look like? Let’s take a look.

Insert image description here

  • It is a storage method like 0101, and then according to the binary system, how many addresses can be stored in these 32 address lines are listed. Here to tell you, there are a total of 232 addresses that can be stored.
  • Then we can actually draw the conclusion that an address sequence composed of 32 0s or 1s requires 32 bits, which is 4 bytes, to store , and these 4 bytes correspond to the size of our pointer variable. So we can figure out why the size of the pointer variable is 4 bytes
  • Then let’s explain why this pointer variable becomes 8 bytes in a 64-bit environment. In fact, you can also deduce this yourself. An address sequence composed of 32 0s or 1s requires 32 bits, so here we need 64 bits, according to 1B = 8bit, so 8 bytes are needed to store , which can also be concluded that the size of the pointer variable in a 64-bit environment is 8 bytes

After understanding the above, we know that the size of pointer variables depends on the size of the address. Let's take a look at the size of these pointer variables. I am running in a 32-bit environment.

printf("%d\n", sizeof(short*));
printf("%d\n", sizeof(long*));
printf("%d\n", sizeof(long long*));
printf("%d\n", sizeof(float*));
printf("%d\n", sizeof(double*));
  • Is it 1 4 8 4 8? If this is the answer, please go back and look at the above derivation process carefully.
  • Let’s take a look at the results

Insert image description here

  • As you can see, they are all 4. They are all pointer variables. What is the size of a pointer variable? It is the size of the address. As mentioned above, I am running in a 32-bit environment, so it is 32. The address line requires 32 bits, which is 4 bytes to store

  • As you can see, a lot of Warnings are reported. Why is this? Obviously this code can be run, and it can also produce results. Here, a [symbol mismatch] problem is reported. Why? Let me make it clear here that when sizeof() calculates the size of data bytes, the default return type is unsigned int, which is an unsigned integer. However, %d is used to print integer variables, so [unsigned integer] appears here. matching] problem

Insert image description here

  • You should modify it and ask %zu to print it. Just remember that it is specially used to print the return value of sizeof(). It doesn't matter if you don't understand it in depth.
  • Modify as follows. You can see that there is no more Warning.

Insert image description here

15. Structure

The structure is also an important part of the C language, because the C language is a process-oriented language. It is not object-oriented like C++ and Java. It has classes, and member variables and member methods can be defined within the class, so There is a structure in C, which can be used to describe complex objects.

  • We have all gone to bookstores to buy books. We know that a book has a title, publisher, and author. These can all be defined as character types, but there is also the price of the book. How to define it? Can it also be defined as a character type? Of course not, It is still defined as a floating point type. In addition to these, there are actually many types that need to be defined.
  • But for so many types, do they have to be separated? This is definitely not possible, so this book will not be a whole. If you have object-oriented thinking, you will know that its attributes and behaviors are all defined in this class. They are all encapsulated. This is the encapsulation of classes.
  • In C language, we can also implement encapsulation, that is, using structures

We use the student type to make a package

  • As you can see, we have used the keyword struct, which is the keyword that belongs to the keyword module and will be explained here. stu is the abbreviation of student. As you can see, there are three types in it, namely name, age and grades . Because a student has these three attributes, which are their common attributes, they can be packaged together.
struct stu {
    
    
	char name[20];		//姓名
	int age;			//年龄
	float score;		//成绩
};
  • So how to define variables for initialization of composite types such as structures? Let’s take a look.
  • In fact, it is the same as ordinary variables. You have to regard [struct stu] as a type. Variables defined with this type are called [structure variables]. For the initialization of each structure variable, a pair of Curly brackets {}, go inside to initialize the variables you defined in the structure one by one in order.
  • Warm reminder: The float score type here is followed by f and double types as a distinction.
struct stu s1 = {
    
     "zhangsan",20,80.5f };
struct stu s2 = {
    
     "lisi",25,90.5f };

So how to print out these variables after initializing them, and then access the information of each student?

  • Here we need to use the [.] dot operator, which we left earlier. This operator can access the information of the current variable through the variables declared in the structure. The code is as follows:
//格式:结构体变量.结构体成员
printf("%s %d %f\n", s1.name, s1.age, s1.score);
printf("%s %d %f\n", s2.name, s2.age, s2.score);

Okay, my first introduction to C language ends here. I will sort out the entire content of C language later. I hope it will be helpful to everyone! ! ! Let’s work together!

Guess you like

Origin blog.csdn.net/2201_76004325/article/details/134981046