C language --- initial C language

1. Initial C language

1. Compilers mainly include: Clang, GCC, WIN-TC, MSVC, Turbo C, etc.

What is compilation?

test.c----------------------------->test.exe

This process needs to go through 编译, 链接and other processes, and the function implemented by many compilers is to compile the test.c we wrote.

2. VS2022 (IDE) installation

Official website: https://visualstudio.microsoft.com/zh-hans/?rr=https://www.microsoft.com/zh-cn/

insert image description here

insert image description here

Document description:

  • A file ending in .c is called a source file
  • Files ending in .h are called header files

Create a source file below

insert image description here

insert image description here

3. The first C language project:

#include <stdio.h>
int main()
{
    
    
	printf("hehe\n");         
	return 0;
}

//VS中点击F5运行
//C语言中一定要有main函数,main函数是程序的入口
//标准的主函数的写法
int main()
{
    
    
    return 0;
}
//这里有个对应的关系,return “0”和int相对应,int是整数类型,0是整数
//printf是个库函数,是别人开发好我们可以直接使用的,所以说在使用之前我们需要声明一下,所以“#include <stdio.h>”就是个说明
//std---代表标准的意思,i---代表input,o---代表output,所以说stdio.h就是标准的输入输出的头文件

4. Data type

char                    //字符数据类型
short                   //短整型
int                     //整形
long                    //长整型
long long               //更长的整形
float                   //单精度浮点数
double                  //双精度浮点数
int main()
{
	printf("%d\n", 100);       "%d"以整形的方式打印,可以把"%d"---改为"%zu"
	return 0;
  • How big is each data type? A library function is used here to display
int main()
{
    
    
	printf("%d\n", sizeof(char));
	printf("%d\n", sizeof(short));
	printf("%d\n", sizeof(int));
	printf("%d\n", sizeof(long));
	printf("%d\n", sizeof(long long));
	printf("%d\n", sizeof(float));
	printf("%d\n", sizeof(double));
	return 0;
}

1
2
4
4
8
4
8
//以上单位为“字节”
//可以发现int数据类型大小怎么和long的数据类型大小一样呢?
//原因:C语言规定:sizeof(long)>=sizeof(int)

4.1, %+letter

%d-----------打印整型(有符合整型)
    
%u-----------用于打印unsigned int num = 0这样的数据类型,这是无符号整型
    
//有符号整形包含正负数,无符号整型不包含复数。

%c-----------打印字符
    
%s-----------打印字符串
    
%f-----------打印float类型的数据
    
%lf----------打印double类型的数据
    
%zu/zd----------打印sizeof()的返回值
 
%p-----------打印地址
    
%02d--------------输出02/05...这样的效果
    
%2d---------------输出 2/ 5   //也就是说前面的0被空格替代了。
    
%-2d-------------左对齐
    
%.1f--------------打印小数点后一位的小数
    
float a = 0.0f       //float类型数据进行初始化
    
double a = 0.0       //double类型数据进行初始化
    //一般的直接赋值3.14编译器认为它是double类型的数据,为不是float类型的。
a=2 c=1 b=5 8
a=2 c=1 b=7 10
            12
            14
            16

4.2. Computer unit

bit---------bit, computer binary 101010101010. Storing a "1" or "0" occupies a bit

byte-------byte, 1 byte=8bit

kb----------1kb=1024 bytes

Gb----------

tb------------

pb------------

4.3 Briefly describe the nature of variables

int main()
{
	int age = 22;         //age = 22赋值的这个过程叫做初始化,如果不进行赋值初始化,那么这个变量是随机值,这样一来这个变量不好掌控,所以尽量进行初始化。
	return 0;
}

//int整数类型大小为4字节,实际上就是向内存申请了一个4字节的内存大小,命名为age,用来存储“22”这个数据的。

5. Variables and constants: local variables and global variables

Invariant quantity/unmodifiable quantity, represented by constants in C language, and variable values ​​in C language

5.1, the method of defining variables

int main()
{
	int age = 22;
	return 0;
}

5.2. Classification of variables

  • local variable
  • global variable
#include <stdio.h>

int global = 2019;    //全局变量
int main()
{
	int local = 2018;
	int global = 2020;     //局部变量
	printf("global = %d\n", global);          //那这里global值为什么?
	return 0;
}

输出:
    2020

So it can be concluded that when the global variable and the local variable have the same name, the local variable takes precedence. Of course, if there are only global variables, then the global variables will be displayed

Error code example: Duplicate variables cannot be declared in the same scope:

int main()
{
	int local = 2018;
	int local = 2020;    
	return 0;
}
//会报错

5.3, the use of variables - write a code to calculate the sum of 2 integers

#include <stdio.h>
//scanf是一个输入函数
int main()
{
	int num1 = 1;
	int num2 = 2;              //初始化
	
	//输入两个整数
	scanf("%d %d",&num1,&num2);

	//求和
	int sum = num1 + num2;

	//输出
	printf("%d\n", sum);
	return 0;

}

At this time, the following error will be reported when running:

insert image description here

Solution: Write the following code in the first line of the source file:

#define _CRT_SECURE_NO_WARNINGS

//但是我们也能看到提示说可以用scanf_s这个函数代替,值得说明一下:scanf_s是VS编译器自己提供的函数,而非标准C提供的函数。

5.4, ​​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/available

To put it simply: Where does this variable play a role/use, where is its scope

  • The scope of a local variable is the local scope in which the variable resides
  • The scope of global variables is the entire project

5.4.1. The scope of a local variable is the local scope where the variable is located

Code demo:

#include <stdio.h>
int main()
{
	{
		int a = 10;
		printf("a=%d\n", a);           //这个可以输出
	}
	printf("a=%d\n", a);               //但这个就会报错
	return 0;
}

But what if this is the case?

#include <stdio.h>
int main()
{
	int a = 10;
	{
		
		printf("a=%d\n", a);
	}
	printf("a=%d\n", a);
	return 0;
}


输出:
    a=10
    a=10
//此时a变量的作用域是整个的第一个大括号,所以都会输出

5.4.2. The scope of global variables is the entire project

Code demo:

#include <stdio.h>
int a = 10;
int main()
{
	{
		printf("a=%d\n", a);
	}
	printf("a=%d\n", a);
	return 0;
}

输出:
    a=10
    a=10

5.4.2.1: Added: Declaring symbols from outside

extern int a;      //声明变量
extern int Add(int x,int y);         //声明函数

__Life cycle:__The life cycle of a variable refers to a period of time between the creation of the variable and the destruction of the variable.

1. The life cycle of local variables is: the life cycle starts after entering the scope, and the life cycle ends/destroys when the scope is out.

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

for example:

#include <stdio.h>

void test()
{
	int n = 1;
	n++;
	printf("%d ", n);
}

int main()
{
	int i = 0;
	while (i < 10)
	{
		test();
		i++;
	}
	return 0;
}

输出:
    2 2 2 2 2 2 2 2 2 2

The key point is to look at the declaration cycle of the a variable in test(). The a variable is created from calling the test function to {, and then it is destroyed at }, so the output is always 22222222... instead of 2, 3, 4, 5, 6...

6. Constants

A constant is an unchangeable/unmodifiable quantity

The definition forms of constants and variables in C language are different.

The constants in C language are divided into the following categories:

  • literal constant
  • constModified constant__variable__
  • Identifier constants defined by #define
  • enumeration constant

6.1. Literal constants

#include <stdio.h>
//1.字面常量
int main()
{ 
	14;          //整形常量
	3.14;       //浮点型常量
	'w';        //字符常量,单个字符用单引号''
	"asdf";     //字符串常量,字符串用双引号""
	return 0;
}

6.2. constModified constant __ variable __

Why is it called a constant variable? First, let's take a look at the regular variables:

int main()
{ 
	int a = 10;
	a = 20;                 //进行变量赋值,变量改变,最终输出20
	printf("%d\n", a);
	return 0;
}

The a variable above can be modified, so what if we can't do it? We just need to constdeclare

int main()
{ 
	const int a = 10;            //
	printf("%d\n", a);
	return 0;
}

Supplement: In C language, a const modified is essentially a variable, but it cannot be modified and has constant attributes.

6.3. Identifier constants defined by define

#define	MAX 100                       //MAX就是个标识,这里定义的值也可以为字符串,浮点型...
#include <stdio.h>
int main()
{
	printf("%d\n", MAX);
	return 0;
}

 输出:
    100

The constants defined by define can be used for direct printing or assignment.

#define	MAX 100
#include <stdio.h>
int main()
{
	printf("%d\n", MAX);
	int a = MAX;
	printf("%d\n", a);
	return 0;
}

输出:
    100
    100

6.4. Enum constants

#include <stdint.h>

enum Color
{
	//下面的三个变量就是枚举常量
	RED,
	GREEN,
	BLUE
};

int main()
{
	enum Color c = RED;
	return 0;
}

7. String

1. First of all, char is a character type, not a string type. So is there a string type in C language? The answer is no!

So how do we represent strings? Use double quotes "" to indicate

"hello bit.\n"

This string of characters enclosed in double quotes is called a string literal (String Literal), or simply a string.

Note: The end of the string is a \0 escape character. \0 is the end mark when calculating the length of the string, and it is not counted as the content of the string.

2. How do we store strings? How do we realize the importance of __\0__?

#include <stdio.h>
int main()
{
	char arr1[] = "abcdef";         //存储字符串的形式
	char arr2[] = { 'a','b','c','d','e','f' };
	printf("%s\n", arr1);
	printf("%s\n", arr2);            //%s是以字符串的形式显示
	return 0;
}

Output result:

insert image description here

Why is there such a phenomenon?

  • First analyze the first one, the arr1 array, \0 is hidden behind the string, so when the program is executed, it ends when it meets \0, so the output is abcdef
  • Then the second arr2 array, there is no \0, so the program will not end after 'f', until when \0 is encountered, the program will stop. Hence the output of the above.

So what if we output the arr2 array normally? We can manually add a \0

char arr2[] = { 'a','b','c','d','e','f',"\0"};

!!!The importance of \0 in the visible string

What if this is the case?

#include <stdio.h>
#include <string.h>
int main()
{
	char arr[3] = { 'b','i','t' };
	printf("%d\n", strlen(arr));
	return 0;

output:

insert image description here

why? Obviously I declared arr[3], the arr array has three elements, but why is the length of the string still a random value? Because we assign and initialize only three elements, and I just declared three spaces, so there is no \0 after 't', so it will be retrieved until the following \0 will be output.

Then write it another way:

char arr[4] = { 'b','i','t' };     //上述代码就改变这一行,arr[3]--->arr[4]

Output: 3

Reason: We have declared to allocate 4 storage spaces, and there are only 3 elements to be stored later, so the fourth space is directly 0 value, which is equivalent to the function of \0, so stop here, the length of the string is 3 .

3. Below we give an example to illustrate the importance of \0

Here we use a library function: strlen - used to output the length of the string, this requires a header file: #include <string.h>

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[] = "abcdef";
	char arr2[] = { 'a','b','c','d','e','f'};
	printf("%d\n", strlen(arr1));
	printf("%d\n", strlen(arr2));
	return 0;
}

Output result:
insert image description here

In the same way, arr1 stops after encountering \0 behind f, and \0 is not counted as the string content, so the output string length is 6

And arr2 does not have \0 behind f, so it will not stop, and continue to traverse backwards until it encounters \0, so your output is not 6 but 33

Then if we want arr2 to output the string length normally, we only need to manually add \0

char arr2[] = { 'a','b','c','d','e','f','\0'};

8. Escape characters

Common escape characters, all escape characters below are one character, note: it is one character

escape character paraphrase
? Used when writing multiple question marks in a row, preventing them from being parsed into three-letter words
\’ Used to represent character constants'
\" Used to denote double quotes inside a string
\\ Used to represent a backslash. prevents it from being interpreted as an escape sequence
\a warning character, beep
\b backspace
\f Feed character
\n new line
\r carriage return
\t horizontal tab
\v vertical tab
\ddd ddd represents 1-3 octal numbers, such as: \130 Output: X
\xdd dd represents two hexadecimal numbers, such as: \x30 output: 0

The following two escape character code demonstrations:

#include <stdio.h>
int main()
{
	printf("%c\n", '\130');   //特别强调,'\130'不是4个字符,而是一个字符
	printf("%c\n", '\x62');   //同理,'\x62'不是4个字符,而是一个字符
	return 0;
}

output:

insert image description here

8.1. A question about escape characters

Count the length of the following strings

#include <stdio.h>
#include <string.h>
int main()
{
	printf("%d\n", strlen("c:\test\628\test.c"));
	return 0;
}

Answer: 14

Analysis: \t counts as one character, \62 counts as one character, so there are 14 characters in total

So why does \62 count as a character? We said that \ddd needs three numbers? Why doesn't the "8" in the back count?

Because \ddd represents an octal number, and the octal number is from 0 to 7, which does not contain 8, so only \62 is considered an escape character.

9. Notes

10. Select statement and loop statement

1. Select statement

if (aa == 1)
{
	printf("ok,去玩");
}
else
{
	printf("废了");
}

2. Loop statement

How to implement loop in C language?

  • while statement
  • for statement
  • do...while statement
while ()
{
    
}

11. Function

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int Add(int x, int y)
{
	int z = 0;
	z = x + y;
	return z;
}

int main()
{
	int n1 = 0;
	int n2 = 0;
	//输入
	scanf("%d %d", &n1, &n2);
	//求和
	int sum = Add(n1,n2);
	//输出
	printf("%d\n",sum);
	return 0;
}

insert image description here

12. Array

Question: How to store numbers from 0 to 9?

The definition of an array in C language: a set of elements of the same type

#include <stdio.h>
int main()
{
	int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
    printf("%d\n", arr[3]);       //遍历数组
	return 0;
}

arr[10], this 10, means that I want to store 10 elements of int type, of course, it is okay not to write 10, the program will allocate it by itself

And these elements are ordered in memory, starting from 0...

These serial numbers are called the subscripts of the array, and the subscripts start from 0.

Iterate over all elements:

#include <stdio.h>
int main()
{
	int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
	int i = 0;
	while (i < 10)
	{
		printf("%d\n", arr[i]);
		i++;
	}
	return 0;
}

What if this is the case?

int arr[10] = { 0 };

Then these 10 spaces store all 0

insert image description here

13. Operator

13.1. Arithmetic operators

+    -    *    /(得整数部分)    %(取模,得余数)

//  7 / 2    ----->3
//  7 % 2    ----->1
    
//那如果想要打印出小数呢?只需要两端有一个浮点数就会执行浮点数得出发
#include <stdio.h>
int main()
{
	float a = 7 / 2.0;
	printf("%.1f\n",a);          //.1就是保留小数点后一位
	return 0;
}

13.2. Shift operators

>>   <<

13.3. Bitwise operators

&   ^   |

13.4. Assignment operator

=   +=   -=   *=   /=   &=   ^=   |=   >>=   <<=
  • a = a+3 a += 3 has the same effect, and the rest are based on this principle

13.5. Unary operators

!                     逻辑反操作
-                     负值
+                     正值
&                     取地址
sizeof                操作数的类型长度(以字节为单位)
~                     对一个数的二进制按位取反
--                    前置、后置--
*                     间接访问操作符(解引用操作符)
++                    前置、后置++
(类型)                 强制类型转换

In C language 0 means false, non-zero means true

13.5.1,! introduction

#include <stdio.h>
int main()
{
	int flag = 0;           //flag初始化为0,所以flag此时为假
	if (!flag)              //那既然flag为假,那么!flag就为真
		printf("现在为真");
	return 0;
}

13.5.2 Introduction to the use of sizeof

#include <stdio.h>
int main()
{
	int a = 10;
	printf("%d\n", sizeof(a));        //4
	printf("%d\n", sizeof(int));      //4
	printf("%d\n", sizeof a);         //因为size是个操作符,所以不带()也可以使用   输出:4

	return 0;
}

Of course, sizeof can also count the type size of the array

#include <stdio.h>
int main()
{
	int arr[10] = {0};
	printf("%d\n", sizeof(arr));            //40
	printf("%d\n", sizeof(arr[0]));        //4,
	printf("%d\n", sizeof(arr) / sizeof(arr[0]));       //计算数组中元素的个数的方法
	return 0;
}

13.5.3 Use of –, ++

Here only one ++ is enough, the use of – is the same

1. Let’s talk about post ++ first, eg: a++, post ++ follows a principle: use first, then ++

#include <stdio.h>
int main()
{
	int a = 10;
	int b = a++;           //先使用,后++,也就是先 int b = a,然后在a = a+1
	printf("%d\n", b);
	printf("%d\n", a);
	return 0;
}

输出:
    10
    11

2. Front ++, eg: ++a. Pre-++ follows a principle: first ++, then use

#include <stdio.h>
int main()
{
	int a = 10;
	int b = ++a;           //先++,后使用,也就是先 a = a+1,然后在int b = a
	printf("%d\n", b);
	printf("%d\n", a);
	return 0;
}

输出:
    11
    11

13.5.4. Mandatory type conversion

#include <stdio.h>
int main()
{
	int a = (int)3.14;
	printf("%d\n", a);
	return 0;
}

输出:
    3

13.6. Relational operators

>
>=
<
<=
!=          //用于测试不相等
==          //用于测试相等

13.7. Logical operators

&&       逻辑与/并且
||       逻辑或/或者

13.8. Conditional Operators

exp1?exp2:exp3
    
exp1 ? exp2 : exp3
 真     算     不算      那么整个表达式的结果就是exp2表达式的结果
 假    不算     算       那么整个表达式的结果就是exp3表达式的结果

Code example:

#include <stdio.h>
int main()
{
	int a = 10;
	int b = 20;
	int r = a > b ? a : b;      //比较最大值
	printf("%d\n", r);
	return 0;
}

输出:
    20

insert image description here

Analysis: If a>b(exp1) is established, then a(exp2) is correct, then b(exp3) is wrong, so the result of the whole expression is the result of exp2, because a=10, so the result of the whole expression The result is 10, so store r=10

But here obviously b(exp3) is correct, and because b=20, so r=20 for storage, so the maximum output value is 20.

13.9. Comma expressions

exp1,exp2,exp3,...expN

A comma expression is a string of expressions separated by commas.

The characteristics of a comma expression are: it is calculated sequentially from left to right, and the result of the entire expression is the result of the last expression.

#include <stdio.h>
int main()
{
	int a = 10;
	int b = 20;
	int c = 0;
	int d =(c = a - 2, a = b + c, c - 3);    //最后一个表达式c-3=5,所以最终输出结果5
	printf("%d\n", d);
	return 0;
}

输出:
    5

13.10. Subscript references, function calls, and structure members

[]   ()   .   ->

13.10.1. Subscript references

printf("%d\n", arr[0]);

13.10.2. Function call

Add()
    

14. Introduction to common keywords

auto  break  case  char  const  continue  default  do  double  else  enum  extern  float  for  goto  if   int  register  return  short  signed  sizeof  static  struct  switch  typedef  union  unsigned  void  volatile  while

The keyword is built into the C language

15. Keywords typedef and static

15.2. Keyword typedef

typedef, as the name implies, is a type definition, which should be understood as type renaming

typedef can only rename types

for example:

#include <stdio.h>
//将unsigned int 重命名为unit,所以unit也是一个类型名
typedef unsigned int unit;
int main()
{
	//观察num1和num2,这两个变量的类型是一样的
	unsigned int num1 = 0;
	unit num2 = 0;
	return 0;
}

15.3. Keyword static

In C language:

static is used to modify variables and functions

  • Modified local variables—called static local variables
  • Modified global variables—called static global variables
  • Decorative functions—called static functions

15.3.1, static modified local variables

Let's take a look at the piece of code:

#include <stdio.h>

test()
{
	int n = 1;
	n++;
	printf("%d ", n);
}

int main()
{
	int i = 0;
	while (i < 10)
	{
		test();
		i++;
	}
	return 0;
}

output:

insert image description here

__Analysis:__Remember the life cycle of variables mentioned above. The life cycle of variables is created from entering the scope to being destroyed out of the scope.

When the test function is called for the first time, the variable n is created from {, to }, and then destroyed, and then n++ in the middle, so n=2 is finally printed. At this time, the test function is called, and there is no such thing as the n variable at this time . , because it has been destroyed , then call the test function for the second time, then create n variable from scratch and assign n=1, then print n=2, and then destroy n variable, so the final print effect: 2 2 2 2 2 2 2 2 twenty two

Then ok, let's enter the whole, we use the static keyword to modify the local variables to see what effect:

#include <stdio.h>

test()
{
	static int n = 1;                //这里使用static关键词修饰局部变量n变量
	n++;
	printf("%d ", n);
}

int main()
{
	int i = 0;
	while (i < 10)
	{
		test();
		i++;
	}
	return 0;
}

output:

insert image description here

? ? ? Why is the printing effect different?

Analysis of the cause: Also call the test function for the first time, create n variable and assign n=1, then n++, and then print n=2, here comes the important point: since the n variable is modified with the static keyword, then even if the n variable is displayed at this time After entering this scope, the n variable will still not be destroyed. This is the function of the static keyword. At this time, n=2 is stored , and then the test function is called for the second time. At this time, "static int n = 1;" One sentence is equivalent to not working, because when n=2, then n++, so n=3, after the test function is finally released, the n variable will still not be destroyed, and n=3 will be saved. The loop continues like this, so the output is as above.

Summary: When static modifies a local variable, the local variable is out of scope, and the local variable will not be destroyed.

Essentially, when static modifies a local variable, it changes the storage location of the variable.

In a detailed dissection it is:

A large memory is stored in sub-areas, divided into: stack area, heap area, and static area

insert image description here

After the variable is modified by static, the variable is moved from the stack area to the static area, but the n in the code here is directly in the static area, there is no conversion, here is just a special explanation, so when static modifies the local variable, the variable is changed storage location.

15.3.2, static modified global variables

Let's look at the code first:

insert image description here

Analysis: We put the g_val variable in one source file, and then call and print the g_val variable in another source file (the two source files are in the same project). At this time, we only need to use the keyword extern to declare it.

Then we use the static keyword to modify g_val. At this time, even if the keyword extern is used to declare the g_val variable in another source file, g_val still cannot be used:

[External link image transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the image and upload it directly (img-gUmQ2Abk-1685426179194) (C:\Users\Zheng Bo\AppData\Roaming\Typora\typora-user-images \1684597115195.png)]

Summary: Global variables have external link attributes, and once the global variable is modified by static, the external link attributes of this global variable become internal link attributes, and other source files can no longer use this global variable. The scope of the variable changes from the entire project to the current file, and at this time the static global variable is stored in the static area.

15.3.3, static modifier function

Let's look at a piece of code first: to realize the addition of two numbers

#include <stdio.h>

int Add(int x,int y)
{
	return x + y;
}

int main()
{
	int a = 10;
	int b = 20;
	int c = Add(a, b);
	printf("%d\n", c);
	return 0;
}

输出:
    30

The above code uses an Add function to add two numbers. We can put the Add function in the test01.c file, then put the main function in the test02.c file, and then call the Add function. Similarly, we also use the extern keyword to declare the Add function (actually, it’s okay if you don’t declare it, but there are warnings)

insert image description here

Then we use the static keyword to modify the Add function. At this time, even if the Add function variable is declared with the keyword extern in another source file, the Add function still cannot be called:

insert image description here

Summary: A function originally has an external link attribute, but once it is statically modified, the external link attribute of this function becomes an internal link attribute, and other source files cannot use this function.

15.4. [Popularity] keyword register—register

insert image description here

Since the CPU processes data so fast that the memory cannot keep up with the speed of the CPU, when processing data, the data in the memory is stored in the upper level, so it is placed in the cache and register.

Then enter the whole, we can also write register variables when writing code:

#include <stdio.h>
int main()
{
	//寄存器变量
	register int num = 3;     //建议把‘3’存放在寄存器里面
	return 0;
}

When the '3' data is stored in the register, it will be faster to read this data, but it should be noted that it is only recommended to store it here, and the compiler has the final say whether to store it in the register or not.

16. define defines constants and macros

16.1. #define defines constants

This knowledge point is what the constants mentioned above involve.

#define	MAX 100                       //MAX就是个标识,这里定义的值也可以为字符串,浮点型...
#include <stdio.h>
int main()
{
	printf("%d\n", MAX);
	return 0;
}

 输出:
    100

16.2, #define definition macro

macros have parameters

Above we used the Add function to achieve the sum of two numbers, here we use a macro instead of the Add function to achieve this function

#include <stdio.h>

//定义宏
#define Add(x,y) ((x)+(y));

int main()
{
	int a = 10;
	int b = 20;
	int c = Add(a, b);
	printf("%d\n", c);
	return 0;
}

insert image description here

17. Pointer

17.1. Memory

Memory is a particularly important memory on the computer, and the running of programs in the computer is carried out in the memory.

Therefore, in order to effectively use the memory, the memory is divided into small memory units, and the size of each memory unit is __1 bytes. __

In order to be able to effectively access each unit of the memory, the memory units are numbered, and these numbers are called the address of the __memory unit__

insert image description here

Ok, now there is a problem: if there is an integer variable whose data is "10", (int a = 10), then the int data type needs to occupy 4 bytes, then it needs to apply for 4 storage units from the memory, then the variable What is the memory address of a? As shown below:

insert image description here

For example, the allocated memory address is shown in the figure below: the allocated 4 memory spaces are: 5, 6, 7, 8
insert image description here

Then the memory address of variable a at this time is the fifth address (first address)

17.2. How to print variable memory address, how to store memory address?

1. Print memory address

&a //take address operator

#include <stdio.h>
int main()
{
	int a = 10;
	printf("%p\n", &a);           //打印内存地址
	return 0;
}

2. Storage memory address:

#include <stdio.h>
int main()
{
	int a = 10;
	int* p = &a;            //存储变量a的内存地址
	return 0;
}

17.3. Pointer variables

Here comes the point:

int* p = &a;       这个变量p就是指针变量

Why is the variable p called a pointer variable?

In fact, it is very simple. We all know that each memory unit has a number, which is also called an address, and the address is also called a pointer.

insert image description here

If the data type of variable a is character type, you need to write like this:

#include <stdio.h>
int main()
{
	char a = 10;
	char* p = &a;            //存储变量a的内存地址
	return 0;
}

17.4 The meaning and function of *p

look at a piece of code

#include <stdio.h>
int main()
{
	int a = 10;
	int* p = &a;            
	*p = 20;          //解引用操作符,意思就是通过p中存放的地址,找到p所指向的对象,*p就是p指向的对象
	printf("%d\n", a);
	return 0;
}

输出:
    20

*p = 20 feels like reassigning a = 20. (Personal analysis: there is a difference between *p and direct assignment. *p is to find the memory address for assignment. The address of the variable a in this operation has not changed, but the memory address of the reassigned variable a should have changed.)

17.5. The size of pointer variables

#include <stdio.h>
int main()
{
	printf("%zu\n", sizeof(char*));
	printf("%zu\n", sizeof(int*));
	printf("%zu\n", sizeof(short*));
	printf("%zu\n", sizeof(float*));
	printf("%zu\n", sizeof(double*));
	return 0;
}

//64bit位的电脑上
输出:
    8
    8
    8
    8
    8
    
    
//32bit位的电脑上
    4
    4
    4
    4
    4

Cause Analysis: No matter what type of pointer is, it is creating a pointer variable. Pointer variables are used to store addresses. The size of a pointer variable depends on how much space an address needs to store, and the address under the 32-bit platform is 32 bits—that is, 4 bytes, so the size of the pointer variable is 4 bytes, while the address under the 64-bit platform is 64 bit-that is, 8byte, so the size of the pointer variable is 8 bytes.

18. Structure

The structure is a particularly important knowledge point in the C language, and the structure makes the C language capable of description 复杂类型.

For example, to describe a student, the student contains: 名字+年龄+性别+学号these pieces of information. Because students need to contain these pieces of information at the same time, they are complex objects, so they cannot be represented by a single data type such as char, short, int, long, etc. Therefore, in order to solve the corresponding problems, the C language gives the ability to define types as structures.

Structs are groups of single types together.

Then only the structure can be used here to describe:

struct Stu
{
    //以下都是结构体成员
	char name [20];
	int age;
	char sex[5];
	char id[15];
};

18.1. Create a variable with a structure type and print the information

We know that creating a variable is very simple, both are data type + variable name, such as:

int a 
char t
float dd

Then the above struct Stustructure is also a type, and then it can also create variables: struct Stu S, this Sis a variable,

It can be found struct Stu{...}that the effect is the same as that of int, but intit only solves the problem of a single variable and struct Stusolves the problem of complex variables, so it does not take up space, and only when an action struct Stu{...}occurs , the created variable takes up a little space.intstruct Stu SS

So how to use variables?

#include <stdio.h>

struct Stu
{
	char name [20];
	int age;
	char sex[5];
	char id[15];
};

int main()
{
	struct Stu S = 
	{
		"zhangsan",17,"nan","123456789"
	};
    printf("%s %d %s %s\n",S.name,S.age,S.sex,S.id);  //打印的顺序需要相互对应
	return 0;
}

18.2. To upgrade the difficulty, ask: Can the pointer area be used to achieve the effect of printing information?

code show as below:

#include <stdio.h>

struct Stu
{
	char name [20];
	int age;
	char sex[5];
	char id[15];
};

void print(struct Stu* ps)
{
	printf("%s %d %s %d\n", (*ps).name, (*ps).age, (*ps).sex, (*ps->id));
    printf("%s %d %s %d\n", ps->name, ps->age, ps->sex, ps->id);
    //效果一样,形式:结构体对象.结构体成员变量

}

int main()
{
	struct Stu S = 
	{
		"zhangsan",17,"nan","123456789"
	};
	print(&S);
	return 0;
}

Just like the section on pointer variables mentioned earlier, the reason is the same.

Guess you like

Origin blog.csdn.net/m0_57776598/article/details/130946922