C语言学习总结

开发环境:VMware下安装Ubuntu;使用gedit编辑器。在Windows下使用vc6.0(后面准备使用vs 2017,听说好用)

  1. 在Linux下学会了一些基本的操作指令;
命令功能
ctrl shift +放大终端
ctrl-缩小终端
ls -a -l(-long)查看路径下文件 -查看所有文件 -查看详细信息
clear清屏
cd / ~ -跳转 根目录 当前用户的家目录 上次目录
pwd显示当前所在路径
mkdir创建文件夹
touch创建文件
rm -f -r *删除 -强制删除 -递归删除(删除文件夹)通配符
cp 源文件(路径) 目标文件(路径)复制
mv移动文件或修改名字
tar解压

用su可以到root。

注意:cd的时候有绝对路径和相对路径。cd Desktop/ 是相对路径, cd /root/Desktop/ 是绝对路径。在后面写文件时要尤其注意路径的问题。

在Ubuntu下用gedit写完C语言用gcc编译器编译。
gcc 文件.c -o 可执行文件名
如果不加可执行文件名默认为a.out
调试 https://www.cnblogs.com/inrgihc/articles/7909336.html

数据类型

基本数据类型:字符型,整型,浮点型
字符型:char 1个字节占八位。256种变化情况(0000 0000 ~ 1111 1111)
存放数字时:有符号 (signed) char (默认是有符号的) 最高为代表符号位,范围是-128~127;无符号 unsigned char ,范围是0~255。
存放字符时:(用到ASCII表),存放单个字符使用单引号,如’a’,存放字符串用双引号,如"hello word"。
整型:int 在16位单片机/8位单片机(STC89C51)是16位 ,2个字节;默认是有符号的,unsigned int 是无符号的。long是长整型占4个字节(long int),short是短整型占2个字节(short int)。
浮点型(小数):float 单精度, 4字节(小数点数据有效位后6位);double双精度,8个字节
**构造数据类型:**数组,指针,结构体,共用体,枚举。
输出格式
%d:以十进制格式打印,也是以ASCII码表来打印的。
%x:以16进制格式打印
%o:以8进制格式打印
%f:打印浮点型数据
%c:打印字符型数据
%s:打印字符串
%u:以十进制格式打印无符号变量
%5d:5代表位宽为5,右对齐
%-5d:位宽为5,左对齐
%.3f:打印小数点后3位,第四位进行四舍五入
切记输出是是从右到左进行的。
注意:Windows中是大端存储,低地址存低位,高地址存高位。
51中是小端存储,低地址存高位,高地址存低位。

常量和变量
常量:字符常量:用单引号引起来的字符-- ‘a’ ‘b’ '\n’换行 '\r’回车 ‘\0’空字符。
字符串常量:用双引号引起来的字符–“hello” 等效于’h’ ‘e’ ‘l’ ‘l’ ‘o’ ‘\0’。注意字符串常量以 ‘\0’ 结尾。
常量不能更改。
运算符
在这里插入图片描述在这里插入图片描述
类型转换:自动转换:当两个类型不同的数据进行运算时,自动像高精度转换。
强制类型转换:如

 float a = 1.234;
 int b = 0;
 b = (int)a;

九条语句和32个关键字
C语言的32个关键字和9种控制语句

一、C语言的关键字共有32个,根据关键字的作用,可分其为数据类型关键字、控制语句关键字、存储类型关键字和其它关键字四类。

1 数据类型关键字(12个):
(1) char :声明字符型变量或函数
(2) double :声明双精度变量或函数
(3) enum :声明枚举类型
(4) float :声明浮点型变量或函数
(5) int : 声明整型变量或函数
(6) long :声明长整型变量或函数
(7) short :声明短整型变量或函数
(8) signed :声明有符号类型变量或函数
(9) struct :声明结构体变量或函数
(10) union :声明共用体(联合)数据类型
(11) unsigned :声明无符号类型变量或函数
(12) void :声明函数无返回值或无参数,声明无类型指针(基本上就这三个作用)

