C语言基础
C语言基础
编程思想
- 翁凯
- 反向封闭(将已知判断条件做取反,得到最少代码实现聚焦功能)
基础语法(略,参考Java)
指针(保存地址的变量)
&:取地址赋值或传参
*:访问指针变量所指的空间
使用
int i;//声明int类型的变量i
int* p=&i;//声明int类型的指针变量并赋值变量i的地址,也就是说让p指向i所代表的int内存空间
int* p,q;//这句和下一句一样效果,int*不是完整的,而*p才构成指针变量,所以q是int而不是指针
int *p,q;
//作为参数声明,指定需要对方提供变量地址作为参数传递
//int i=0;fun(&i);
//作为函数可以通过指针来访问外面定义的i变量所指的空间
void fun(int *p)
//函数内使用
int k = *p;
*p = k+1;
//场景一:使用函数交换变量
//场景二a:函数返回多个值,给函数提供存放区
//场景二b:函数返回运算状态,结果通过指针返回(为了避免结果中含有意义不明的部分,比如0或-1也为有效结果时)
//注意没有初始化的指针值可能随机内容,当使用*p去运算时,它指向哪里完全不可预料,会出现异常也不可预料
与数组的关系
传递数组进入函数时,其实传递的是数组地址,也就是首地址,在函数内,sizeof函数无法判断数组的真实大小,因为它在函数中变成指针
但是,与其说数组变成指针,不如说数组变量本身表达的是地址
//以下四种函数原型是等价的
int sum(int *ar, int n);
int sum(int *, int);
int sum(int ar[],int n);
int sum(int [], int);
//注意
int a[10];
int *p=a;//无需用&取地址
//但是数组的单元表达的是变量,需要用&取地址
a == &a[0]
//[]运算符可以对数组做,也可以对指针做
//p[0]等价于*p
//int a[10]; *a等价于a[0]
//可以认为数组变量是const的指针,不能被赋值
int a[]; int * const a=....
与const的关系
- 指针是const
- 一旦得到了赋值,不能再指向其他变量
- int * const q = &i //q是const
- *q = 26; //ok
- q++; //ERROR
- 一旦得到了赋值,不能再指向其他变量
- 所指的是const
- 表示不能通过这个指针去修改所指的那个变量(并不能使得那个变量成为const,仅仅是限制指针不去修改,指针变为只读)
- const int *p = &i;
- *p = 26 ;//ERROR! (*p)是const
- i = 26;//ok
- p = &j;//ok
- 表示不能通过这个指针去修改所指的那个变量(并不能使得那个变量成为const,仅仅是限制指针不去修改,指针变为只读)
int i;
const int* p1;
int const* p2;
int *const p3;
//判断哪个被const了的标志是const在*的前面还是后面:*前面-只读指针;*后面-指针值固定
//总是可以把非const的值转换称const的
void f(const int* x);
int a = 15;
f(&a); //ok
const int b = a
f(&b); // ok
b = a+1; //Error!
const数组
- const int a[] = {1,2,3,4,5,6};
- 数组变量已经是const的指针了,这里的const表明数组的每个单元都是const int
- 所以必须通过初始化进行赋值
- int sum(const int a[],int length);
- 因为把数组传入函数时传递的是地址,所以那个函数内部可以修改数组的值
- 为了保护数组不被函数破坏,可以设置参数为const
指针的运算
这些算术运算可以对指针做:
- 给指针加、减一个整数(+,+=,-,-=),移动指针
- *p++,取出p所指的那个数据,完事后顺便把p移到下个位置,++比*优先级高,常用于数组类的连续空间操作,在某些cpu上,这可以直接被翻译成一条汇编指令
指针的比较
- <,<=,==,>,>=,!=都可以对指针做
- 比较它们在内存中的地址
- 数组的单元地址肯定是线性递增的
0地址
- 通常不能使用
- 指针不应该具有0值
- 代表
- 返回指针无效
- 指针没有真正初始化(先初始化为0)
- NULL是一个预定义的符号,表示0地址
- 有的编译器不愿意你用0来表示0地址
指针的类型
- 类型
- 无论指向什么类型,所有的指针的大小都是一样的,因为都是地址
- 但是指向不同类型的指针是不能直接互相赋值的,为了避免用错指针
- 转换
- void* 表示不知道指向什么东西的指针
- 计算时与char*相同(但不相通)
- 指针可以转换类型
- int *p = &i;void *q = (viod*)p;
- 这没有改变p所指的变量的类型,而是让后人用不同的眼光通过p看它所指的变量
- 我不在当你时int,而是void
- int *p = &i;void *q = (viod*)p;
- void* 表示不知道指向什么东西的指针
动态内存分配
C99之后可以用变量来定义数组大小,C99之前使用int *a = (int *)malloc(n*sizeof(int));
malloc来自于stdlib.h文件,此时指针a当作数组来使用,a[0]。。。
malloc与free成对出现:malloc锁定空间使用,free解放空间归还
#include<stdio.h>
#include<stdlib.h>
//测试本机器可申请的空间有多大
int main(void){
void *p;
int cnt = 0;
while ((p=malloc(100*1024*1024))){
cnt++;
}
printf("分配了%d00MB的空间\n", cnt);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?