c语言结构体指针的作用,C语言最后内容 指针 结构体(外带教你如何实现保存功能)...

目的

学习并使用指针和结构体

1.为什么要用指针?

2.怎么使用指针?

技术

1.指针

指针问题从两方面考虑:地址 内存空间

我们之所以使用指针,是用它来解决跨区域(不同作用域 不同代码块)之间的数据交互

两个符号的意义

'*':

1.声明/对应变量的时候 表示一个指针变量

float b=20;

int c=10;

int *a;定义一个指针变量 指向的内存空间只能存放整数

注意:定义指针变量的时候一定要给初值 不确定就给null

int *a=b;错误 指针变量只能存储地址 不能存储具体值

int *a=&b;错误 整形指针只能存储整形变量的地址

int *a=&c;正确

float *d+null;null指向内存的起始地址 0x00

2.除了定义指针变量外 都是访问某个地址的值

int *temp=&c//定义指针变量

*temp=21;//访问temp地址里面的数据 赋值为21

‘&’: 取某个变量的地址

另外

%p:打印 int * 型 即打印地址

"%d",*a:打印指针a地址内的内容

2.数组和指针的关系

数组名并不是一个变量 没有分配内存空间 int a=10;

指针变量是有内存空间的

指针变量本身占据8个字节的内存空间

ps:赋值数组某个的值 的2种方法

int num[20]={};

int *pNum=num;

pNum[0]=29;—等价于—*(pNum+0)=29;

区别:

//定义一个数组 系统会分配内存空间 可以存值

int num[10] = {};

//定义一个指针变量 只为变量本身分配8个字节内存空间

//无法存值,因为没有为他分配可以存值的内存空间

给指针指向的区域赋值

//1.指针变量已经指向某块区域

int a3 = 10;

int *pA = &a3; //指向变量a的内存地址

*pA = 30;

//2.指针指向一个数组

int num2[10] = {};

int *pNum = num2; //指向数组num2的首地址

*(pNum+0) = 20;

pNum[0] = 20;

*(pNum + 1) = 30;

pNum[1] = 30;

//3.动态分配内存 malloc realloc free

//分配一个属于自己的内存空间

//自己分配的内存空间必须自己释放

//普通变量的内存是系统自己分配 所以系统自己负责释放

char *pName = malloc(3 * sizeof(char));

//判断分配是否成功

if(pName == NULL){

//分配失败

exit(EXIT_FAILURE);

}

pName[0] = 'j';

pName[1] = 'a';

pName[2] = 'c';

//当之前分配的内存空间不够了 就需要在之前的基础上重新分配

//realloc 必须是之前使用malloc分配过的

//如果是系统分配的内存 是不能使用realloc的用完了就要自己释放内存

pName = realloc(pName, 4*sizeof(char));

pName[3] = 'k';

printf("%s\n", pName);

free(pName);

3.结构体

结构体是一种数据类型 复合数据类型

一般形式:

struct Person {

char name[10];

char *addr;

int age;

};

结构体中用指针和数组的区别

struct Person xw;

//xw.name = "小王";//数组一旦定义 地址不能改变

//不能直接给数组赋值

xw.name[0] = 'x';//系统为这个变量分配内存了

xw.name[1] = 'w';

//xw.addr = "澳大利亚";//常量字符串的地址是由系统分配的

//先为addr分配内存

xw.addr = malloc(4 * sizeof(char));

xw.addr[0] = 'S';//字符指针赋值 必须要有内存

xw.addr[1] = 'o';

xw.addr[2] = 'u';

xw.addr[3] = 't';

xw.age = 30;

printf("name:%s\n", xw.name);

printf("addr:%s\n", xw.addr);

4.数据持久化

先找到桌面的文件路径 如:C:\Users\header\Desktop

再将文件名加上 后如:C:\Users/HP\Desktop\abc.txt

注意:文件路径找到后使用的时候要把''改为'/' 如:C:/Users/HP/Desktop/abc.txt

//mode 文件的操作模式

// r 只读 文件不存在就报错 从头开始读

