C语言教程

  • Post author:
  • Post category:其他




C语言教程



C语言结构

#include<stdio.h>                 /*引入头文件*/
int main(void)                  /*一个简单的C程序*/
{
    int number;             /*定义个名字叫做number的变量*/
    number=2014;                /*给number赋一个值*/
    printf("Hello ! I am dotcpp.com\n");    /*像屏幕打印一句话*/
    printf("This year is %d\n",number);
    return 0;
}

预处理语句+主函数



预处理语句

预处理语句主要有三类构成,分别是宏定义(

#define

),文件包含(

#include

)和条件编译(

#if

)。



宏定义(

#define


宏定义相当于定义了一个全局变量,用全局变量来代替变量或者表达式。宏定义包含有参宏和无参宏。

宏定义
#define M (y*y+3*y);//无参宏,作用是指定标识符 M 来代替表达式(y*y+3*y)。
#define M(y) (y*y+3*y);//有参宏
宏调用
#define M(y) (y*y+3*y);//有参宏
int main(){
	M(4);//输出的是4*4+3*4
}


文件包含(include)

(1)另外文件包含后面可以接

<>

或者

“”

,里面来包含要引入的文件(以下两种方式都是可以的),文件包含的作用是引入指定文件的所有内容。

#include "stdio.h"
#include <stdio.h>

尖括号表示在包含文件目录中去查找,而双引号则表示首先在当前的源文件目录中查找, 若未找到才到包含目录中去查找。

(2)一个 include 命令只能指定一个被包含文件,若有多个文件要包含,则需用多个 include 命令。

(3)文件包含允许嵌套,即在一个被包含的文件中又可以包含另一个文件。



条件编译(

#if


条件编译存在3种形式

第一种形式:

#ifdef 标识符 
程序段 1 
#else 
程序段 2 
#endif 


如果标识符被预定义过,则执行程序段1,否则执行程序段2。如果程序段2为空,则else可以不写。

#ifdef 标识符 
程序段 
#endif 

第三种形式:

#ifndef 标识符 
程序段 1 #else 
程序段 2 #endif 


如果标识符没有被预定义过,则执行程序段1,否则执行程序段2。

第三种形式:

#if 常量表达式 
程序段 1 #else 
程序段 2 #endif 


如果常量表达式为真,则执行程序段1,否则执行程序段2。



其它预处理指令

1.

#error

:强制停止编译。

2.

# error-message

:遇到#error 指令时,显示错误信息和作者预先定义的其它内容。

3.

# line

:改变

__LINE__



__FILE__

的内容,

__LINE__



__FILE__

都是编译程序中预定义的标识符。

4.

# pragma

:允许由此向编译程序传入各种指令。



C语言的数据类型



基本数据类型

C语言的基本数据类型为:整型、字符型、浮点型。分别是:

short



int



long



char



float



double

等的有符号和无符号类型,有符号一般包含正负数,而无符号一般指的是正数。

下面列出了在32位操作系统下 常见编译器下的数据类型大小及表示的数据范围:

在这里插入图片描述



关键字

为了实现相应的功能,c语言中提供了一些关键字,在定义变量的时候注意不要和这些关键字重名,以下是c语言中的32个关键字。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rWdnzkmQ-1624429938542)(C:\Users\y\AppData\Roaming\Typora\typora-user-images\image-20210617194016077.png)]



C语言中的基本输入和输出



字符输出函数

putchar


putchar

函数是字符输出函数,其功能是在终端(显示器)输出单个字符。

int putchar(int ch);

ch表示要输出的字符内容,返回值作用为:如果输出成功返回一个字符的

ASC

码,失败则返回

EOF

即-1。

putchar(‘A’); /*输出大写字母A */putchar(x);  /*输出字符变量x的值*/putchar(‘\n’); /*换行*/


字符输入函数

getchar


getchar

函数的功能是接收用户从键盘上输入的一个字符。

char c;  /*定义字符变量c*/c=getchar(); /*将读取的字符赋值给字符变量c*/


格式化输出函数

printf


printf

函数叫做格式输出函数,其功能是按照用户指定的格式输出内容。

printf

函数的格式为:

printf(“格式控制字符串”,输出表项); 

格式控制字符串有两种:格式字符串和非格式字符串。非格式字符串在输出的时候原样打印;格式字符串是以%打头的字符串,在”%”后面跟不同格式字符,用来说明输出数据的类型、形式、长度、小数位数等。