2控制语句关键字(12个):
A循环语句
(1) for :一种循环语句(可意会不可言传)
(2) do :循环语句的循环体
(3) while :循环语句的循环条件
(4) break :跳出当前循环
(5) continue :结束当前循环,开始下一轮循环
B条件语句
(1)if: 条件语句
(2)else :条件语句否定分支(与 if 连用)
(3)goto :无条件跳转语句
C开关语句
(1)switch :用于开关语句
(2)case:开关语句分支
(3)default:开关语句中的“其他”分支
D返回语句
return :子程序返回语句(可以带参数,也看不带参数)

3 存储类型关键字(4个)
(1)auto :声明自动变量 一般不使用
(2)extern:声明变量是在其他文件正声明(也可以看做是引用变量)
(3)register:声明积存器变量
(4)static :声明静态变量

4 其它关键字(4个):
(1)const :声明只读变量
(2)sizeof:计算数据类型长度
(3)typedef:用以给数据类型取别名(当然还有其他作用
(4)volatile:说明变量在程序执行中可被隐含地改变

二、C语言中的9中控制语句
goto语句:无条件转向;
if语句:判断语句;
while循环语句;
do-while语句:先执行循环体,然后判断循环条件是否成立. 之后继续循环;
for语句:循环,可替代while语句; 只是用法不同;
break语句跳出本层的循环;(只跳出包含此语句的循环)
continue语句:继续(一般放到循环语句里,不再执行它下面的语句,直接跳到判断语句例:for语句,就直接跳到第二个分号处,while语句,就直接跳到while()的括号里;
switch语句:多相选择;
return语句:返回;

三.C语言运算符(34个)
一、算术运算
C语言一共有34种运算符,包括常见的加减乘除运算。
①. 加法:+ 还可以表示正号
②. 减法:- 还可以表示负号
③. 乘法:* 非数学意义上的X
④. 除法:/ 注意1/2的值为0而非0.5
⑤. 取余(模运算):两个整数相除之后的余数(注意两边都必须是整数,带符号只和左值有关)
注意点:
①. Int a=10.8;//数据精度丢失警告。结果为10——自动类型转换
②. Int a=(int)10.8;//无警告。把10.8强制转换为整型——强制类型转换
③. Double c=10.6+6//结果为16.600000。在计算机中,拿两个数值进行运算,则运算符两边的数值需要类型相同,如果不同则进行自动类型提升。即把6转为6.000000后再参与运算。
④. 参与运算的两个数是什么类型,那么其结果就是什么类型。
int a=10/3结果为3
double b=10/3结果为3.000000;
double c=10.0/3结果为3.333333。
要求精确值可以进行强制类型转换。double d=(double)3/2把3转换为double类型变为3.000000,之后2进行自动类型提升转变为2.000000参与运算,结果为1.500000。也可以写成3/(double)2。这种情况需要注意与对整体进行强制转换的区别 double e=(double)(3/2)是先计算3/2的值为1再对1进行强制类型转换,结果为1.000000。

二、赋值运算
(一)简单赋值
Int a=10+5;a=b=10;//从右向左,左边不能为常量
(二)复合赋值
a=a+5; => a+=5;
a=a5; => a=5;
a+=56+4; => a=a+(56+4)
提示:预算顺序取决于两点:一是运算符的优先级,二是结合的顺序。

三、自增自减运算
Int a=10;
把a的值加1有四种方法:
①. a=a+1;
②. a+=1;
③. a++;
④. ++a;
简单区分a++和++a。
Int b;
Int a=10;
b=++a; //a11,b11;a先把值加1为11,再赋值给b
b=a++; //a11,b10;a先把值10赋值给b,a自己再加1为11
b=(a++)+(++a); //a110,a212,b22
b=(++a)+(a++); //a1
11,a211,b22
注意:int d=10++;//这种写法是错误的,因为对常量进行自加和自减没有任何意义。

四、Sizeof
作用:用来计算变量,常量或者是一种数据类型所占的内存字节数。
基本形式:sizeof(变量名|常量|数据类型),完成之后返回一个值。
①. Sizeof 变量|常量
②. Sizeof (变量|常量)
③. Sizeof (数据类型)
注意:数据类型一定要用括号括起来,不能写成sizeof 数据类型这样的形式。

五、关系运算符
(一)条件判断
默认情况下。在程序中写出的每一句正确的代码都会被执行,但很多时候我们需要在某个条件成立的情形下才执行某一段代码,如登录操作,这种情况可以使用条件语句来完成。
(二)真假
在C语言中,条件成立称为“真”,条件不成立称为“假”。
C语言规定,任何数值都有真假性,任何非零值都为真,只有0才为假,无布尔类型。
(三)关系比较
关系运算的结果只有两种情况,如果条件成立就为真,值为1,如果条件不成立就为假,值为0。有6种运算符,分别是:(1)< (2)<= (3) > (4) >= (5)== (6)!=
(四)使用注意
①. 和!=优先级相等,其他四个关系运算符的优先级相等,且前者的优先级低于后者。如23>1 应该先计算3>1
②. 关系运算符中,若优先级相同,则“从左往右”结合。如4>3<2,先计算4>3
③. 关系运算符中的优先级小于算术运算符。如3+4>8-2 相当于(3+4)> (8-2)

六、逻辑运算符
逻辑运算的结果只有两个:真(0)和假(1)
①. 与 && 条件1&&条件2 只有的那个条件1和条件2都成立时,才为真否则为假。
②. 或 || 条件1 ||条件2 当条件1或条件2中有一个成立时就为真,都不成立时为假。
③. 非 ! !条件 取反
注意:逻辑运算符在进行运算时,只要能够确定整体的真假性,后面的条件就不再进行而是直接忽略。

Int a=b=10;
Int c=(a>5)&&(++b>=11);//此时a==10,b==11,c==1
Int c=(a<5)&&(++b>=11);//此时a==10,b==10,c==0

提示:在进行逻辑运算时,如果搞不清楚各个符号的优先级,可以使用()。

七、三目运算符
双目:需要两个值参与运算
单目:1个数值参与运算 如!5
三目:需要3个数值参与
格式:条件?数值1:数值2
先判断?前的条件,若条件成立则返回数值1,若条件不成立则返回条件2。
要求比较a和b的值,把数值大的存入到c中 c=a>b?a:b
比较a,b,c三个数的值,把最大的值存入到d中
Int abmax=(a>b)?a:b;
d=abmax>c:abmax:c;

数组

一维数组:a[];

二维数组:a[行长度][列长度] = {{},{}…}

字符数组 char 数组名[数组长度] (=初始化)

#include <stdio.h>
int main()
{
	char str[5]={'C','H','I','N','A'};
	int i = 0;
	for(i=0;i<5;i++)
	{
		printf("%c",str[i]);
	}
	printf("\n");
}

字符串数组 char

#include <stdio.h>
int main()
{
	char str[5]={'C','H','I','N','A'};
	char str1[]={"CHINA"};
	printf("%s\n",str1);
}

这里注意%s他只需要获取首地址就可以把字符串数组打印出来。

char num[] = {'h', 'e', 'l', 'l', 'o'}//长度不确定,因为没有\0
char num[]  = "hello"//长度是6,多了一个'\0'

字符串常用函数:

strcpy() //复制
strcat() //连接
strcmp() //比较
strlen() //长度,在遇到‘\0’的时候结束

算法有冒泡排序。

for(i = 0; i < length; i++)
{
	for(j = 0; j <= length-i; j++)
		if(a[i] > a[j])
		{
			temp = a[i];
			a[i] = a[j];
			a[j] = temp;
		}
}

函数

函数是工程中最小的单位,一个工程从主函数开始到主函数结束,函数的作用是让程序模块化,封装代码,提供统一接口。
使用函数时要注意形参和实参,局部变量和全局变量。
定义一个函数。
数据类型 函数名(形参)//函数头
{
//函数体
}

注意C语言开辟的五大区,堆区,栈区,全局变量区,文字常量区,代码段。

两个关键字:(考试)
static :static 数据类型 变量名;//固定的,修饰全局变量和函数,表示该全局变量或则函数只能在本文件内使用,修饰局部变量表示定义了一个静态变量。
extent:外来的,修饰全局变量和函数,表示该变量或该函数来自外部文件。
例如:extern int num;)使用时要一起编译

指针:指针比较难,所以独立了一个文章。

结构体:不同数据类型变量的集合
有四种定义结构体变量的方法
第一种

struct std
{
	char name[20];
	int id;
	int score;
};    
struct std   student1;

//先定义结构体类型struct std ,再用该类型定义变量
第二种:

struct std
{
	char name[20];
	int id;
	int score;
}student1;
struct std student2;

定义类型的同时定义变量
第三种

struct  
{
	char name[20];
	int id;
	int score;
}student1,student2;

//定义类型的同时定义变量,之后不能用于定义其他变量
第四种

typedef struct std
{
	char name[20];
	int id;
	int score;
}STD;
STD  student1;//等效struct std student1;

结构体定义:

struct std student1 = {"张三",1,80};//正确

struct std student2;
student2 = {"李四",2,60};//错误

student2.id = 2;//int id
student2.score = 60;//int score
strcpy(student2.name,"李四");//student2.name = "李四";正确
student2 = student1;//正确

结构体大小:以四字节对齐。

struct std{
	int a; //4字节
	char b; //1字节,补三个字节变成4
	int c; //4字节
};                      //求字符串的大小,四字节对齐总共12字节

struct std{
	char a; //1字节
	char b; //1字节,两个char型合起来是2,再补2个字节
	int c; //4字节
};                      //求字符串的大小,四字节对齐总共8字节


struct tag
{
	char b;//4
	int a;   //4
	char str[5];//总共是5字节,再补3个是8个
};						//求字符串的大小,四字节对齐总共16字节

//求字符串的大小
http://www.cnblogs.com/smile-812/p/7897187.html

共同体:可以理解为一个特殊的结构体,数据成员共用内存空间
同一块内存可以用来存放几种不同类型的数据,但在某个时刻只能在其中存放一个成员变量。共用体变量中起作用的成员是最后一次存入的数据。在存入一个新的成员后原有的成员的值会被覆盖。共用体变量的长度取决于其成员的最大长度。
结构体变量所占内存的长度是各个成员的总和,每个成员分别占有自己的存储空间。共用体变量所占内存的长度是其最长成员的长度。共用体变量的地址和它的各成员的地址相同。

union share
{
	int a;
	char str[4];
};

一个整形变量a=0x12345678,打印整形空间每个字节内存放的内容(考题)

#include <stdio.h>
union share
{
	unsigned int a;
	char str[4];
};
union share share1;

int main()
{
	int i;
	share1.a = 0x12345678;
	for(i=0;i<4;i++)
	{
		printf("%-5x",share1.str[i]);
	}
	return 0;
}
--------------------------------------------------------------------------------------
#include <stdio.h>
int main()
{
	unsigned int a = 0x12345678;
	unsigned char *p = (unsigned char *)&a;
	int i;
	for(i=0;i<4;i++)
	{
		printf("%-5x",*(p+i));
	}
	
	return 0;
}

逆序输出的原因是计算机有大端模式和小端模式
大端模式:低地址存放高位,高地址存放低位
小端模式:高地址存放高位,低地址存放低位

枚举:把变量可能出现的结果给一一列举出来

定义格式:枚举类型的定义格式为:
enum <类型名> {<枚举常量表>};

#include <stdio.h>
enum day{monday=1,tuesday,wednesday};
enum day workday; 
int main()
{
	scanf("%d",&workday);
	switch(workday)
	{
		case monday:printf("星期一\n");break;
		case tuesday:printf("星期二\n");break;
		case wednesday:printf("星期三\n");break;
	}
	return 0;
}

文件操作

文件的存储方式有两种:ASCII码存储和二进制存储
在进行输入输出时会运用到系统自动开的流来进行输入输出。

stdin标准输入
stdout标准输出
stderr标准错误

写入时是先将数据写到缓冲区,当缓冲区满了或遇到回车才会被写入磁盘。
输出数据时先放在输出缓存区中遇到一定条件的时候才会被输出。

FILEL:是一个给定的不能改变的重定义后的结构体类型。

typedef struct
{
	char *_ptr;        //文件输入的下一个位置
	int _cnt;        	//当前缓冲区的相对位置
	char *_base;	 //指基础位置(即是文件的其实位置)
	int _flag;   		 //文件标志
	int _file;    		//文件的有效性检验
	int _charbuf; 		 //检查缓冲区状况,吐过无缓冲区则不读取
	int _bufsiz;    			//文件的大小
	char *_tmpfname;	 //临时文件名
}FILE

文件打开是,系统自动建立文件结构体,并把指向它的指针返回回来,程序通过这个指针获得文件信息,访问文件。文件关闭时它的文件结构被释放。

在C语言中可以通过一些函数实现对文件的操作。

下面对各个函数进行一一举例解释:
文件打开与关闭:
fclose(fp)//关闭文件
FILE * fopen(char *name, char *mode);//name是文件的名字以及路径,默认是当前目录下;mode是对打开文件进行什么样的操作
r 以只读的方式打开文件 不会新建文件 ,文件必须存在
r+ 以读写的方式打开文件 不会新建文件
w 以只写的方式打开文件 若当前文件存在则清空当前文件,不存在则新建文件
w+ 以读写的方式打开文件 当前文件存在则清空当前文件,不存在则新建文件
a 以追加的方式打开文件 可以新建文件,打开时已只读方式打开,读取时在文件头
a+ 以追加的方式打开文件 可以新建文件,打开时可以读写,读的时候在文件头,写的时候在末尾

#include<stdio.h>
int main()
{
	FILE *fp = NULL;
	fp = fopen("a.txt", "r");
	if(fp == NULL)
	{
		perror("fopen:");//显示打开失败,会输出当前操作的错误原因
		return -1;
	}
	printf("fopen ok\n");
	fclose(fp);//文件关闭
	return 0;
}

文件读写

  • int fgetc(FILE *fp);//单个字符读取,正常读取返回读取到的值,读取到文件结尾返回EOF(-1)
  • int fputc(int c, FILE *fp);//单个字符写入,正常写入返回写入值c,否则返回iEOF(-1)
  • int feof(FILE *fp);//判断文件是否到结尾,没有到结尾返回0,否则返回非0(真)
#include <stdio.h>
//任意输入字符 然后读取出来  fputc  fgetc  feof
int main()
{
	char ch;
	FILE *fp = fopen("1.txt","w+");
	while(ch!='#')
	{
		ch=getchar();//从键盘获取一个字符
		fputc(ch,fp);//写入字符
	}
	fclose(fp);
	fp=fopen("1.txt","r");
	ch=fgetc(fp);//先读取一位在进入循环读取,不然会有乱码
	while(!feof(fp))
	{
		putchar(ch);
		ch=fgetc(fp);//从文件获取字符//顺序不能反,会出现乱码
	}
	printf("\n");
	fclose(fp);
	return 0;
}
  • char *fgets(char *s, int size, FILE *stream);//字符串读取,成功返回字符串地址,将文件获取的size个字节的字符串,存放在s中,失败或到达文件结尾返回NULL

  • int fputs(const char *s, FILE *stream);//字符串写入,成功返回非0值,失败返回EOF(-1)

  • size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);//块读,从文件里一次读写size个字节到ptr中,读取nmemb次;成功返回写入的数据块的元素的个数。失败或者到达文件结尾返回0。

  • size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);//快写,把字符串ptr写入文件中,一次写size字节,写入nmemb次。成功返回写入的字节数,失败或达到文件结尾返回0。