//w 只写 文件不存在就创建 从头开始写

//a 只写 从末尾开始写

//r+ w+ a+ 可读可写

FILE *fp = fopen("C:/Users/HP/Desktop/abc.txt", "r");

//写入数据

//音频 视频 图片 -> 二进制数据

//fputs("abc", fp);

struct Student{

char name[10];

int age;

};

//struct Student zx1 = {"zhangxiao", 20};

//将结构体写到文件里面去

//fwrite(&zx1, sizeof(struct Student), 1, fp);

//读取数据

//char temp[20] = {};

//fgets(temp, 5, fp);

//printf("%s\n",temp);

struct Student xw1;

fread(&zx1, sizeof(struct Student), 1, fp);

printf("name: %s\n",zx1.name );

printf("age: %d\n", zx1.age);

//关闭文件

fclose(fp);

return 0;

}

实际应用:模拟学生查成绩系统

ad98364df120

image.png

(其中用文件来实现数据持久化)

#import

/*

1. 读取文件内容

内容是什么: 学生信息 -> 结构体

怎么存储:数组 不是最优解

链表 是最优解

线性表 栈 单链表 双链表 二叉树树 图 哈希表

2. 显示界面

Update Delete Insert Select

3. 保存数据

*/

//定义一个学生的结构体节点

typedef struct Node{

char name[10];

int _id;

float score;

struct Node *next;

} Student;

//初始化一个头结点

void initHeader(Student **pHeader){

//动态分配内存

Student *pTemp = malloc(1 * sizeof(Student));

//初始化

pTemp->next = NULL;

//改变外部的值

*pHeader = pTemp;

}

void showMenu(void){

printf("************\n");

printf("1.信息查询\n");

printf("2.信息删除\n");

printf("3.信息更改\n");

printf("4.信息录入\n");

printf("5.退出\n");

printf("************\n");

}

int getChoice(void){

int c;

printf("请您选择操作:");

scanf("%d", &c);

return c;

}

void MyExit(int status){

printf("**************\n");

printf("感谢你的使用再见\n");

printf("**************\n");

}

//保存数据

void save(Student *pTemp){

}

void insert(Student *pTemp){

//准备一个结构体 保存数据

Student *pStu = malloc(1 * sizeof(Student));

pStu->next = NULL;

//提示用户输入

printf("请输入姓名:");

scanf("%s", pStu->name);

printf("请输入成绩:");

scanf("%f", &(pStu->score));

//插入

int count = 0;

while (pTemp -> next != NULL) {

pTemp = pTemp->next;

count++;

}

//自动编号

pStu->_id = count+1;

//将当前这个学生添加到最后一个节点就可以了

pTemp->next = pStu;

}

void querry(Student *pTemp){

//指向第一个数据节点

pTemp = pTemp -> next;

while (pTemp != NULL ) {

printf("id:%d\n", pTemp->_id);

printf("name:%s\n", pTemp->name);

printf("score:%.1f\n",pTemp->score);

printf("\n");

pTemp = pTemp->next;

}

}

int main(int argc, const char * argv[]) {

//定义一个指针 记录头结点

Student *pHeader = NULL;

//初始化头结点

initHeader(&pHeader);

int choice = 0;

while(1){

showMenu();

choice = getChoice();

switch (choice) {

case 1:

//查询

querry(pHeader);

break;

case 2:

break;

case 3:

break;

case 4:

//录入

insert(pHeader);

printf("录入成功!!!\n");

break;

default:

MyExit(EXIT_SUCCESS);

break;

}

}

return 0;

}

感悟

今天的内容有点多,也很难,不过这篇的目的还是在指针和结构体,以后面试的话C语言面到的题重点会有指针,而指针和结构体容易一起出现,所以要好好理解学习,至于那个文件实现数据持久化属于附加内容,链表也是,这些内容单独来看并不是很难理解,但结合在一起使用还是让人掉头发,终于理解脱发的苦恼QAQ。

最后,如果你已经打算要仔细学习这里面的内容,记得买一瓶育发液哦。

ad98364df120

图片发自简书App

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值