格式字符串的形式为: % [输出最小宽度] [.精度] [长度] 类型

以下是格式字符串的类型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oJ7491oJ-1624429938543)(C:\Users\y\AppData\Roaming\Typora\typora-user-images\image-20210618093532155.png)]



printf

中的修饰符

*

,它的作用是由程序来控制宽度。

/*使用可变宽度输出字段*/#include<stdio.h>int main(void){    unsigned width,precision;    int number = 256;    double weight = 25.5;    printf("Please input number's width:\n");    scanf("%d",&width);    printf("The number is: %*d\n",width,number);    printf("Then please input width and precision:\n");    scanf("%d %d",&width,&precision);    printf("Weight = %*.*f\n",width,precision,weight);    return 0;}


格式化输入函数

scanf


scanf

函数称为格式输入函数,即将输入的内容格式化。

scanf

函数的调用的一般形式为:

scanf(“格式控制字符串”,输入项地址列表); 

输入项地址列表由地址运算符

&

后跟变量名组成。


scanf

函数中格式字符串的构成与

printf

函数基本相同,但使用时有几点不同.

(1) 格式说明符中,可以指定数据的宽度,但不能指定数据的精度。例:

float a;scanf(%10f”,&a);  //正确scanf(“%10.2f”,&a); //错误

(2) 输入

long

类型数据时必须使用

%ld

,输入

double

数据必须使用

%lf



%le


scanf()

函数所用的转换说明符与

printf()

所用的几乎完全相同。主要区别在于

printf()



%f、%e、%E、%g、%G

同时用于

float

类型和

double

类型,而

scanf()

只是把他们用于

float

类型,而用于

double

类型时要求使用l(字母l)修饰符。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-98aGwWkG-1624429938545)(C:\Users\y\AppData\Roaming\Typora\typora-user-images\image-20210618094724252.png)]


修饰符*在

scanf中()

的用法是使函数跳过相应的输入项目。

/*用*跳过scanf接收的数字*/#include<stdio.h>int main(void){        int num;        printf("Please enter three number:\n");        scanf("%*d %*d %d",&num);        printf("The last number is %d\n",num);        return 0;}


scanf()

的返回值,

scanf()

函数返回成功读入的字符的个数,如果没有读取字符,则返回

0



运算符和表达式



基本运算符


赋值运算符


数学匀速符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uL6ngc4F-1624429938546)(C:\Users\y\AppData\Roaming\Typora\typora-user-images\image-20210618095435041.png)]

#include<stdio.h>int main(){        int a=20;        int b=5;        int c=6;        printf("a = %d b = %d c = %d\n",a,b,c);        printf("a + b = %d\n",a+b);        printf("a - c = %d\n",a-c);        printf("a * b = %d\n",a*b);        printf("a / c = %d\n",a/c);        printf("a %% c = %d\n",a%c);/*两个%才会输出一个%*/        return 0;}



sizeof

运算符


sizeof()

运算符的作用是返回一个数据类型和变量的字节大小。

#include<stdio.h>int main(){        int n=0;        int intsize = sizeof(int);        printf("int sizeof is %d bytes\n",intsize);        return 0;}


三目运算符

三目运算符的一般形式如下:

表达式1?表达式2:表达式3

如果表达式

1

为真,则执行表达式

2

,否则执行表达式

3



表达式和语句

每个表达式以分号结尾,表示一个语句。



C语句和程序流



选择结构

选择结构有单选择、双选择和多选择3种形式。

单选择

