day10 coding: 指针, 函数与指针,动态内存申请
This commit is contained in:
parent
74ddf49c45
commit
07358e7842
|
@ -11,3 +11,5 @@
|
|||
#### day8: 静态库,动态库,指针
|
||||
|
||||
#### day9: 指针高级
|
||||
|
||||
#### day10: 数组指针,函数与指针,动态内存申请
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int arr[3][4] = {1, 2, 3, 4, 5, 6, 7, 8,
|
||||
9, 10, 11, 12};
|
||||
// arr 表示第 0 行的地址, arr[0] 表示第 0 行的地址
|
||||
int *p = arr[0]; // p 表示第 1 行的地址
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
printf("%d ", *(p + i));
|
||||
}
|
||||
printf("\n");
|
||||
p += sizeof(arr[0]) / sizeof(arr[0][0]);
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
#include <stdio.h>
|
||||
|
||||
void show(char *q[], int n)
|
||||
// void show(char **q, int n) // char **q == char *q[]
|
||||
{
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
while (*(*(q + i))) // 当本行字符串没有结束时
|
||||
{
|
||||
printf("%c", *(*(q + i))++); // q[i] == *(q + i)
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// names 内容存在栈区,names[0] 存放的是字符串的首地址
|
||||
// "disen" 是常量,存在常量区,"disen" 的首地址存在栈区
|
||||
// 常量区的内容不能修改
|
||||
char *names[3] = {"disen", "rose", "jack"};
|
||||
show(names, 3);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
// int rands[10]; // 全局变量处理方式
|
||||
|
||||
void *rand_arr(int size, int min, int max)
|
||||
{
|
||||
srand(time(NULL));
|
||||
// 使用 malloc 分配内存,因为函数返回的指针是局部变量,会被释放
|
||||
// 而当使用 malloc 分配内存时,内存会一直存在,直到程序结束
|
||||
// malloc 存放在内存的堆区,而局部变量存放在内存的栈区
|
||||
// 堆区的内存需要手动释放,栈区的内存会自动释放
|
||||
int *rands = (int *)malloc(sizeof(int) * size);
|
||||
// int rands[size]; // 对照上面的处理方式
|
||||
// static int rands[size]; // 静态变量处理方式,但是变长数组不能使用静态变量
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
rands[i] = (rand() % (max - min + 1)) + min;
|
||||
}
|
||||
return rands;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int *nums = (int *)rand_arr(10, 3, 12);
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
printf("%d ", *(nums + i));
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("free nums\n");
|
||||
free(nums);
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
printf("%d ", *(nums + i));
|
||||
}
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int *input_score(int size)
|
||||
{
|
||||
int *arr = (int *)malloc(sizeof(int) * size);
|
||||
memset(arr, 0, sizeof(int) * 5); // 将 scores 指向的内存清零0
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
printf("请输入第 %d 个学生的成绩: ", i + 1);
|
||||
scanf("%d", arr + i);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int *scores = input_score(5);
|
||||
// scores = NULL 的判断是必须的,因为 malloc 分配内存失败时,会返回 NULL
|
||||
if (scores == NULL)
|
||||
{
|
||||
printf("内存分配失败\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
printf("%d ", *(scores + i));
|
||||
}
|
||||
printf("\n");
|
||||
printf("R%p\n", scores);
|
||||
free(scores); // 释放后,打印的前两个值是随机的,因为内存已经被释放了,但是后面的值还在,所以还能打印出来
|
||||
// free(scores); // 重复释放内存,会报错;一个指针只能释放一次内存
|
||||
printf("R%p\n", scores);
|
||||
for (int i = 0; i < 10000000; i++)
|
||||
;
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
// 会报错,因为 scores 指向的内存已经被释放了
|
||||
// free(scores + i); // 释放指针数组中的每一个元素 malloc 分配的内存
|
||||
printf("%d ", *(scores + i));
|
||||
}
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
char *p = "disen";
|
||||
free(p); // 释放常量区的内存,会报错; 因为常量区的内存是只读的
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
// malloc(30) 申请大小为 30 字节的内存空间,返回的是这块内存空间的首地址
|
||||
char *p = (char *)malloc(30);
|
||||
strcpy(p, "hi, disen");
|
||||
printf("%s, p->%p, last p->%p\n", p, p, p + 8);
|
||||
free(p); // free 后,变为野指针,指向的内存空间已经被释放了
|
||||
|
||||
// free 之后,p 指针指向的内存空间已经被释放了,但是 p 指针本身的地址没有变
|
||||
p = (char *)malloc(10);
|
||||
memset(p, 'A', 10);
|
||||
printf("%s, p->%p\n", p, p);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
// malloc(30) 申请大小为 30 字节的内存空间,返回的是这块内存空间的首地址
|
||||
char *p = (char *)malloc(30);
|
||||
strcpy(p, "hi, disen");
|
||||
printf("%s, p->%p, last p->%p\n", p, p, p + 8);
|
||||
free(p); // free 后,变为野指针,指向的内存空间已经被释放了
|
||||
|
||||
// free 之后,p 指针指向的内存空间已经被释放了,但是 p 指针本身的地址没有变
|
||||
p = (char *)ralloc(p, 10);
|
||||
memset(p, 'A', 10);
|
||||
printf("%s, p->%p\n", p, p);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int m[3][5] = {{1, 2, 3, 4, 5},
|
||||
{6, 7, 8, 9, 10},
|
||||
{11, 12, 13, 14, 15}};
|
||||
// 数组指针
|
||||
int(*p)[5] = m; // 5 表示每行有 5 个元素,*p 表示第 0 行的地址
|
||||
int(*p2)[5] = m + 2;
|
||||
|
||||
printf("%p\n", p2);
|
||||
printf("%p\n", p);
|
||||
uintptr_t ret2 = (uintptr_t)p2 - (uintptr_t)p; // uintptr_t 无符号整型 // 除以每个元素的大小
|
||||
|
||||
int ret = p2 - p; // 原理: (m + 2) - m = 2
|
||||
printf("%d\n", ret2); // 2
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
for (int j = 0; j < 5; j++)
|
||||
{
|
||||
printf("第 %d 行第 %d 列的地址: %p\n", i, j, *(p + i) + j);
|
||||
scanf("%d", *(p + i) + j); // *(p + i) + j 表示第 i 行第 j 列的地址
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
for (int j = 0; j < 5; j++)
|
||||
printf("%d ", *(*(p + i) + j));
|
||||
printf("\n");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int a[5];
|
||||
int *p = a;
|
||||
int(*q1)[5] = &a;
|
||||
int **q2 = &p;
|
||||
|
||||
// uintptr_t 是 C 语言标准库<stdint.h> 中定义的一个无符号整数类型,它的大小足够存储指针值。因此, % lu 格式说明符用于打印 uintptr_t 类型的变量。 printf("q1=%p, &q1+1=%p, len = %lu\n", q1, q1 + 1, (uintptr_t)(q1 + 1) - (uintptr_t)q1);
|
||||
printf("q2=%p, &q2+1=%p, len = %lu\n", q2, q2 + 1, (uintptr_t)(q2 + 1) - (uintptr_t)q2);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int a[2][3] = {1, 2, 3, 4, 5, 6};
|
||||
int(*p)[3] = a;
|
||||
int **q = &p;
|
||||
|
||||
int i = 0;
|
||||
// while (i < 2)
|
||||
// {
|
||||
// int j = 0;
|
||||
// while (j < 3)
|
||||
// {
|
||||
// // printf("%d ", *(p[i] + j));
|
||||
// printf("%d ", *(*(p + i) + j));
|
||||
// j++;
|
||||
// }
|
||||
// printf("\n");
|
||||
// i++;
|
||||
// }
|
||||
|
||||
printf("q = %lu\n", q);
|
||||
printf("*q = %lu\n", *q);
|
||||
printf("(*q + 1) = %lu\n", (*q + 1));
|
||||
printf("(*q + 1) - *q = %lu\n", (uintptr_t)(*q + 1) - (uintptr_t)*q);
|
||||
printf("*(*q + 1) = %lu\n", *(*q + 5));
|
||||
printf("--------------------");
|
||||
printf("\n");
|
||||
printf("**q = %lu\n", **q);
|
||||
printf("*(*q + 1) = %lu\n", *(*q + 1));
|
||||
printf("p = %lu\n", p);
|
||||
printf("&p = %lu\n", &p);
|
||||
printf("&p + 1 = %lu\n", &p + 1);
|
||||
|
||||
// while (i < 6)
|
||||
// {
|
||||
// printf("%d ", *(*q + i));
|
||||
|
||||
// i++;
|
||||
// }
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#include <stdio.h>
|
||||
|
||||
void change(int *p)
|
||||
{
|
||||
*p += 10;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int x = 10;
|
||||
change(&x);
|
||||
|
||||
printf("x = %d\n", x);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#include <stdio.h>
|
||||
|
||||
void change(char *p)
|
||||
{
|
||||
printf("change %s, p = %p\n", p, p);
|
||||
p = "jack"; // p 的 char * 指针可以理解为是一个字符串的常量
|
||||
printf("change %s, p = %p\n", p, p);
|
||||
p = "D";
|
||||
printf("change %s, p = %p\n", p, p);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
char *name = "disen";
|
||||
change(&name); // 属于地址传递
|
||||
printf("name = %s, name 地址 = %p\n", name, name);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#include <stdio.h>
|
||||
|
||||
void change(char **p)
|
||||
{
|
||||
printf("change %s, p = %p\n", *p, p);
|
||||
*p = "jack"; // p 的 char * 指针可以理解为是一个字符串的常量
|
||||
printf("change %s, p = %p\n", *p, p);
|
||||
*p = "D";
|
||||
printf("change %s, p = %p\n", *p, p);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
char *name = "disen";
|
||||
change(&name);
|
||||
printf("name = %s, name 地址 = %p\n", name, &name);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int max(int *p, int size)
|
||||
{
|
||||
int m = *p; // 默认为第一个元素是最大
|
||||
for (int i = 1; i < size; i++)
|
||||
{
|
||||
if (m < *(p + i))
|
||||
m = *(p + i);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int a[3] = {1, 5, 2};
|
||||
int m = max(a, 3); // a 表示第一个元素的地址
|
||||
printf("m max %d\n", m);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
#include <stdio.h>
|
||||
|
||||
// 查找数组中的元素并替换为特定值
|
||||
void findReplace(int rows, int cols, int (*p)[cols], int oval, int nval)
|
||||
{
|
||||
for (int i = 0; i < rows; i++)
|
||||
{
|
||||
for (int j = 0; j < cols; j++)
|
||||
{
|
||||
if (*(*(p + i) + j) == oval)
|
||||
*(*(p + i) + j) = nval;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int a[3][3] = {1, 2, 3, 4, 1, 6, 1, 8, 9};
|
||||
int(*q)[3] = a;
|
||||
findReplace(3, 3, q, 1, 9);
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
printf("%d ", a[i][j]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue