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
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

动态内存分配

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;
}
posted @   邵泽龙  阅读(62)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示