1.收获
今天学习了指针的定义,使用,以及它的注意事项,尽管指针有许多的坑,也许我会跌入这个坑中,但是我还是要从跌倒的坑中爬起来,不断理解,收获颇多。虽然以前学过指针,但是只懂一点点,但是通过今天的学习,明白了许多。在以前只是听说动态分配内存,不知道怎么做,虽然自己在网上看了一些资料,但是没有理解,但是今天学习动态分配内存之后,感觉它没有多难,感觉有get到了新的知识。在以前学习c语言的文件的读取和写入这部分时,感觉自己是在听天书,但是今天我明白怎样去读取和写入,以及怎样将结构体写入文件中,这也是以前我不会的,但是现在我会了,这使我的信心大大增加,我明白在编程的道路上是孤独的,大部分时间时坐在电脑的面前,不断思考,不断将代码写入,无论在这条路上是多麽困难,都不能放弃,加油!!!
2.技术
(1).指针的定义,使用以及注意事项
(2).动态分配内存
(3).结构体
(4).文件的读取和写入
3.技术的实际应用与解析
(1)指针
c c++ 有指针 多继承
java 多继承
C语言 :
为什么要有指针: 解决跨区域(不同作用域或不同的代码块)之间的数据交互
指针能够干什么:地址 内存空间
范例:
int *a;
*a 取a的值
a 表示地址
*表示:
一.声明/定义变量的时候 表示一个指针变量 int a;
范例:
float b=20;
int c=10;
*** int *a;定义一个指针变量 指向的内存空间只能存放整数
*** 注意:定义指针变量的时候一定要给初值 不确定就给NULL
范例:
*** int *a=b;//不行 指针只能存地址 不能存具体值
*** int *a=&b; //不行 整型指针只能存整型数据的地址
*** int *a=&c;//正确
*** float *d=NULL//;NULL指向内存的起始地址 0x00
二. 除了定义指针变量之外 都是访问某个地址的
范例:
*** int *temp=&c;//定义指针变量
*** *temp=21;//访问temp地址里面的内容 在这里是给c赋值为21
(2)指针与数组的关系
注意:
//数组名并不是一个变量 没有分配内存空间
指针变量是有内存空间的
范例:
int score[5]={16,65,9,8,4};
printf_s("%p\n",score);
printf_s("%p\n",&score);
在这里两者输出的结果是相同的,如果数组名分配内存空间
,那么输出的结果是不相同的,当时这里输出的结果是相同的说明数组名并不是一个变量 没有分配内存空间。
在学习完指针后要对指针进行进一步的理解
范例:
for(int i=0;i<5;i++){
printf_s("%d",*(score+1));
}
printf_s("%p",score);
printf_s("%p",score+1);
printf_s("%d",*(score+1));
printf_s("%d",*score+1);
在这里%p是对指针变量本身进行输出
score表示数组的首地址
而score+1表示score+1=score+类型的字节数乘1
*score表示score的指的地址中内容
//
printf_s("%d",(*score)++);
printf_s("%d",score[0]);
printf_s("%d",++*score);
这里用了++的知识点,前面的文章已经讲了,在这里说明一下(score)++,他打印出来时score的内容,但是后面就执行了++,所以score[0]就比原来多一,因为score=score[0]
//定义一个数组 系统会分配内存空间 可以存值
int num[10]={};
定义一个指针变量 只为变量本身分配8个字节的空间 无法存值,因为没有为他分配内存空间
范例:
int *p;
num[2]=20;可以
*p=20;不行
因为这里的指针没有指向任何区域
//如果想给指针指向的的区域赋值
// (1).指针变量已经指向某块区域
int a=10;
int *p=&a;
*p=30;
** //(2).指针指向一个数组**
int num[10]={};
int *p=num;
*(p+0)=20;
p[0]=20;
*(p+1)=30;
p[1]=30;
(3).动态分配内存
动态分配内存
三个用到的 malloc realloc
//上面两种指向的内存是别人的
//希望分配属于自己的内存空间
free
//自己分配的内存空间必须自己释放
//普通变量的内存是系统自己分配的 所以系统自己负责释放
//需要导入文件
#include "stdlib.h"
//开始自己分配内存
char *p=malloc(3*sizeof(char));
//判断是否成功
if(p==NULL)p{
//分配失败
//退出
exit(EXIT_FAILURE);
}
P[0]='j';
p[1]='l';
p[2]='m';
printf_s("%s\n",p);
在这里打印出来结果是ijm
//当自己申请的内存空间不够了或多了 就需要在之前的基础上重新分配
//realloc 必须是之前使用malloc分配过的
//如果是系统分配的内存 是不能用realloc的
p=realloc(p,4*sizeof(char));
p[3]='h';
//也要判断是否分配成功
if(p==NULL)p{
//分配失败
//退出
exit(EXIT_FAILURE);
}
//用完了就要自己释放内存
free(p);
其实动态分配内存不是那磨难
(4)结构体以及结构体的读入文件
定义
结构体// 是一种数据类型 复合数据类型
//struct
//声明一种类型 struct Person
struct Person{
char *addr;
char name[10];
int age;
};
//定义结构体变量
int i;
i=20;
struct Person xw;
xw.name="小王";错的//数组一旦定义 地址不能改变
//不能直接给数组赋值
xw.name[0]='x';//系统为这个变量分配内存了
xw.name[1]='w';
//xw.addr="西南大学"//可以的 常量字符串的地址是由系统分配的
xw.addr[0]='s';//字符指针赋值 必须要有内存 这样是不对的
如何将结构体读入和读取
//首先声明
#include "stdlib.h"
//打开文件
FILE *p;
fopen_s(&p,"C:/Users/ASUS/Desktop/ABC.txt","w");
if(p!=NULL){
printf_s("该文件打开成功\n");
/}
else printf_s("该文件打开失败\n");
//定义一个结构体
struct Student{
char name[20];
int age;
float score;
};
struct Student student1={"xiaowang",20,89.23};
//将结构体写入文件
fwrite(&student1,sizeof(struct Student),1,p);
//读取文件
在这里需要注意在读取时是不需要再写入文件的吗,因为前面已经写入文件了
定义一个新的结构体变量
FILE *p;
fopen_s(&p,"C:/Users/ASUS/Desktop/ABC.txt","r");
struct Student student1={};
//读取数据
fread(&student1,sizeof(struct Student),1,p);
printf_s("name:%s\n",student1.name);
printf_s("age:%d\n",student1.age);
printf_s("score:%0.2f\n",student1.score);
//关闭文件
fclose(p);
printf_s("文件已保存\n");
(5)文件的读取和写入
//打开文件
FILE *p;
fopen_s(&p,"C:/Users/ASUS/Desktop/ABC.txt","w");
if(p!=NULL){
printf_s("该文件打开成功\n");
}
else printf_s("该文件打开失败\n");
//写入文件(在终端中输入xiaowang#)
fputs("c",p);
printf_s("请输入需要写入的字符(以#结束):");
char ch=getchar();
while(ch!='#'){
fputc(ch,p);
ch=getchar();
}
printf_s("\n");
然后文件中就有
//读取数据
char name[10]={};
fgets(name,8,p);//这里的数字是表示读取多少个字符
printf_s("%s\n",name);
最终将“xiaowang”读出
//关闭文件
fclose(p);
printf_s("文件已保存\n");