二级指针
一级指针用来保存普通变量的地址
二级指针用来保存一级指针变量的地址
数据类型** 变量名;
Intnum = 0;
一级指针:
Int*p = #
二级指针:
Int*pp = &p;
注意:
(1)二级指针一般用于函数的形参中,用于带回数据
通用类型指针
void* 通用类型指针,表示一个地址
注意:
void* v;不能直接取出数据,需要做类型转换
动态内存分配
动态内存是指程序员通过代码主动向系统申请指定大小的内存,只要是程序员主动申请的(通过申请内存函数)都是放在堆区,申请成功后系统会返回该申请内存的首地址给程序员,但这些内存不能由系统自己释放了,而是由程序员进行释放,假若不释放就会出现内存泄漏
动态内存申请函数:
#include<stdlib.h>
malloc(内存大小),返回值void*表示的首地址,对于申请的内存不做初始化
如:int* p =(int*)malloc(sizeof(int))
解释:在栈区申请一个名为p的整型指针,该指针保存在堆区申请出来的首地址
calloc(元素个数,每个元素的大小) 返回值也是void*表示的首地址,内存清零
int* p =(int*)calloc(2,sizeof(int))
realloc(原来内存首地址,新内存的大小)如果新申请的大小可以在原来的内存后面
进行扩展,那么返回原来首地址,如果不能扩展,则重新寻找位置寻找内存,将原来的数
据拷贝过来,释放原来的内存,同时返回新内存的首地址
free(首地址) 释放指定的内存空间
函数指针
概念
数组指针:指向数组的指针
函数指针:指向函数的指针
格式
函数:返回值类型 函数名(形参);
解释:
优先级首先是形参括号,之后是函数名称,最后是返回类型
函数指针:返回值类型 (*函数指针名)(形参);
解释:
优先级首先是左括号,先是一个指针,之后是形参括号,最后是返回类型
例子
int* fn(int i); //先括号,函数名,再返回值 ——是一个函数
表示fn是一个函数,一个具有int类型形参和int*类型返回值的函数
int(*fn)(int i);表示fn是一个函数指针,一个指向具有int类型形参和int类型返回值
函数的指针
函数指针就是保存一个固定格式函数的变量,这个变量是一个指针
实际应用:
例子
//函数指针的用途
#include <stdio.h>
void fn1(int* num)
{
printf("num = %d\n",*num);
}
void fn2(int* num)
{
*num = 118;
}
void fn3(int* num)
{
(*num)++;
}
//编写一个通用函数,可以分别调用上面的三个函数
void common(int* pNum,void (*pF)(int* num))
{
pF(pNum);
}
int main(void)
{
int num = 66;
fn1(&num);
fn2(&num);
fn1(&num);
fn3(&num);
fn1(&num);
printf("----------------------------\n");
common(&num,fn1);
common(&num,fn2);
common(&num,fn1);
common(&num,fn3);
common(&num,fn1);
return 0;
}
文件操作
File类型没有存储指向的文件名,File类型定义:
struct{
int _fd;//文件号
int _cleft;//缓冲区所剩下的字符数
int _mode;//文件操作方式
char* _next;//文件当前读写位置
char* _buff;//文件缓冲区位置
}FILE;
//向文件中写入一个字符串,再读取出来打印到屏幕上
#include <stdio.h>
int main(void)
{
//1.打开一个文件
FILE* fp= fopen("a.txt","w");
if(fp ==NULL)
{
printf("打开要写入数据的文件失败\n");
return -1;
}
//2.写入一个字符串数据
charbuf[20] = "GoodAfternoon!";
fputs(buf,fp);
//3.关闭这个文件
fclose(fp);
//4.再次打开这个文件
FILE*fp2 = fopen("a.txt","r");
if(fp2== NULL)
{
printf("打开读取的文件失败\n");
return -1;
}
//5.读取文件中保存的字符串内容
charbuf2[20] = {0};
fgets(buf2,20,fp2);
printf("读取到的字符串内容是:%s\n",buf2);
//6.再次关闭这个文件
fclose(fp2);
return0;
}
文件操作的相关函数
文件定位问题
int fseek(FILE *stream, long offset, int whence);
功能分析:
第一个参数为文件指针,第二个参数表示偏移量,第三个参数表示从什么地方开始偏移
,返回值为0表示成功,-1表示失败
whence的数值:
SEEK_SET 文件的起始位置 0
SEEK_CUR 文件的当前读写位置 1
SEEK_END 文件的末尾位置 2
注意:
(1)如果偏移量是正数,表示从文件开头向文件末尾的方向移动,如果偏移量是负数,那么
向文件开头的方向移动
(2)SEEK_END 表示文件中最后一个字符的下一个位置
ftell和rewind函数
long ftell(FILE *stream);
功能分析:
表示将stream指向文件的读写位置偏移量通过返回值返回出来,偏移量指的以文件的开头
位置为基准
void rewind(FILE *stream);
功能:
表示将stream指向的文件读写位置移动到文件的开头
fread和fwrite函数
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
功能:
第一个参数表示内存地址,第二个参数为每一个数据的大小,第三个参数为数据的个数,
第四个参数为具体的文件
fread表示将文件中的数据读取出来存储到ptr指向的内存中
fwrite表示将ptr指向的内存中数据存储到文件中
返回值为成功读写的数据个数
例子1
//fseek函数的使用
#include <stdio.h>
int main(void)
{
//1.打开文件
FILE* fp = fopen("b.txt","r+");
if(fp == NULL)
{
printf("打开文件失败\n");
return -1;
}
printf("开始的读写位置是:%ld\n",ftell(fp));
//2.调整文件的读写位置
char c = fgetc(fp);
printf("读取到的字符是:%c\n",c);
printf("读取之后的读写位置是:%ld\n",ftell(fp));
fseek(fp,2,SEEK_CUR);
c = fgetc(fp);
printf("读取到的字符是:%c\n",c);
printf("移动之后的读写位置是:%ld\n",ftell(fp));
fseek(fp,3,SEEK_SET);
c = fgetc(fp);
printf("读取到的字符是:%c\n",c);
fseek(fp,-1,SEEK_CUR);
c = fgetc(fp);
printf("读取到的字符是:%c\n",c);
//fseek(fp,-2,SEEK_END);
fseek(fp,-2,2);
c = fgetc(fp);
printf("读取到的字符是:%c\n",c);
//移动读写位置到文件的开头
rewind(fp);
printf("开始的读写位置是:%ld\n",ftell(fp));
//3.关闭文件
fclose(fp);
return 0;
}
例子2
//定义员工结构体,实现信息的存储和读取
#include <stdio.h>
typedef struct Employee
{
int id;
char name[20];
int salary;
}Employee;
int main(void)
{
//1.打开文件
FILE* fp = fopen("employee.dat","w");
if(fp == NULL)
{
printf("打开存储文件失败\n");
return -1;
}
//2.输入员工信息并且存储到文件中
Employee e = {0};
int i = 0;
for(i = 0; i < 3; i++)
{
printf("请输入第%d个员工的信息:\n",i+1);
scanf("%d%s%d",&e.id,e.name,&e.salary);
fwrite(&e,sizeof(Employee),1,fp);
}
//3.关闭文件
fclose(fp);
//4.再次打开文件
FILE* fp2 = fopen("employee.dat","r");
if(fp2 == NULL)
{
printf("打开读取文件失败\n");
return -1;
}
//5.读取文件信息并且输出到屏幕上
Employee e2 = {0};
for(i = 0; i < 3; i++)
{
fread(&e2,sizeof(Employee),1,fp2);
printf("第%d个员工的信息是:%d %s %d\n",i+1,e2.id,e2.name,e2.salary);
}
//6.再次关闭文件
fclose(fp2);
return 0;
}