C语言基础 record 2-指针,结构体,链表,文件的输入输出

指针:

1.指针的概念:
内存区的每一个字节有一个编号,这就是 ‘地址’,由于通过地址能找到所需的变量单元,而地址指向该变量单元,所以将地址形象化称为 ‘指针’。C/C++中是可多继承的指针,而Java中是单继承指针。

2.为什么要用指针?
解决跨区域(不同作用域,不同代码块)之间的数据交互。

3.指针变量:
如果有一个变量专门用来存放另一变量的地址(即指针),则它称为 ‘指针变量’。指针变量的值是地址(即指针)。指针变量本身在内存里面占据8个字节。

注意⚠️:指针是一个地址,而指针变量是存放地址的变量。

4.怎样定义和使用指针变量:

“&” :取地址运算符。&a 是变量a的地址。
” :指针运算符(或称‘间接访问’ 运算符),p代表指针变量p指向的对象
(1)定义指针变量的一般形式为:
类型名 * 指针变量名;
eg: int *point_1, *point_2;

注意⚠️:定义指针变量时必须指定基类型。可以在定义指针变量时同时对它初始化

(2)一个变量的指针的含义包括两个方面:
一是以存储单元编号表示的纯地址(如编号为2000的字节);一是它指向的存储单元的数据类型(如 int,char,float等)。

注意⚠️:指针变量中只能存放地址(指针),不能将一个整数赋给一个指针变量。地址只能用地址符 “&” 得到并赋给一个指针变量。
eg:
float b =20;
int c = 10;
int *a=b;❌ 指针变量只能存地址,不能存具体值
int *a=&b;❌整型指针只能存整形数据的地址
int *a = &c;✔️
float *d = NULL;NULL指向内存的起始地址 0x00

(3)数组和指针的关系:
数组名并不是一个变量 ,没有分配内存空间。 而指针变量有内存空间。

(4)指针实际使用:
a. 定义一个数组,系统会为其分配内存空间,可以存值
int num[10]={0};
b. 定义一个指针变量,系统只为变量本身分配8个字节内存空间,但无法存值,因为系统没有为其分配可赋值的内存空间
int *p;
c. 如果想给指针指向的区域赋值
//1.指针变量已经指向某块区域

Xnip2019-08-04_10-37-29.png

//2.指针指向一个数组
C语言基础 record 2-指针,结构体,链表,文件的输入输出_第1张图片
Xnip2019-08-04_10-37-41.png
//3.动态分配内存

a. 用 malloc 函数开辟动态存储区,其函数原型为:
                void * malloc (unsigned int size);

其作用是在内存的动态储存区中分配一个长度为 size 的连续空间。
b. 用 calloc 函数开辟动态存储区,其函数原型为:
void * calloc (unsigned n, unsigned size);
其作用是在内存的动态存储区分配 n 个长度为 size 的连续空间,这个空间一般比较大,足以保存一个数组。
c. 用 realloc 函数重新分配动态存储区,其函数原型为:
void * realloc (void *p, unsigned int size);
如果已经通过 malloc 函数或 calloc 函数获得了动态空间,想改变其大小,可以用 realloc 函数重新分配。
d. 用 free 函数释放动态存储区,其函数原型为:
void free (void *p);
其作用是释放指针变量 p 所指向的动态空间,使这部分空间能重新被其他变量使用。p 应是最近一次调用 malloc 或 calloc 函数时得到的函数返回值。

1).分配一个属于自己的内存空间 必须由自己释放
2).普通变量的内存空间由系统分配和释放
C语言基础 record 2-指针,结构体,链表,文件的输入输出_第2张图片
Xnip2019-08-04_10-38-04.png
3).若之前分配的内存空间不够或多余了 则必须重新分配 重新分配用(在malloc基础上):realloc
C语言基础 record 2-指针,结构体,链表,文件的输入输出_第3张图片
Xnip2019-08-04_10-38-13.png

5.通过指针引用数组:
(1)所谓数组元素的指针就是数组元素的地址。可以用一个指针变量指向一个数组元素:
eg:
int a[10]={1,3,4,6};
int *p;
p=&a[0];
(2)引用数组元素可以用下标法:a[i]形式,也可以用指针法:如 *(p+i) 或 *(a+i) 即通过指向数组元素的指针找到所需的元素。
(3)在指针指向一个数组元素时可以对指针进行以下运算:
加一个整数:(用+或+=),如p+1;
减一个整数:(用-或-=),如p-1;
自加运算:如p++,++p;
自减运算:如p--,--p;
两个指针相减,如p1-p2,只有p1和p2都指向同一数组中的元素才有意义。
注意⚠️:
a. 如果p的初值为&a[0],则p+i和a+i就是数组元素a[i]的地址,或者说它们指向a数组序号为i的元素。
b. *(p+i) 或 *(a+i) 是 p+i 或 a+i 所指向的数组元素,即 a[i]。例如 *(p+5) 或 *(a+5) 就是 a[5]。即 *(p+5), *(a+5) 和 a[5] 三者等价。

