文章目录
1. 指针是什么,作用是什么
-
指针是一个变量(这个变量只能存地址)
长度为八个字节
不论什么类型(int、char….),指针变量都占据8个字节空间 -
如果希望在函数之间传递数据(>1个)给调用者
就得使用指针来解决(因为return只能返回一个值)
同时如果需要通过函数来完全改变变量的内容,就要通过指针把这个地址里面内容给修改 (按地址传递) -
二级指针
int a = 10;
int *p = &a;
int **p2 = &p
存储方式
2. 指针的类型
- 普通指针变量
- 常量指针
*特点: 指向的值不可以改变,但是能改变指向的方向
int a;
int const *pa = &a;
*pa = 50; //错误!!,因为是常量指针,不能改变指针指向的变量的值
pa = &b; //正确 可以改变指针的指向,同时固定住了b的值(不能利用指针改变量的值)
- 指针常量
*特点: 值可以变, 方向不可以变
int * const pb = &a;
*pb = 50; //正确 可以改变指针指向的变量的值
pb = &b; //错误 不能改变指针的指向
- 指向常量的常量指针
*特点: 值 和 方向 都不可以变
int const * const pc = &a;
*pc = 50; //错误,不能改变指针指向的变量的值
pc = &b //错误,不能改变指针指向的方向
3. 指针和函数
- 定义一个函数,什么情况下参数是指针
这个函数会不会改变传递过来的数据本身
需要改变外部的值,就将整个变量定义为指针变量
如果函数要改变main里面的变量,这时函数就需要用到指针变量
如果函数的声明里是
void ycw(int *pa);
而main里面是
int a;
如果要把a传给ycw,那么要加&
ycw(&a);
//因为函数接受的是指针变量,而指针变量又存着地址
4. 指针与数组
- 传递数组给函数,传的是数组的首地址
函数接受数组时,必须知道元素个数
void ycw(int p[], int count);
或者用指针变量
void ycw(int *p) ; //获取数组首地址,下面就通过赋给不同地址的值来改变不同地址(不同数组元素)的内容
例如:(让数组的每一个元素加+1)
void ycw(int *arr){
for(int i = 0;i < 5;i++){
*arr += 1;
arr++;
}
}
- 注意:
数组名在sizeof内部单独出现以及 &数组名 这两种情况下,数组名表示整个数组
其他情况都表示数组的首地址
int ycw[4];
&ycw + 1 //表示在整个数组之后加1,相当于转到下一个数组
ycw + 1 //表示ycw[0+1] =ycw[1]
- 注意:
定义二维数组
int ycw[3][2] = {{1,2},{3,4},{5,6}};
int ycw[3][2] = {(1,2),(3,4),(5,6)} //错误
都是大括号而不是小括号
-
注意: 【?】
字符指针并不是直接接受字符串,而是接受这个字符串的首地址
因为字符指针只为这个变量分配8个字节内存空间
这个空间只能用来存地址,不能存具体的数据数组的类型是由该数组所存放的东西的类型以及数组本身的大小决定的。
如char s1[3] 和 char s2[4],s1的类型就是char[3],s2的类型就是char[4]
–》详细解释《–
5. 结构体
能存放多个数据类型的新数据类型
- 结构体内存大小计算
两个原则:
起始位置为成员数据类型所占内存的整数倍,若不足则不足部分用数据将内存填充为该数据类型的整数倍。
结构体所占总内存为其成员变量中所占空间最大数据类型的整数倍。
例子:
char a;
int b;
double c;
6. 内存空间
(动态分配内存空间)
-
常量字符串的内存空间由系统自动分配
在常量区里面分配,当程序结束才会被释放
常量区 – 常量 const int a = 1;
静态区 static //程序结束后就释放掉 -
栈 系统分配的内存空间 局部变量 int a = 10;离开作用域,内存空间就自动收回
堆 自己申请的内存空间 malloc calloc realloc(都是函数) 必须自己释放
(不释放就一直存在那里)(此时就需要动态分配内存) -
如果在函数里面给一个指针赋值,那么这个就会变成常量指针
这个指针对应的东西在函数结束后就被释放了,相当于这个地址会变成没有值或者是存在别的值的状态,因此返回给main的时候,再调用这个地址,获得的并不是在函数里面定义的值,而是别的东西甚至没有 -
申请内存:
- 使用指针变量
char *ycw;
- malloc 申请
ycw = (char *)malloc(10*sizeof(char));
- realloc 改变
ycw = (char *)realloc(20*sizeof(char));
- free 释放内存
free(ycw);
7. 文件操作
- 文件操作中的函数要注意是对文件进行操作,而不是对输出屏幕进行操作(在对文件进行操作前,要先打开函数-fopen)
- 对文件进行写入时有以下函数 (fputc fputs fwrite fprintf)
- 对文件进行读取时有以下函数 (fgetc fgets fread fscanf)
- 对文件操作完成后,要关闭文件 fclose
- 另外文件指针默认是指向文件开头,而要对文件部分进行操作时
涉及到
ftell(返回指针位置)函数、
fseek(移动指针)函数、
feof(判断文件执行情况)函数
frewind(将指针移回文件开头)函数
fmove(删除文件)函数
- 例子
FILE* fp; //定义一个文件指针
fp=fopen("文件位置","文件打开方式"); //用文件指针打开文件
if (fp == NULL) //判断文件是否存在
{
printf("文件打开失败");
return; //return 会直接结束函数
}
//...文件具体操作(读取 or 写入)
fclose(fp); //文件操作完成,关闭文件
1. 打开文件
- fp可以变 fp是文件操作指针
//fopen 函数
FILE *fp = fopen("路径","模式");
FILE *fp = fopen("C:\Users\ycw123\Desktop","r");
- 模式列表
- 进行以下操作时,要先fopen
2. 文件写入内容
//fputc 函数
fputc('a',文件操作指针名); //输入单个字符
//fputs 函数
fputs("ycw",文件操作指针名); //输入字符串
3. 读取文件
//fgetc 函数
fgetc(文件操作指针名);
fgetc(fp);
4. 关闭文件
fclose(文件操作指针名);
fclose(fp);