if(表达式) /*若条件成立则实行花括号里的语句,反之则不执行*/ {     //语句 }

双选择

if(表达式) /*若表达式成立则执行语句1,否则执行语句2*/ {     //语句1 } else {     //语句2 }

多选择

if(表达式) /*若表达式成立则执行语句1,否则执行语句2*/ {     //语句1 } else {     //语句2 }

多分支选择结构除了

else if

之外,C语言还提供了

switch

的结构。


switch

的执行过程是首先计算表达式的值,按照表达式的值执行相应的语句。

switch(表达式) /*首先计算表达式的值*/ {     case 常量表达式1:语句1;     case 常量表达式2:语句2;     case 常量表达式3:语句3;     // … …     case 常量表达式n:语句n;     default:语句n+1; }
switch(value){    case 1:printf("one");break;    case 2:printf("two");break;    case 3:printf("three");break;    default:printf("other");break;}


循环结构

C语言提供三种循环结构,分别为

while

循环,

do while

循环和

for

循环


while

循环,满足表达式则进入循环。

while(表达式) {     循环体语句 } 
while(i++<10){    printf(“count %d ”,i);}


do while

循环,先循环一次,然后判断是否满足表达式,满足表达式则继续循环。

do {     循环体语句 }while(表达式); 
do{    printf("count %d",i);}while(i<20);

for循环,确定循环次数的循环。

for(初始化表达式;判断表达式;更新表达式) {     循环体语句 } 
for(i=0;i<100;i++){    printf("i count is %d\n",i);}



函数



函数的定义

c语言中最简单的函数是

main()

主函数。

函数的定义通常包含以下内容: 返回值类型 函数名(形参表说明) /*函数首部*/ { 说明语句 /*函数体*/ 执行语句 } 

1.函数的返回类型不能是数组,而是基本数据类型。

2.函数名不能和C语言中的关键字同名。

根据函数定义的一般形式,可以定义一个最简单的函数:

int main(){	return 0;}


函数的调用


变量的存储类型

C语言中的变量可以分为两种类型,及全局变量和局部变量。

C 语言中定义了 4 种类型的变量,即自动变量、外部变量、静态变量和寄存器变量,它们存储的位置有些不同。


自动变量

自动变量指的是在方法中定义的,用

auto

关键字修饰的变量。

int fun(int a){    auto int b,c=3; /*定义 b,c 为自动变量*/}


外部变量

外部变量指的是在方法外面定义的全局变量。


静态变量

静态变量指的在方法中定义的,用

static

关键字修饰的变量,静态变量在方法执行结束后不会消失。


寄存器变量

寄存器变量指的是在方法中定义的变量,用

register

关键字修饰的变量,

register

指的是存储在

CPU

寄存器中。

注意以下几点:

(1)只有局部自动变量和形式参数可以作为寄存器变量。

(2)一个计算机系统中的寄存器数目有限,不能定义任意多个寄存器变量。

(3)不能使用取地址运算符“&”求寄存器变量的地址。



数组



一维数组的定义和使用
类型说明符 数组名 [常量表达式]; 
int a[100];     //定义一个数组名为a,存储100个int类型的数组,其元素分别是a[0]~a[99]float b[10];    //数组名为b的,存储10个float类型的数组,其元素分别是b[0]~b[9]char c[256];    //定义一个数组名为c的字符型数组 长度为256,其元素分别是c[0]~c[255]
int a[100]={1,2,3,4,5}; //定义一个整型数组a,前5个元素即赋值为1,2,3,4,5,后95个元素值值全部为0float b[10]={1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9,0.0};  //定义float数组b并对全部float类型的元素都分别赋值char c[256]={'C','l','a','n','g','u','a','g','e'};  //定义一个数组名为c的字符型数组 并对前9个元素进行赋值,其余元素全部为'\0'


二维数组的定义和使用

二维数组的定义:

类型说明符 数组名[行数][列数]; 
int a[3][4];/*定义一个整形二维数组a,有3行4列共12个元素分别为:a[0][0] a[0][1] a[0][2] a[0][3]a[1][0] a[1][1] a[1][2] a[1][3]a[2][0] a[2][1] a[2][2] a[2][3]*/char arry[10][10];//定义一个字符型二维数组arry,有10行10列,依次为arry[0][0]~arry[9][9]供100个元素
int a[3][4]={{1,2,3,4},{10,20,30,40},{100,200,300,400}};//定义一个三行四列的二维数组,按行赋值int a[3][4]={1,2,3,4,10,20,30,40,100,200,300,400};//定义一个三行四列的二维数组并对其中的12(3*4)个元素进行赋值


字符数组和字符串

字符数组的定义和使用

char c[10];char c[6]={'c', ' h ', 'i', 'n', 'a' , '\0' };

对字符数组的各个元素逐个赋值后,各元素的值为:

c[0]= 'c',c[1]= 'h',c[2]= 'i',c[3]= 'n',c[4]= 'a',c[5]= '\0';

字符数组也可采用字符串常量的赋值方式,例如:

char a[]={"china"};



指针



地址与指针

在我们最广泛使用的32位操作系统下,变量的内存地址就是是从

0~4,294,967,295

之间的一个编号。在C语言中可以通过地址运算符

&

来得到变量的地址。

#include<stdio.h>int main(){           int i;           int a[10]={1,2,3,4,5,6,7,8,9,0};           char b[10]={'c','l','a','n','g','u','a','g','e'};           for(i=0;i<10;i++)           {                       printf("int Address:0x%x,Value:%d\n",&a[i],a[i]);          }           printf("\n");           for(i=0;i<10;i++)           {                       printf("char Address:0x%x,Value :%c\n",&b[i],b[i]);           }           return 0;}


指针的定义和使用

指针和地址一样,代表的是在逻辑内存中的一个编号,但是地址是一个常量,而指针所对应的地址值是一个变量。

对指针变量定义的一般形式为:

类型说明符 *变量名; 
#include<stdio.h>int main(){        int num=2014;        int *p=&num;        printf("num Address = 0x%x,num=%d\n",&num,num);        printf("p = 0x%x,*p=%d\n",p,*p);        printf("%d\n",*&num);        return 0;}


注意:在32位操作系统下,任何类型的指针变量都占四个字节!

#include<stdio.h>struct INFO{        int a;        char b;        double c;};int main(){        int *p;        char *p1;        float *p2;        double *p3;        struct INFO *p4;   //struct INFO类型为结构体类型 我们将会在后面的章节中讲解        void *p5;        printf("int point size is :%d\n",sizeof(p));        printf("char point size is :%d\n",sizeof(p1));        printf("float point size is :%d\n",sizeof(p2));        printf("double point size is :%d\n",sizeof(p3));        printf("struct point size is :%d\n",sizeof(p4));        printf("void point size is :%d\n",sizeof(p5));        return 0;}


数组与指针

由于数组中的每一个元素都是变量,因此可以使用指针方式访问数组中的元素。对一个指向数组元素的指针变量的定义和赋值方法,与指针变量相同。

int a[10]; /*定义 a 为包含 10 个整型数据的数组*/int *p; /*定义 p 为指向整型变量的指针*/p=&a[0]; /*把 a[0]元素的地址赋给指针变量 p*/

C 语言规定,数组名代表数组的首地址,也就是第 0 号元素的地址。因此:

p=a; /*等价于 p=&a[0]; */int *p=a; /*等价于 int *p=&a[0]; */

对于执行首地址值的指针,

p+i

就是第

i

个元素的地址值,而

*(p+i)



*(a+i)

就是第

i

个元素的值。

引入指针变量后,就可以用以下两种方法来访问数组元素:

(1)下标法:即用

a[i]

形式访问数组元素。

(2)指针法:即用

*(p+i)



*(a+i)

形式,用间接访问的方法来访问数组元素。

#include<stdio.h>int main(){        int i;        int a[10]={1,2,3,4,5,6,7,8,9,0};        int *p=a;        for(i=0;i<10;i++)        {                printf("P Value:%d   a Value :%d\n",*(p++),*(a+i));        }        printf("\n");        return 0;}


字符串与指针

可以用字符串常量对字符指针进行初始化

char *str = "www.dotcpp.com" ;char string[ ] = "Welcome to dotcpp.com";

这是对字符指针进行初始化。此时,字符指针指向一个字符串常量的首地址。

字符串指针和字符串数组两种方式都可以访问字符串,但它们有着本质的区别:

字符指针

str

是个变量,可以改变

str

使它指向不同的字符串, 但不能改变

str

所指向的字符串常量的值。 而

string

是一个数组,可以改变数组中保存的内容

指针变量不能改变字符的值,只能改变地址值,而数组可以改变字符串的值。

#include<stdio.h>int main(){        char *str = "www.dotcpp.com";        char string[]="Welcome to dotcpp.com";        str[0]='C'; //试图修改str指向的常量区的字符串内容        return 0;}



复合结构



结构体的定义和使用

结构体就像

java

中类的概念,另外结构体的定义说明了它的组成成员,以及每个成员的数据类型。定义一般形式如下:

struct 结构类型名 { 数据类型 成员名 1; 数据类型 成员名 2; ...... 数据类型 成员名 n; }; 

和其他类型的变量一样,结构变量也可以进行初始化。结构初始化的一般形式如下:

struct 结构类型名 结构变量 = { 初始化数据 1, ...... 初始化数据 n };
#include<stdio.h>  #include<string.h>  struct _INFO  {          int num;          char str[256];  };  int main()  {          struct _INFO A;          A.num = 2014;          strcpy(A.str,"Welcome to dotcpp.com");          printf("This year is %d %s\n",A.num,A.str);          return 0;  }


结构体的高级使用

指向结构体变量的的指针叫做结构体指针变量,结构体指针变量中的值是所指向的结构变量的首地址,通过结构指针即可访问该结构变量.

体指针变量定义的一般形式为:


struct

结构类型名 *结构指针变量名



共用体的定义和使用

将不同类型的变量存储到同一个内存单元中,这几个变量共同占用同一段内存结构,这种结构称为共用体

union

。共用体的一般定义 形式为:

union 共用体名 { 数据类型 成员名 1; 数据类型 成员名 2; ...... 数据类型 成员名 n; }变量名表列; 

只有先定义了共用体变量,才能在后续的程序中引用它。不能直接引用共用体变量,而只能引用共用

体变量中的成员。引用方法如下:

共用体变量名.成员名

共用体变量中起作用的成员是最后一次存放的成员,在存入一个新成员后,原有成员就失去作用。 共用体变量的地址和它的各成员的地址都是同一地址。

#include<stdio.h>union INFO{        int a;        int b;        int c;};int main(){        union INFO A;        A.a=1;        A.b=2;        A.c=3;        printf("a:%d\n",A.a);        printf("b:%d\n",A.b);        printf("c:%d\n",A.c);        return 0;}

不能对共用体变量名赋值,也不能企图引用变量名来得到一个值,并且,不能在定义共用体变量时对 它进行初始化。

不能把共用体变量作为函数参数, 也不能是函数返回共用体变量, 但可以使用指向共用体变量的指针。 共用体类型可以出现在结构体类型的定义中,也可以定义共用体数组。反之,结构体也可以出现在共 用体类型的定义中,数组也可以作为共用体的成员。



使用typedef定义类型

在C语言中,除了结构体和共用体这种自定义的数据类型外,还可以类型说明语句 typedef 定义新的类型来代替已有的类型。typedef 语句的一般形式是:

typedef 已定义的类型 新的类型; 
typedef int INTEGER; /*指定用 INTEGER 代表 int 类型*/typedef float REAL; /*指定用 REAL 代表 float 类型*/

在具有上述 typedef 语句的程序中,下列语句就是等价的:

int i, j; /*与 INTEGER i, j;*/float pi; /*与 REAL pi;*/

类型说明语句

typeof

的最常用的作用是给结构体变量重命名

#include<stdio.h>#include<string.h>typedef struct _INFO{        int num;        char str[256];}INFO;int main(){        struct _INFO A;        INFO B;    //通过typedef重命名后的名字INFO与struct _INFO完全等价!        A.num = 2014;        strcpy(A.str,"Welcome to dotcpp.com");        B=A;        printf("This year is %d %s\n",A.num,A.str);        printf("This year is %d %s\n",B.num,B.str);        return 0;}

可以看到typedef可以为关键词改名,使改名之后的INFO类型等价于

struct _INFO

类型,让我们在定义这种结构类型时更方便、省事。



文件操作



C语言实现文件读写

C语言中所定义的变量都是存储在内存中的,内存中的数据关机就会消失。那C语言是如何读取磁盘中的文件的呢?C语言读写磁盘中的文件一般有3个步骤:

1.打开文件

2.读写文件

3.关闭文件。

其中上面每一步操作都需要通过函数所提供的接口来实现。打开文件所使用的函数是

fopen

函数,读写文件所使用的函数是

fprintf



fscanf

或者

fwrite



fread

或者

fputs



getss

,每组函数都是写和读文件。

fprintf



fscanf

的作用是向文件中输入和输出。

关闭文件所使用的函数是

fclose

函数,它的作用是切断文件指针和文件的关联。如果未关闭文件,就对文件进行读写操作,则会出现“正在被使用,无法修改”的提示。



打开文件

fopen

函数的用法


fopen

函数的作用是打开文件,获取文件指针。函数原型是:

FILE *fopen(const char *filename, const char *mode);

该函数的两个参数是字符类型的文件名和字符类型的文件操作模式,函数的返回值是FILE类型的文件指针,打开失败则返回NULL。以下是常见的文件操作模式。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zoLj7s0V-1624429938548)(C:\Users\y\AppData\Roaming\Typora\typora-user-images\image-20210621124325171.png)]

FILE结构体类型的定义如下:

typedef struct {   int level;           /* fill/empty level of buffer */   unsigned flags;        /* File status flags */   char fd;            /* File descriptor */   unsigned char hold;      /* Ungetc char if no buffer */   int bsize;           /* Buffer size */   unsigned char _FAR *buffer; /* Data transfer buffer */   unsigned char _FAR *curp;  /* Current active pointer */   unsigned istemp;      /* Temporary file indicator */   short token;          /* Used for validity checking */ } FILE; 

比如,如果我们现在想打开一个D盘根目录下的

123.txt

,并且想读出该文件里的数据,那么我们可以这样写:

FILE *fp;fp=fopen("d:\\abc.dat","r")//后面通过fp指针开始读文件

值得说明的是

1.文件路径可以是绝对路径,也可以是相对路径,该文件的目录是绝对路径,因此这样写,如果不写盘符比如

abc.dat

则表示相对路径,表示与本程序同目录下。

2.路径中的反斜杠虽然只有一个,但这里打了两个,原因在于C语言字符串中对反斜杠要当作转义字符处理,因此要用两个反斜杠才能表示一个。

3.一旦以r也就是只读的方式打开文件,后面则不允许写数据,否则会出错,一定要保持一致!



写文件

fprintf

函数的用法

如果打开模式是写,那么可以用

fprintf

函数来进行写,下面来介绍

fprintf

函数,它的原型是:

int fprintf (FILE* stream, const char*format, [argument])

该函数比

printf

函数多了一个参数,该参数是文件指针。该函数的返回值是一个整数,写入成功返回的是写入字符的格式,写入失败返回的是一个负数。以下是常见的格式化字符串类型:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VCUN6rIK-1624429938549)(C:\Users\y\AppData\Roaming\Typora\typora-user-images\image-20210621125125286.png)]