结构体:

  1. 建立结构体类型:
    struct 结构体名
    {成员表列};
    成员都应进行类型声明,即:类型名 成员名

  2. 定义结构体类型变量:
    (1)先声明结构体类型,再定义该类型的变量
    (2)在声明类型的同时定义变量。其一般形式为:
    struct 结构体名
    {
    成员表列
    }变量名表列;
    (3)不指定类型名而直接定义结构体类型变量。其一般形式为:
    struct
    {
    成员表列
    }变量名表列;

  3. 结构体变量的初始化和引用:
    (1)在定义结构体变量时可以对它的成员初始化。初始化列表是用花括号括起来的一些常量,这些常量依次赋给结构体变量中的个成员。
    (2)可以引用结构体变量中成员的值,引用方式为:
    结构体变量名,成员名
    “ . ” 是成员运算符,在所有的运算符中优先级最高。
    (3)如果成员本身又属一个结构体类型,则要用若干个成员运算符,一级一级的找到最低的一级的成员,且只能对最低级的成员进行赋值或存取以及运算。
    (4)对结构体变量的成员可以像普通变量一样根据其类型进行各种运算。
    (5)同类的结构体变量可以互相赋值。
    (6)可以引用结构体变量成员的地址,也可以引用结构体变量的地址。

  4. 结构体数组:
    (1)定义结构体数组一般形式是:
    a. struct 结构体名
    {成员表列} 数组名[数组长度];
    b. 先声明一个结构体类型,然后再用此类型定义结构体数组:
    结构体类型 数组名[数组长度];

(2)对结构体数组初始化的形式是在定义数组的后面加上:
= {初值表列};

  1. 结构体指针:
    假设声明一个 struct Student 结构体类型,struct Student p 定义为为指向 struct Student 类型数据的指针变量 p,‘num’ 为 struct Student 中的一成员变量。C 语言允许把 (p).num 用 p->num 代替, “-> ”代表一个箭头, p->num 表示 p所指向的结构体变量中的 num 成员。
    如果 p 指向一个结构体变量 stu ,以下3种用法等价:
    a. stu. 成员名;
    b. (*p).成员名;
    c. p->成员名;

链表:

  1. 链表是动态的进行存储分配的一种常见的数据结构。
    2.链表有一个“头指针”变量,它存放一个地址,该地址指向一个元素。
    3.链表中每一个元素称为“结点”,每个结点都包括两部分:
    (1)用户需要用的实际数据
    (2)下一个结点的地址

文件的输入输出:

1.一个文件要有一个唯一的文件标识,以便用户识别和使用。文件标识包括3部分:
(1)文件路径;
(2)文件名主干;
(3)文件后缀。

2.文件类型指针:
(1)缓冲文件系统中,每个被使用的文件都在内存中开辟一个相应的文件信息区用来存放文件的有关信息,这些信息都保存在一个结构体变量中,该结构体类型由系统声明,取名为:FILE。
(2)要引用 FILE 类型变量,一般不通过给 FILE 类型的变量命名来引用这些变量,而是设定一个指向 FILE 类型变量的指针变量来引用这些 FILE 类型变量。比如,定义一个指向文件型数据的指针变量 fp:FILE * fp; 通过该文件指针变量能够找到与它关联的文件。

  1. 用函数打开与关闭文件
    (1)用 fopen 函数打开数据文件
    fopen 函数的调用方式为:fopen(文件名,使用文件方式);
    eg:


    C语言基础 record 2-指针,结构体,链表,文件的输入输出_第4张图片
    Xnip2019-08-04_18-31-59.png

(2)用 fclose 函数关闭数据文件
fclose 函数的调用方式为:fclose(文件指针);

注意⚠️:打开了一个文件一定要关闭


C语言基础 record 2-指针,结构体,链表,文件的输入输出_第5张图片
Xnip2019-08-04_18-32-40.png
  1. 使用文件的方式:
    r : 只读 w : 只写 a : 追加
    rb : 只读 wb : 只写 ab: 追加
    r+ : 读写 w+ : 读写 a+ : 读写
    rb+ : 读写 wb+ : 读写 ab+ : 读写
    常用下面的方法打开一个文件:


    C语言基础 record 2-指针,结构体,链表,文件的输入输出_第6张图片
    Xnip2019-08-04_17-56-23.png

5.向文件读写字符:
(1)向文本文件读入字符:
函数名:fgetc
调用形式:fgetc(fp)
(2)向文本文件输出字符:
函数名:fputc
调用形式:fputc(ch,fp)

6.向文件读写字符串:
(1)向文本文件读入字符串:
函数名:fgets
函数原型:
char * fgets(char * str,int n,FILE * fp);
调用形式:fgets(str,n,fp)
功能:从 fp 指向的文件读入一个长度为(n-1)的字符串,存放到字符数组 str 中。
eg:

C语言基础 record 2-指针,结构体,链表,文件的输入输出_第7张图片
Xnip2019-08-04_18-32-20.png

(2)向文本文件输出字符串:
函数名:fputs
函数原型:
int fputs(char * str,FILE * fp);
调用形式:fputs(str,fp)
功能:把 str 所指向的字符串写到文件指针变量 fp 所指向的文件中。

今日总结感悟:A day of Tired, boring, unreadable .

你可能感兴趣的:(C语言基础 record 2-指针,结构体,链表,文件的输入输出)