#include<stdio.h>
#include<conio.h>
int main()
{
	char name[30] = "xiaowang, xiaozhao";
	char str[30] = "\0";
    FILE *fp=fopen("01.txt","w+");
    fwrite(name, sizeof(char), sizeof(name)/sizeof(char), fp);//先写输入的字符串,再写输入元素大小,然后是元素个数,接着输入流
	fseek(fp, 0, SEEK_SET);//定位到开头,偏移0相当于不便宜
	fread(str, sizeof(char), 6, fp);//先写输输出的字符串,再写输出元素大小,然后是元素个数,接着输出流
	printf("%s\n",str);
    getch();
    return 0;
}
  • int fscanf(FILE *stream, const char *format, …);//格式化读,从文件里面按照一定的格式读取。
  • int fprintf(FILE *stream, const char *format, …);//格式化写,从文件里面按照一定的格式写入。
#include<stdio.h>
#include<conio.h>
#include<string.h>
int main()
{
	char name[30] = "xiaowang,xiaozhao,xiaosun";
	char str[30] = "nan nan nan nan";
	char string1[30] = "\0";
	char string2[30] = "\0";
    FILE *fp=fopen("01.txt","w+");
    fprintf(fp,"%s %s" ,name, str);//将name 和 str以字符串的形式写入,格式是"%s %s"
	rewind(fp);//将光标移至文件开头
	fscanf(fp, "%s %s", string1, string2);//将文件中的字符串分别赋给string1,string2
	printf("string1 = %s, string2 = %s\n", string1, string2);
	//printf("string1 = %s, string2 = %s\n", strcat(string1, string2);
    //getch();
    return 0;
}
  • int remove(const char *pathname);//删除文件
  • int fseek(FILE *stream, long offset, int whence);//将光标定位到某个位置,offset偏移量,正向左偏,负向右偏,whence参考位置(SEEK_SET 文件开头;SEEK_CUR 当前位置;SEEK_END 文件结尾);成功返回0,失败返回-1
  • long ftell(FILE *stream);//返回当前读写指针的位置,常用来求文件的大小,成功返回文件指针当前位置,失败返回-1;