读文件

fscanf

函数的用法

从文件里读数据所使用的是

fscanf

函数,它的函数原型如下:

int fscanf(FILE *stream, char *format[,argument...]);

第一个参数是文件指针,表示读取的文件目标,其余参数和

scanf

一样,按照相应的格式进行读取,返回值表示读取数据的字节数。比如:

char str[100];fscanf(fp,"%s",str);

上诉代码表示的是从

fp

所指向的文件中进行读数据,与空格或换行结束,将结果保存到

str

数组中。

更多

scanf

的格式如下表:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ROKyJqc0-1624429938550)(C:\Users\y\AppData\Roaming\Typora\typora-user-images\image-20210621125708457.png)]



写文件

fwrite

函数的用法

写文件的是

fwrite

函数,它的函数原型如下:

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)

这个函数的参数有4个:

第一个是写入数据的头指针。

第二个是每个写入元素的大小,单位是字节。

第三个参数是个数。

第四个参数是文件指针,表示往哪里写。

该函数执行成功返回写入元素的个数,写入失败显示错误。

#include<stdio.h> int main (){   FILE *fp;      char str[] = "www.123.com";    fp = fopen( "123.txt" , "w" );      fwrite(str, sizeof(str) , 1, fp );    fclose(fp);     return(0);}

