朋也的博客 » 首页 » 文章
作者:朋也
日期:2021-10-12
类别:C学习笔记
版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
*
与 &
的区别
*
可被用来声明指针,也可被用来获取指针指向地址的值
#include <stdio.h>
int main() {
int a = 10;
int *b = &a;
printf("a = %d b = %p *b = %d\n", a, b, *b);
return 0;
}
输出
a = 10 b = 000000000065FE14 *b = 10
&
被用来获取内存的地址,比如上面例子中,int *b = &a;
就是将a变量的地址赋值给指针b
结构体
在C中没有对象的概念,但有个结构体,可以被用来封装对象,用法如下
#include <stdio.h>
#include <string.h>
struct user {
char name[5]; // 必须要带上长度
int age;
};
int main() {
struct user user_1 = {"java", 24};
printf("name = %s age = %d\n", user_1.name, user_1.age);
struct user *user_2 = &user_1;
strcpy(user_2->name, "C"); // 给char[]赋新值
user_2->age = 25;
printf("name = %s age = %d\n", user_2->name, user_2->age); // 取指针指向数据的值本来使用的是 (*user_2).name 这里使用 -> 简化了写法
return 0;
}
方法间传值
如果想在调用方法时,还想使用当前作用域的数据且能同步更新的话,就需要传内存地址
如下,如果只传值的话,在方法 swap()中即使调换了数据,回到main里打印也不会生效
#include <stdio.h>
// 在方法swap里定义了两个int变量,这两个int变量的作用域就只在方法 swap()里,在main里调用了这个方法并传入了main中的ab,相当于使用main中的ab变量给swap方法中的ab形参初始化了,所以在swap里将ab调换仅仅修改的是swap方法下的ab,并没有对main中的ab进行值调换
void swap(int a, int b) {
int tmp = a;
a = b;
b = tmp;
}
int main() {
int a = 1, b = 2;
swap(a, b);
printf("a = %d b = %d\n", a, b);
return 0;
}
如果传内存地址的话,就能解决了
#include <stdio.h>
void swap(int *a, int *b) {
// 通过 * 来获取内存地址指向数据的值,然后进行交换操作
int tmp = *a;
*a = *b;
*b = tmp;
}
int main() {
int a = 1, b = 2;
swap(&a, &b); // 传内存地址过去
printf("a = %d b = %d\n", a, b);
return 0;
}
数组
C中数组没有越界异常,声明一个 char name[10];
然后给它初始化,可以初始化成超过10位,超出部分会在内存里找下一个或者下几个char类型的地址然后进行赋值,这是非常可怕的
栈与堆
栈案例
#include <stdio.h>
int main() {
int a = 1, b = 2;
{
int c = 3; // 程序走到这地方时,会创建一个c变量然后将其压入栈中
}
// 当上面代码块执行完时,里面的变量的生命周期也就结束了,会自动被系统给清除掉,所以在下面printf里打印c会报错
printf("a = %d b = %d c = %d\n", a, b, c);
return 0;
}
堆案例
#include <stdio.h>
#include <stdlib.h>
int main() {
int a = 1, b = 2;
int *c; // 声明一个野指针
{
c = (int *)malloc(sizeof(int)); // 给指针分配一块内存空间,此时这个变量是被放在堆里管理的,大小就是int的默认长度
*c = 3; //给指针c赋值
}
printf("a = %d b = %d c = %d\n", a, b, *c);// 打印
free(c); //释放内存,如果不手动释放,就一直在内存里存在
return 0;
}