当前位置:网站首页>Part II - C language improvement_ 3. Pointer reinforcement
Part II - C language improvement_ 3. Pointer reinforcement
2022-07-24 07:09:00 【qq_ forty-three million two hundred and five thousand two hundr】
3.1 A pointer is a data type
3.1.1 Pointer to the variable
A pointer is a data type , Take up memory space , Used to store memory addresses .
void test01()
{
int* p1 = 0x1234;
int*** p2 = 0x1111;
printf("p1 size:%d\n",sizeof(p1));
printf("p2 size:%d\n",sizeof(p2));
// The pointer is a variable , The pointer itself also takes up memory space , Pointers can also be assigned
int a = 10;
p1 = &a;
printf("p1 address:%p\n", &p1);
printf("p1 address:%p\n", p1);
printf("a address:%p\n", &a);
}Output results
p1 size:4
p2 size:4
p1 address:003DFC50
p1 address:003DFC38
a address:003DFC383.1.2 Wild pointer and null pointer
3.1.2.1 Null pointer
The standard defines NULL The pointer , As a special pointer variable , It doesn't point to anything . To make a pointer NULL, You can assign it a zero value .
If you have a NULL What happens to pointer indirect access ? The results vary from compiler to compiler .
It is not allowed to report to NULL And illegal address copy memory :
void test()
{
char *p = NULL;
// to p Copy the contents of the memory area pointed to
strcpy(p, "1111"); //err
char *q = 0x1122;
// to q Copy the contents of the memory area pointed to
strcpy(q, "2222"); //err
}4.1.2.2 Wild pointer
When using pointers , To avoid wild pointers :
The wild pointer points to a deleted object or an object that has not requested access to a restricted memory area The pointer .
Under what circumstances will cause the wild pointer ?
1. Pointer variable not initialized Any pointer variable that is just created does not automatically become NULL The pointer , Its default value is random , It's going to point at all . therefore , Pointer variables should be initialized at the same time as they are created , Or set the pointer to NULL, Or let it point to legitimate memory . 2. The pointer is not set to null after being released Sometimes the pointer is free or delete No assignment after NULL, It will make people think it is legal . Do not look free and delete Name ( In especial delete), They just free the memory that the pointer points to , But it didn't kill the pointer itself . Now the pointer is pointing to “ The garbage ” Memory . The released pointer should immediately set the pointer to NULL, Prevent generation “ Wild pointer ”. 3. Pointer operation goes beyond variable scope Do not return pointers or references to stack memory , Because there are functions in the stack that will be released at the end . |
The operation field pointer is a very dangerous operation , The appearance of wild pointers should be avoided :
1. Set when initializing NULL Pointer variables must be initialized to NULL, Because when any pointer variable is first created, it will not automatically become NULL The pointer , Its default value is random . 2. Set when releasing NULL When the pointer p When the memory space pointed to is released , No pointer set p The value of is NULL.delete and free Just free up memory space , But the pointer is not p The value of is assigned to NULL. Usually judge whether a pointer is legal , Is to use if Statement to test whether the pointer is NULL. |
3.1.3 Indirect access operators
The process of accessing the address it points to through a pointer is called indirect access , Or dereference pointer , The operator used to perform indirect access is *.
Be careful : To a int* Dereference of type pointer will produce an integer value , Similarly , To a float* Pointer dereference produces a float Type value .
// Quoting
void test01()
{
int* p = NULL; // Define pointer
int a = 10;
p = &a; // Who does the pointer point to , Just assign whose address to the pointer
*p = 20;
int b = *p;
char* str = "hello world!"; // You must ensure that the memory is writable
//*str = 'm'; // error , String constants cannot be changed
printf("a:%d\n", a);
printf("*p:%d\n", *p);
printf("b:%d\n", b);
}3.1.4 The step size of the pointer
A pointer is a data type , Refers to the data type of the memory space it points to . The memory space pointed to by the pointer determines the step size of the pointer . The step size of the pointer refers to , When the pointer +1 When , How many bytes are moved .
Think about the following :
int a = 0xaabbccdd;
unsigned int *p1 = &a;
unsigned char *p2 = &a;
// Why? *p1 Print out the correct results ?
printf("%x\n", *p1);
// Why? *p2 Did not print out the correct results ?
printf("%x\n", *p2);
// Why? p1 The pointer +1 added 4 byte ?
printf("p1 =%d\n", p1);
printf("p1+1=%d\n", p1 + 1);
// Why? p2 The pointer +1 added 1 byte ?
printf("p2 =%d\n", p2);
printf("p2+1=%d\n", p2 + 1);Output results
aabbccdd
dd
p1 =6028576
p1+1=6028580
p2 =6028576
p2+1=60285773.2 The meaning of the pointer _ Indirect assignment
3.2.1 Three conditions for indirect assignment
Three conditions for indirect assignment through pointer :
1. 2 A variable ( A normal variable, a pointer variable 、 Or an argument, a formal parameter )
2. To build a relationship
3. adopt * The memory pointed to by the operation pointer
void test()
{
int a = 100; // Two variables
int *p = NULL;
p = &a; // To build a relationship
*p = 22; // adopt * Operating memory
}3.2.2 Multi level pointer
void test()
{
int b;
int *q = &b;
int **t = &q;
int ***m = &t;
}3.2.3 Indirect assignment : from 0 Level pointer to 1 Level pointer
int func1()
{
return 10;
}
void func2(int a)
{
a = 100;
}
void test02()
{
int a = 0;
a = func1();
printf("a = %d\n", a);
func2(a);
printf("a = %d\n", a); // Why not modify ?
}
// Indirect assignment of pointers
void func3(int* a)
{
*a = 100;
}
void test03()
{
int a = 0;
func3(&a);
printf("a = %d\n", a); // Modification successful
}3.2.4 Indirect assignment : from 1 Level pointer to 2 Level pointer
void AllocateSpace(char** p)
{
*p = (char*)malloc(100);
strcpy(*p, "hello world!");
}
void FreeSpace(char** p)
{
if (p == NULL)
{
return;
}
if (*p != NULL)
{
free(*p);
*p = NULL;
}
}
void test()
{
char* p = NULL;
AllocateSpace(&p);
printf("%s\n",p);
FreeSpace(&p);
if (p == NULL)
{
printf("p Memory free !\n");
}
}Output results
hello world!
p Memory free !3.3 Pointer as function parameter
Pointer as function parameter , Have Input and Output characteristic :
- Input : The calling function allocates memory
- Output : The called function allocates memory
3.3.1 Input features
void fun(char *p)
{
strcpy(p, "abcddsgsd"); // to p Copy the contents of the memory area pointed to
}
void test()
{
char buf[100] = { 0 }; // Input , The calling function allocates memory
fun(buf);
printf("buf = %s\n", buf);
}Output results
buf = abcddsgsd3.3.2 output characteristic
void fun(char **p , int *len)
{
char *tmp = (char *)malloc(100);
if (tmp == NULL)
{
return;
}
strcpy(tmp, "adlsgjldsk");
// Indirect assignment
*p = tmp;
*len = strlen(tmp);
}
void test()
{
char *p = NULL; // Output , The called function allocates memory , Address delivery
int len = 0;
fun(&p, &len);
if (p != NULL)
{
printf("p = %s, len = %d\n", p, len);
}
}Output results
p = adlsgjldsk, len = 103.4 String pointer
3.4.1 String pointer as function parameter
3.4.1.1 String basic operation
// String basic operation
// String is based on 0 perhaps '\0' Array of characters at the end ,( Numbers 0 And character '\0' Equivalent )
void test01()
{
// Character arrays can only be initialized 5 Characters , When output , From the beginning until you find 0 end
char str1[] = { 'h', 'e', 'l', 'l', 'o' };
printf("%s\n",str1);
// Character array part initialization , Residual filling 0
char str2[100] = { 'h', 'e', 'l', 'l', 'o' };
printf("%s\n", str2);
// If initialized as a string , Then the compiler will add... At the end of the string by default '\0'
char str3[] = "hello";
printf("%s\n",str3);
printf("sizeof str:%d\n",sizeof(str3));
printf("strlen str:%d\n",strlen(str3));
//sizeof Calculate array size , The array contains '\0' character
//strlen Calculate the length of the string , To '\0' end
// So if I write , What's the result ?
char str4[100] = "hello";
printf("sizeof str:%d\n", sizeof(str4));
printf("strlen str:%d\n", strlen(str4));
// What is the input result below ?sizeof What's the result ?strlen What's the result ?
char str5[] = "hello\0world";
printf("%s\n",str5);
printf("sizeof str5:%d\n",sizeof(str5));
printf("strlen str5:%d\n",strlen(str5));
// Again, what is the input result below ?sizeof What's the result ?strlen What's the result ?
char str6[] = "hello\012world";
printf("%s\n", str6);
printf("sizeof str6:%d\n", sizeof(str6));
printf("strlen str6:%d\n", strlen(str6));
}Output results
hello Hot hot hot Salty period
hello
hello
sizeof str:6
strlen str:5
sizeof str:100
strlen str:5
hello
sizeof str5:12
strlen str5:5
hello ‘/012’ Newline character
world
sizeof str6:12
strlen str6:11Octal and hexadecimal escape characters :
stay C There are two special characters in , Octal escape character and hexadecimal escape character , The general form of octal characters is '\ddd',d yes 0-7 The number of . The general form of hexadecimal characters is '\xhh',h yes 0-9 or A-F One in . Octal characters and hexadecimal characters represent characters ASCII The value corresponding to the code . such as :
|
3.4.1.2 String copy function implementation
// Copy method 1
void copy_string01(char* dest, char* source )
{
for (int i = 0; source[i] != '\0';i++)
{
dest[i] = source[i];
}
}
// Copy method 2
void copy_string02(char* dest, char* source)
{
while (*source != '\0')
{
*dest = *source;
source++;
dest++;
}
}
// Copy method 3
void copy_string03(char* dest, char* source)
{
// Judge *dest Is it 0,0 Then exit the loop
while (*dest++ = *source++){}
}3.4.1.3 String inversion model

