C 指针
变量三要素:
变量名,变量类型,变量值。
变量作用范围
局部:只在特定范围内起作用。
全局变量:在整个程序运行期间起作用。
存储类型
auto(自动):默认,自动变量动态的分配内存空间,数据存储在动态存储区内。
static(静态):在函数初始化的时候就分配空间,而且数据存储在静态存储区内,在程序运行期间,变量的存储空间不会被释放掉。
register(寄存器变量): 存放在寄存器中,大大提高CPU读取效率。 register int i = 0;
指针变量
int *p = &a;
p变量的值为a变量的内存地址,该指针指向的数据类型为int类型。
int (*p)(int,int)
指向函数的指针,指针指向一个函数入口。
判断方法:p先和*结合,为一个指针。后和(int,int)结合,指针指向返回值为int 的函数。
float *fun(int a);
函数返回值为float类型指针。
int *p[4];
指针数组,数组元素为指针。
判断方法:p和[4]结合为一个数组,数组存储的类型为int类型指针。
float (*pointer)[4]
指向一维数组的指针,指针指向长度为4的数组。
判断方法:pointer和*结合,为一个指针。该指针指向一个长度为4的,存有float类型的数组。
预定义宏
系统运行期间,自动注册的变量。
__LINE__:当前行
__FILE__:当前文件
__DATE__:当前日期,月/日/年
__TIME__:当前的时间,时:分:秒
_cplusplus:在编译一个C++程序时定义
__STDC__:在编译一个C程序时定义,编译C++时也有可能定义
指针、内存地址和指针取值
指针是一个存储计算机内存地址的变量,引用表示计算机内存地址,从指针指向的内存地址中读取数据称作指针取值。
指针可以指向某些具体类型的变量地址,例如:int、long和double。
当声明变量时,用 * 表示这里声明了一个指针。其它情况用到 * 表示指针的取值。&是地址操作符,用来引用一个内存地址。通过在变量名字前使用&操作符,我们可以得到该变量的内存地址。
野指针:指向一块未知内存区域的指针,如:未赋值或直接赋值为内存地址。
指针和数组
C语言的数组表示一段连续的内存空间,用来存储多个特定类型的对象,指针用来存储单个内存地址。数组和指针不是同一种结构因此不可以互相转换,而数组变量指向了数组的第一个元素的内存地址。指向数组的指针必须声明为void类型或者和数组的元素类型保持一致。
一个数组变量是常量,即使指针变量指向同样的地址或者另一个数组,也不能把指针赋值给数组变量。也不能将一个数组变量赋值给另一个数组。但可以把一个数组变量赋值给指针,把数组变量赋值给指针时,实际上是把指向数组第一个元素的地址赋给指针。
指针和结构体
指向结构体的指针存储了结构体第一个元素的内存地址。指向结构体的指针必须声明为void类型或者和结构体类型保持一致。
1 #include <stdio.h> 2 3 int main(int argc, char *argv[]){ 4 5 int *p; //声明一个int指针(未初始化) 6 void *void_p; //空指针,可以存储任意类型的指针或引用 7 int *null_p = NULL; //NULL指针 8 9 int a = 1; //声明一个int变量 10 11 printf("未初始化:\t *p=%p \n", p); 12 13 p = &a; //为指针分配一个int变量的引用 14 printf("赋值后:\t *p=%p \n", p); 15 16 int b = *p; //对指针取值,即获取指针指向地址空间里的内容 17 printf("取值:\t *p=%d b=%d \n", *p, b); 18 19 a = 10; //改变a的值 20 printf("再取值:\t *p=%d b=%d \n", *p, b); 21 22 void_p = p;// void_p 指向另一个指针 23 printf("void指针:\t *void_p=%d\n", *(int *) void_p); //通过显示转换,把一个void指针转成int指针并进行取值 24 25 26 int array[5] = {0, 1, 2, 3, 4}; 27 p = array; 28 29 printf("指向数组的指针:\t array[0]=%d, array[1]=%d, array[2]=%d \n", *(p), *(p + 1), *(p + 2)); 30 31 32 struct person { 33 int age; 34 char *name; 35 int height; 36 }; 37 struct person man; 38 struct person *man_p; 39 40 man.age = 21; 41 man.name = "张三"; 42 man.height = 176; 43 44 man_p = &man; 45 printf("结构体指针:\t name=%s, age=%d, height=%d \n", man.name, (*man_p).age, man_p->height); 46 47 exit(0); 48 49 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术