以上代码的意思是将

str

字符串写入到

123.txt

文件中。



读文件

fread

函数的用法


fread

函数的作用是从文件里读内容到程序中,它的返回值表示读取元素的个数,与

nmemb

一致表示读取成功,否则失败,

fread

函数原型如下:

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)

这个函数有4个参数:

第一个参数

ptr

表示盛放内容的首地址

第二个参数

size

表示每个元素的大小,单位还是字节

第三个参数

nmem

表示要读取的元素个数

第四个参数

stream

表示的是文件指针,即从哪个文件中读取

#include <stdio.h>#include <string.h>  int main(){   FILE *fp;   char buffer[100];     /* 首先打开文件,读写都可以,假设文件中已经有内容为www.dotcpp.com */   fp = fopen("dotcpp.dat", "w+");      /* 读取并显示数据 */   fread(buffer, 1, 15, fp);   printf("%s\n", buffer);   fclose(fp);       return(0);}


关闭文件

fclose

函数的用法


fclose

函数的作用是关闭文件,切断文件指针和文件之间的联系,返回值为整型,成功关闭则返回0,失败则返回-1。它的函数原型如下:

int fclose( FILE *fp );



位运算



位运算

位运算包含<<(左移)、>>(右移)、~(按位取反)、&(按位与)、|(按位或)、^(按位异或) 共六种运算符。

