目录
交换两个数的值
#include <studio.h>
void swap(int a, int b);
int main (void)
{
int a = 1;
int b = 2;
print("a is %i, and b is %i", (a, b));
swap(a,b)
print("a is %i, and b is %i", (a, b));
}
void swap(int a, int b)
{
int tmp = a;
a = b;
b = tmp;
}
这样交换的只是两个变量的值, 并不是两个变量的地址, 所以最终会有交换失败的bug.
交换变量的地址
原来的交换代码 , 并不能交换变量的地址
void swap(int a, int b)
{
int tmp = a;
a = b;
b = tmp;
}
调整后的代码
void swap(int *a, int *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
当在函数参数前面标记星号, 就相当于告诉计算机, 我不要整型变量, 我要整型变量的地址.
int temp
存放的是a
的值,*
是解引用操作符, 就是说到这个地址, 取这里的值.- 再继续执行, 到
a
这个地址标记的地方, 获取b
表示的地址, 按地址取值, 把值传递到a
表示的地址处 - 最后 , 到
b
表示的内存地址, 把temp
的值放到这里
&
表示传入数据的地址
交换变量的地址最后的代码为
#include <studio.h>
void swap(int a, int b);
int main (void)
{
int a = 1;
int b = 2;
print("a is %i, and b is %i", (a, b));
swap(&a, &b)
print("a is %i, and b is %i", (a, b));
}
void swap(int *a, int *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
内存空间
使用函数 malloc
给变量内存地址. 使用free函数归还使用的内存
堆 : 在内存的顶部, 存放的是代码段.
栈 : 在内存的底部, 当函数被调用的时候, 使用的是栈这部分的存储空间
Valgrind
找到内存泄漏的错误
数组越界
#include <studio.h>
#include <stulib.h>
int main(void)
{
f();
}
void f(void)
{
int *x = malloc(10 * sizeof(int));
x[10] = 50;
print(x[10]);
free(x);
}
其实这里有一个数组越界的错误, 但是程序可能会正常执行, 因为分配内存的时候, 可能会分配一个比你指定大的内存.
使用valgrind找到这个错误
修改这个错误
void f(void)
{
int *x = malloc(10 * sizeof(int));
x[9] = 50;
print(x[9]);
free(x);
}
实际使用的时候, 不需要这样分配内存
void f(void)
{
int x[10];
}
自定义数据类型
语法
typedef struct
{
char *name;
char *dorm;
}
sutdent;
使用自定义数据类型
- 引入
#include "student.h"
student students[enrollment];
: 意思是给我这么多的student结构, 整个数组叫students.
realloc函数
重新分配内存
每次向内存要一个内存空间
但是这样存储值, 会导致这些值不会被存储在一起
可以每次向内存要一个存储整数 加另一个整数的地址大小的空间.
使用
使用代码表示
typedef struct node
{
int n;
struct node *next;
}
node;
- node * 就是指向节点的指针.
- typedef struct node : 当clang编译器读到这一行时, 就会知道node结构是存在的.
- 每一个node都包含两部分, 一个是整数n, 还有一个指针, 指向另一个node型数据结构.
预先不知道用户需要多少内存, 怎么让用户持续输入, 然后输入q结束输入
#include <studio.h>
#include <cs50.h>
int main(void)
{
int *number = NULL
// 预先设定的内存大小
int capacity = 0
int size = 0
while (true)
{
int number = get_int("Number: ");
if (size == capacity)
{
numbers = realloc(numbers, sizeof(int) * (size + 1));
}
}
}
- 直接创建数组, 它表示内存块的第一个字节的地址
- 不管当前数组大小多少, 重新分配数组内存, 并调整到新的大小