void reverse_string(char* str)
{
if (str == NULL)
{
return;
}
int begin = 0;
int end = strlen(str) - 1;
while (begin < end)
{
// Swap two character elements
char temp = str[begin];
str[begin] = str[end];
str[end] = temp;
begin++;
end--;
}
}
void test()
{
char str[] = "abcdefghijklmn";
printf("str:%s\n", str);
reverse_string(str);
printf("str:%s\n", str);
}Output results
str:abcdefghijklmn
str:nmlkjihgfedcba3.4.2 Formatting of strings
3.4.2.1 sprintf
#include <stdio.h>
int sprintf(char *str, const char *format, ...);
function : According to the parameters format String to convert and format data , Then output the result to str In the specified space , straight To the end of the string '\0' until .
Parameters :
str: String first address
format: String format , Usage and printf() equally
Return value :
success : The number of characters actually formatted
Failure : - 1
void test()
{
//1. Formatted string
char buf[1024] = { 0 };
sprintf(buf, " Hello ,%s, Welcome to join us !", "John");
printf("buf:%s\n",buf);
memset(buf, 0, 1024);
sprintf(buf, " I this year %d Year old !", 20);
printf("buf:%s\n", buf);
//2. String concatenation
memset(buf, 0, 1024);
char str1[] = "hello";
char str2[] = "world";
int len = sprintf(buf,"%s %s",str1,str2);
printf("buf:%s len:%d\n", buf,len);
//3. Number to string
memset(buf, 0, 1024);
int num = 100;
sprintf(buf, "%d", num);
printf("buf:%s\n", buf);
// Set width Right alignment
memset(buf, 0, 1024);
sprintf(buf, "%8d", num);
printf("buf:%s\n", buf);
// Set width Align left
memset(buf, 0, 1024);
sprintf(buf, "%-8d", num);
printf("buf:%s\n", buf);
}Output results
buf: Hello ,John, Welcome to join us !
buf: I this year 20 Year old !
buf:hello world len:11
buf:100
buf: 100
buf:1003.4.2.2 sscanf
#include <stdio.h>
int sscanf(const char *str, const char *format, ...);
function : from str The specified string reads the data , And according to the parameters format String to convert and format data .
Parameters :
str: The first address of the specified string
format: String format , Usage and scanf() equally
Return value :
success : If successful, return the number of parameters , Failure returns -1
Failure : - 1
Format | effect |
%*s or %*d | Skip data |
%[width]s | Read data of specified width |
%[a-z] | matching a To z Any character in ( As many matches as possible ) |
%[aBc] | matching a、B、c One of them , Greed |
%[^a] | Match not a Any character of , Greed |
%[^a-z] | It means read except a-z All characters except |
//1. Skip data
void test01()
{
char buf[1024] = { 0 };
// Skip the previous number
// Match whether the first character is a number , If it is , Then skip
// If not, stop matching
sscanf("123456aaaa", "%*d%s", buf);
printf("buf:%s\n",buf);
}
//2. Read the specified width data
void test02()
{
char buf[1024] = { 0 };
// Skip the previous number
sscanf("123456aaaa", "%7s", buf);
printf("buf:%s\n", buf);
}
//3. matching a-z Any character in
void test03()
{
char buf[1024] = { 0 };
// Skip the previous number
// Match the first character first , Determine whether the character is a-z The characters in , If it's a match
// If not stop matching
sscanf("abcdefg123456", "%[a-z]", buf);
printf("buf:%s\n", buf);
}
//4. matching aBc Any one of them
void test04()
{
char buf[1024] = { 0 };
// Skip the previous number
// First match whether the first character is aBc One of them , If it is , The match , If not, stop matching
sscanf("abcdefg123456", "%[aBc]", buf);
printf("buf:%s\n", buf);
}
//5. Match not a Any character of
void test05()
{
char buf[1024] = { 0 };
// Skip the previous number
// First match whether the first character is aBc One of them , If it is , The match , If not, stop matching
sscanf("bcdefag123456", "%[^a]", buf);
printf("buf:%s\n", buf);
}
//6. Match not a-z Any character in
void test06()
{
char buf[1024] = { 0 };
// Skip the previous number
// First match whether the first character is aBc One of them , If it is , The match , If not, stop matching
sscanf("123456ABCDbcdefag", "%[^a-z]", buf);
printf("buf:%s\n", buf);
}Output results
buf:aaaa
buf:123456a
buf:abcdefg
buf:a
buf:bcdef
buf:123456ABCD3.5 Error prone point of primary pointer
3.5.1 Transboundary
void test()
{
char buf[3] = "abc"; // Run out of three bytes , Can't put it down ‘\0’
printf("buf:%s\n",buf);
}Output results
buf:abc Scald it BRZ3.5.2 Pointer self increment will affect the free space
void test()
{
char *p = (char *)malloc(50);
char buf[] = "abcdef";
int n = strlen(buf);
int i = 0;
for (i = 0; i < n; i++)
{
*p = buf[i];
p++; // Modify the original pointer to
}
free(p); // Report errors
}3.5.3 Return local variable address
char *get_str()
{
char str[] = "abcdedsgads"; // The stack area ,
return str;
}
int main()
{
printf("[get_str]str = %s\n", get_str()); // Stack space has been freed , Cannot output string
return 0;
}Output results
[get_str]str = To scald or scald 0???3.5.4 The same block of memory is released multiple times ( You cannot release the wild pointer )
void test()
{
char *p = NULL;
p = (char *)malloc(50);
strcpy(p, "abcdef");
if (p != NULL)
{
//free() The function of the function just tells the system p The memory pointed to can be recycled
// That is to say ,p The memory usage right pointed to is returned to the system
// however ,p The value of is still the original value ( Wild pointer ),p Or point to the original memory
free(p);
}
if (p != NULL) // Report errors , Because of the second release
{
free(p);
}
}3.6 const Use
//1.const Modifying variables
void test01()
{
const int i = 0;
//i = 100; // error , Read only variables cannot be modified after initialization
const int j; // Definition const Variables are best initialized
//j = 100; // error , Cannot assign again
const int k = 10; //const Is a read-only variable , It's not a constant , Can be modified indirectly through the pointer
//k = 100; // error , It can't be modified directly , But it can be modified indirectly through pointers
int* p = &k;
*p = 100;
printf("k:%d\n", k);
}
//2.const Modify a pointer
void test02()
{
int a = 10;
int b = 20;
const int* p_a = &a;
//*p_a = 100; // The value pointed to by the pointer cannot be modified
p_a = &b; // The pointer can be modified
//const Put it in * The right side of the number , The pointer of the modifier pointer cannot be modified , But you can change the memory space pointed to by the pointer
int* const p_b = &a;
//p_b = &b; // The pointing of the pointer cannot be modified
*p_b = 100; // The value pointed to by the pointer can be modified
// Neither the pointer nor the value pointed to by the pointer can be modified
const int* const p_c = &a;
}
//3.const Modify the structure
struct Person
{
char name[64];
int id;
int age;
int score;
};
// Copy the object every time , Low efficiency , You should use a pointer
/*void printPersonByValue(struct Person person)
{
printf("Name:%s\n", person.name);
printf("Name:%d\n", person.id);
printf("Name:%d\n", person.age);
printf("Name:%d\n", person.score);
}*/
// But using a pointer can have side effects , You may accidentally modify the original data , So add const
void printPersonByPointer(const struct Person *person)
{
printf("Name:%s\n", person->name);
printf("Name:%d\n", person->id);
printf("Name:%d\n", person->age);
printf("Name:%d\n", person->score);
}
void test03()
{
struct Person p = { "Obama", 1101, 23, 87 };
//printPersonByValue(p);
printPersonByPointer(&p);
}边栏推荐
猜你喜欢

Redis persistence

Sealos packages and deploys kubesphere container platform

SPI——发送16位和8位数据

Can recursion still play like this? Recursive implementation of minesweeping game
![(note sorting is not completed) [graph theory: find the shortest path of single source]](/img/58/e61aea3c4d0a33d3615144763160f7.png)
(note sorting is not completed) [graph theory: find the shortest path of single source]

【C语言】操作符详解(深入理解+整理归类)

What kind of mode can make platform users self-help fission- Chain 2+1

第二部分—C语言提高篇_2. 内存分区

"Big factory interview" JVM Chapter 21 questions and answers

Redis sentinel mechanism
随机推荐
xavier_ normal_ Initialization test
Basic syntax of MySQL DDL and DML and DQL
Day (0~6) represents the starting position of the first day of each month, stop represents the number of days of each month, and there are two blank spaces between each day. Input different days and s
[waveform / signal generator] Based on stc1524k32s4 for C on Keil
An AI plays 41 games, and the comprehensive performance score of Google's latest multi game decision transformer is twice that of dqn
第一部分—C语言基础篇_11. 综合项目-贪吃蛇
C language from entry to soil (III)
记账APP:小哈记账2——注册页面的制作
Redis 持久化
Thinking of data analysis -- analyzing the retail industry as a whole -- an all-round and multifaceted detailed analysis
不去和谁比较,只需做好自己
Tensorflow Einstein function
C process running permission
【LeetCode】444. 序列重建
Input some data and find the maximum output. (keyboard and file reading)
Create WPF project
STM32 external interrupt (register version)
Penetration learning - SQL injection - shooting range - installation and bypass experiment of safety dog (it will be updated later)
[USB voltmeter and ammeter] Based on stm32f103c8t6 for Arduino
永远不要迷失自我!