功能如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CWeihnlF-1624429938550)(C:\Users\y\AppData\Roaming\Typora\typora-user-images\image-20210621142034533.png)]



移位运算符

<<和>>分别是C语言中的左移和右移运算符,如表达式13<<2,它的运算过程为:13用二进制表示为,0000 0000 0000 0000 0000 0000 0000 1101,那么向左移两位,右侧补0,则变为0000 0000 0000 0000 0000 0000 0011 0100 换成十进制即变为52。

#include<stdio.h>int main(){    int a,b;    a=13<<2;    b=25>>3;    printf("a=%d,b=%d\n",a,b);    return 0;}

运行结果如下:

a=52,b=3

移位运算符的作用:



1.左移N位的本质是乘以2的N次方



2.右移N位的本质是除以2的N次方



&按位与运算符

按位与运算符&,它的使用规则是同1则为1,不同1则为0。如3&5,运算过程如下:

3 0000 0000  0000 0000  0000 0000  0000 00115 0000 0000  0000 0000  0000 0000  0000 0101& ------------------------------------------  0000 0000  0000 0000  0000 0000  0000 0001
#include<stdio.h>int main(){    int a;    a=3&5;    printf("a=%d\n",a);    return 0;}

运行结果如下:

a=1


按位与运算符的作用:

  1. 清零

    我们可以对某一个数与0进行按位与运算,由于两个位都为1才为1,因此最终全部位都变为0,起到清零的作用

  2. 取指定位

    如某些存储场景下,“第1

    3位表示xxxx“”,我们需要取出1

    3位,则可以让原数值与数字7进行按位与运算,得到的结果即是原数值的1~3位的值。

  3. 判断奇偶

    可以发现,数字的奇偶取决于二进制位的最低一位是1还是0,因此只需要与1按位与运算,判断是1是0即可得知奇偶。



