C语言基础知识学习三

结构体

1.结构体变量声明和定义

结构体是一种构造类型,必须先声明再定义后使用.

声明一般形式:

struct student

{

成员类型 成员名1;

……

};

定义一般形式:

struct student st1,st2;

在声明的同时定义struct student {}st1,st2;

直接定义变量struct {}st1,st2;//这种变量只能是两个不能再增加

typedef struct student{}ST;

ST st1,st2;//一般使用这种

2.结构体的引用

成员点记法:st1.data;

由于结构体占用的内存较大,在函数中传递结构体时一般传递结构体的地址.

ST *p;

此时可写成p->data;引用成员.

3.结构体数组

与普通数组一样,相当于有N个一样结构体.

4.结构体指针

定义指针变量方式:

struct 结构体类型名 *结构体指针变量名;

访问成员方式:

1) 结构体变量名.成员名;

2)(*结构体指针变量名).成员名;

3)结构体指针变量名->成员;

5.动态内存分配

为什么要动态内存分配?

用多少分多少,随时分配,随时释放,静态的在程序结束后自动释放,浪费空间.

分配内存空间函数

1)malloc函数

使用:(类型说明符*)malloc(size);

类型说明符*:强制转换为这种类型的空间.

功能:在内存的动态存储区中分配一块长度为size的连续区域,函数的值是该区域的首地址.

2)calloc函数

使用:(类型说明符*)calloc(n,size);

功能:在内存动态存储区中分配n块长度为size的连续区域,函数的返回值为该区域的首地址.

释放内存空间函数

1)free函数

使用:free(指针变量);

功能:释放动态分配的空间.

6.共用体(联合体)

共用体的声明与调用

一般形式:

union 共用体类型名

{

类型 成员名1;

……

};

调用方式:与结构体一样.

共用体的存储方式

每个成员不占用专门的空间,全体成员共用一块内存,在初始化时每次只能初始化一个

注意:

1) 不能引用共用体的整体,只能引用某个成员

2) 与结构体的调用方式一样,可以是使用->和.

3) 不能在定义共用体时进行初始化

4) 共用体中起作用的是最后一次存放的成员

5) 共用体变量不能作为函数的参数,成员可以

7.枚举类型

枚举类型的声明与定义

枚举类型与结构体类型一样,是一个新的数据类型,需要先声明后定义再使用

声明一般形式:

enum 枚举类型名

{

枚举常量1,//默认标号为0-n

枚举常量2,//可以枚举常量 = 1重新改变标号

……

};

枚举类型的使用

typedef enum UARTx

{

UART0,

UART1

}UARTx;

void SCI_Init(UARTx uart,long unsigned int baud)

文件

1.文件的打开和关闭

1)文件的打开

使用(fopen(fp)函数)

FILE *fp;

fp = fopen (“文件路径及文件名”,“文件使用方式”)

if(fp == NULL)//判断文件是否打开成功,文件打开失败fopen返回NULL

文件路径:

(1)C\\code\\aaa.txt(自定义文件路径).

(2)C/code/aaa.txt(自定义文件路径).

(3)aaa.txt(保存在当前文件中).

文件名:自定义任意拓展名.

文件使用方式:

r:只读打开一个文件(文件必须存在).

w:只写打开一个文件(文件存在会重新创建一个).

a:追加打开一个文件(文件必须存在).

rb、wb、ab:二进制的方式操作.

r+:按读写的方式打开一个文本文件.

w+:按读写的方式创建一个文本文件.

a+:按读写的方式打开一个文本文件.

rb+、wb+、ab+:二进制的方式操作.

2)文件的关闭

使用(fclose(fp))每一次文件操作完成后都要关闭.

2.文件的读写

1)字符的输入输出函数

fgetc 函数和fputc函数:

从文件中读写一个字符(以字节为单位读写).

(1)fgetc 函数(从指定的文件中读入一个字符)

FILE *fp;

char ch;

fp = fopen (“file.txt”,”r”) ;

ch = fgetc (fp);

读入的字符可以输出到屏幕(printf (“%c”,ch)或putch(ch)).

可以循环读取每读一次指针向后移动一位读到文件末尾时返回EOF如果读取错误也返回EOF(EOF的值为-1).

注意文件必须以只读或读写的方式打开

ANSIC中feof函数判断文件是否读完.

feof(fp)如果文件结束返回1,否则返回0.

while(!feof(fp))

{

ch = fgetc (fp);

……

}

(2)fputc函数(向指定的文件中写入一个字符)

while (ch ==‘指定的结束字符’)

{

ch = getchar ();//键盘输入要写入的字符//scanf(“%c”,&ch)//二者等价

fputc (ch,fp)//将字符写入文件

putchar (ch);//输出到屏幕上

……

}

注意如果函数写入成功,返回字符否则返回EOF

可以用w、w+、a等方式打开文件.

2)字符串的输入输出函数

(1)字符串的输出函数fgets(string,n,fp)//从文件中读给字符串.

string 是定义的数组存储文件中读出的字符串.

n是读出的字符串不超过(n-1)个字符,在最后一个字符后加上’\0’而fgets函数读完时返回NULL,开始读的时候返回字符数组的首地址读取的字符串存在数组中.