编译预处理

编译预处理:gcc -E xxx.c -o xxx.i
处理伪指令(#)和特殊的特殊符号
伪指令有:宏定义指令;条件编译指令;头文件包含指令
编译:gcc -S xxx.i -o xxx.s
把预处理玩的文件进行一系列词法分析,语法分析,语义分析以及优化后生成相应的汇编代码文件
汇编 as xxx.s -o xxx.o
汇编器是将汇编代码转变成机器可以执行的命令,每个会变语句对应一条机器指令
链接 gcc xxx.o -o xxx
制定路径下的库文件

宏定义

宏定义是C语言中预处理命令的一种,它允许用一个标识符来表示一个字符串。
#define A B 表示用A 代表B,--------->#define OK 1
在程序中B就完全替换A。
上面是不带参数的宏,还有一种带参数的宏

#define SUM(x,y)  (x+y)//注意在程序中(x+y)与 x+y是不同的

有些类似函数的功能但与函数有些类似,但有不同点在于

带参宏参数函数
处理时间编译时运行时
参数类型预定义
程序长度变长不变
占用存储空间
运行时间不占运行时间调用和返回是占

如果反复调用的函数可以用带参宏来实现

条件编译

#if 表达式
程序1
#else 
程序2
#endif

实现在不同情况下实现使用不同的程序
例如:

#define N 2

#if (N==1)
#include <stdio.h>
int main()
{
	printf("11111\n");
	return 0;
}
#endif

#if (N==2)
#include <stdio.h>
int main()
{
	printf("22222\n");
	return 0;
}
#endif

#if (N==3)
#include <stdio.h>
int main()
{
	printf("33333\n");
	return 0;
}
#endif

当与宏结合时可以对操作系统,GUI等等进行裁剪
防止重复编译

#ifndef _LED_H
#define _LED_H

需要声明的头文件

#endif

位操作

上面对位操作符号已经将过了,下面给几个比较常用的方法。
1、把变量b的第a个位置1 b |= 1<<a
2、把变量b的第a个位置0 b &= 1<<a
3、把变量b的第a个位去反 b ^= 1<<a
任何数与1异或 – 得其取反
任何数与0异或 – 得其本身
后续总结。。。。。更新中
|:位或:任何数或上1结果都为1,或上0为本身,经常用来置1
&:位与:任何数与上0结果都为0,与上1为本身,经常用来置0
个人总结,如有任何问题请联系作者

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值