|按位或运算符

|按位或运算符的作用规则是有一个为1结果即为1。如8|7的运算过程可以如下表示:

8 0000 0000  0000 0000  0000 0000  0000 10007 0000 0000  0000 0000  0000 0000  0000 0111& ------------------------------------------  0000 0000  0000 0000  0000 0000  0000 1111
#include<stdio.h>int main(){    int a;    a=8|7;    printf("a=%d\n",a);    return 0;}
a=15

按位或运算符的作用:

  1. 对一个数字的指定位,置为1

    如“某个数字的第七位”表示开关,原先是0,需要改为1的状态,即可以将这个数字与64按位或,即可得到第七位变为1,其余位的值依旧不变。



^按位异或运算符

^表示按位异或运算符,它的作用规则是不同则为1,反之为0

例如15和16进行异或运算,运算过程如下:

15 0000 0000  0000 0000  0000 0000  0000 111116 0000 0000  0000 0000  0000 0000  0001 0000^ ------------------------------------------   0000 0000  0000 0000  0000 0000  0001 1111
#include<stdio.h>int main(){    int a;    a=15^16;    printf("a=%d\n",a);    return 0;}

运算结果为:

a=31

异或运算符的作用:

  1. 指定位数的翻转

    如想对某个数字的低4位进行翻转,则可以将这个数字与15(二进制为00001111)进行按位异或运算,既可以将原数字的低四位进行翻转,即高四位不变,低四位0变1,1变0

  2. 与0异或还是原值

    大家可以自行实验,一个数字与0进行异或,结果还是原值

  3. 交换两个数字

    除了之前我们学习交换两个数字需要第三个变量做中介之外,如今可以通过异或运算进行,代码如下:

    #include<stdio.h>int swap(int *a,int *b){    if (*a!=*b)    {        *a=*a^*b;        *b=*b^*a;        *a=*a^*b;    }    return 0;}int main(){    int a=5;    int b=5;    swap(&a,&b);    printf("a=%d b=%d\n",a,b);    return 0;}
    

    可以看到原先a为3,b为5,运行后得出:

    a=5 b=5
    


~取反运算符

~取反运算符,是对数值的二进制位进行取反,它的作用规则是0变为1,1变为0。

~1=0~0=1
#include<stdio.h>int main(){    unsigned int a=1;    printf("~a=%u\n",~a);    return 0;}

运算结果如下:

~a=4294967294




版权声明:本文为qq_40410560原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。