文件已w、w+、a+等方式打开且必须存在.

(2)字符串的输入函数fputs(string,fp)//从字符串中写到文件

字符串可以是数组名或指针变量,但是字符'\0'不输出.

fputs(“abc”,fp);//将字符串abc写入到文件.

fputs(string,fp);//将字符串数组string写入到文件.

与fputc的区别是fputc需要结束标志要不停的写入.

3)格式化读写函数

(1)格式化输入函数fscanf(文件指针,格式字符串,输入参数)

fscanf (fp,”%d%f”,&i,&t);//从文件中读取给变量

(2)格式化输出函数fprintf(文件指针,格式字符串,输入参数)

fprintf (fp,”%d%c”,i,ch);//从变量写到文件

4)数据读写函数

(1)数据读函数

整型变量 = getw(fp)//从文件中读入一个整数

注意:如果超出整型所占的大小返回的值是垃圾值.

(2)数据写函数

putw(整数,fp)//从变量中写入到文件

5)数据块读写函数

(1)读数据块函数fread(buffer,size,count,fp)

最多读取count个项,每个项size个字节,如果调用成功返回实际读取到的项个数(小于或等于count),如果不成功或读到文件末尾返回 0.

//从文件中读取到buffer地址内.

buffer 为数据块的起始地址.

size为读取一个数据块的长度(sizeof ()).

count 为读取数据块的个数(a[5]读取1次就能读完).

(2)写数据块函数fwrite(buffer,size,count,fp)

//从地址中的变量写到文件.

buffer 待写入数据块的起始地址.

size为写入一个数据块的长度(sizeof ()).

count 为写入数据块的个数(a[5]写入1次就能写完).

char a[11] = "HelloWorld!";

fwrite (a,sizeof(a),1,fp);

注意如果是字符串的话只能读n-1个.

3.文件的随机读写

1)rewind函数

用法:rewind(fp);

功能:使文件内部的位置指针重新返回文件的开头.

2)fseek函数

用法:fseek(fp,位移量,起始点);

位移量:以起点为基点,向前移动的字节数.

offset为偏移量,正数表示正向偏移,负数表示负向偏移.

起始点:SEEK-SET(0),SEEK-CUR(1),SEEK-END(2).

分别是文件首,当前位置,文件末尾.

fseek(fp,-100L,2);把stream指针退回到离文件结尾100字节处.

功能:使位置指针移到指定的位置

while (!feof(fp1))

fputc(fgetc(fp1),fp2);// 整体含义:将fp1中的字符复制到fp2指向的文件中.

注意:文件指针指向文件/流。位置指针指向文件内部的字节位置,随着文件的读取会移动,文件指针如果不重新赋值将不会改变或指向别的文件.

3)ftell函数

用法:name = ftell (fp);//name为long型变量.

功能:得到文件位置指针的当前位置.

文件刚打开时文件指针位置在文件首,随着操作的进行文件指针会随之移动,读一次移动一次,直到在循环中通过feof函数检测到文件结束时,此时文件指针位置在文件的末尾.

4.文件的出错检测

1)feof函数

用法:feof(fp);

功能:判断文件是否处于文件的结束位置,如结束返回1否则返回0.

2)ferror函数

用法:ferror(fp);

功能:检查它前面一个输入或输出文件操作是否有错误,有返回1否则0.

3)clearerr函数

用法:clearerr(fp);

功能:使文件错误标志和文件结束标志置为0.假设在调用一个输入输出函数时出现了错误,ferror函数值为一个非零值。在调用clearerr(fp)后,ferror(fp)的值变为0.

编译预处理

1.宏定义#define

1)无参数

#define 标识符 字符串

2)有参数

#define 宏名(参数表) 字符串

#define S(a,b) a*b

Area = S(3,2);

注意事项

(1)宏定义后加分号,连分号一起替换.

(2)宏定义必须写在函数之外,作用域为从定义处到程序结束,终止用#undef.

(3)宏定义中若双引号括起来,则不替换.

(4)宏定义允许嵌套,层层替换.

(5)宏定义名习惯是上用大写.

(6)#define PIN1 int* typedef (int*)PIN2; PIN1 a,b;PIN2a,b;意义不同.

(7)宏名与参数表中间不能出现空格#define S (a,b) a*b.

(8)带参宏中只存在符号代换,不存在值传递.

(9)字符串内的形参通常要用括号括起来避免错误#define S(a,b) (a)*(b).

2.文件包含

1)#include“文件名”

先从源文件目录中查找,再到系统指定的其他目录中找.

2)#include

只在系统指定的目录中找.

3.条件编译

1)#ifdef使用格式

#ifdef 标识符

程序段1

#else

程序段2

#endif

功能:当标识符已经被定义过,对程序1进行编译,否则编译程序段2.

2)#ifndef使用格式

#ifndef 标识符

程序段1

#else

程序段2

#endif

功能:当标识符未被定义过,对程序1进行编译,否则编译程序段2.

3)#if使用格式

#if 表达式

程序段1

#else

程序段2

#endif’

功能:当表达式成立,编译程序段1否则编译程序段2.

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180720A1AD1Q00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动