学习C语言基础知识已经两周了,我现在将这一阶段掌握的知识进行一次系统的总结:
一、数据结构
(一)基本数据类型
1.函数
int
int值域:(4字节 == 32bit)
unsigned int :(0~2^32-1)
0000 0000 0000 0000 0000 0000 0000 0000------1111 1111 1111 1111 1111 1111 1111 1111
signed int:(-2^31~ 2^31-1)
1000 0000 0000 0000 0000 0000 0000 0000-----0111 1111 1111 1111 1111 1111 1111 1111
short
short值域:(2字节== 16bit)
unsigned short:(0~2^16-1)
0000 0000 0000 0000-----------1111 1111 1111 1111
signed short:(-2^15~2^15-1)
1000 0000 0000 0000-----------0111 1111 1111 1111 (1000 0000 0000 0000-------1 111 1111 1111 1111----------1 1000 0000 0000 0000-------(-2^15))
long
由于太长就不列出来了
类型 | 含义 | 32位编译器中大小(一般) | 64位编译器中大小(一般) | 最小值(32位) | 最大值(32位) |
---|---|---|---|---|---|
bool(stdbool.h) | 布尔类型 | 1byte | 1byte | false | true |
char | 单个字符 | 1byte | 1byte | -27 | 27-1 |
short | 短整形 | 2byte | 2byte | -215 | 215-1 |
int | 整形 | 4byte | 4byte | -231 | 231-1 |
long | 长整形 | 4byte | 8byte | -231 | 231-1 |
long long | 长整形 | 8byte | 8byte | -263 | 263-1 |
float | 单精度浮点数 | 4byte | 4byte | -2127 | 2128 |
double | 双精度浮点数 | 8byte | 8byte | -21023 | 21024 |
long double | 扩展精度浮点数 | 12byte | 16byte | -216383 | 216384 |
char* | 字符常量或字符串常量 | 4byte | 8byte | 无意义 | 无意义 |
这里要注意long和char*在32位和64位编译器中的大小不同。
2.实型
小数
浮点型的存储方式与整数的存储方式是不一样的
浮点型的存储方式决定了他不能准确的表示一个数,只能近似的表示一个数
float
float(单精度浮点数):有效数字的位数:6~7位:%f
double
double(双精度浮点数):有效数字的位数:15~16位:%lf
%f和%lf:默认输出小数点后6位
%.nf: 保留小数点后n位进行输出
指数
例·:1e+4
3.字符
char
char------1字节 == 8bit
值域范围:
Unsigned char: (0~255)
0000 0000------------------1111 1111
Signed char :(-128~127)
1000 0000-------------0111 1111
(补码:1000 0000--------- 反码:1 111 1111----------------原码:1 1000 0000 -128)
考点:(超范围)(如果超范围了,则转圈去数)
unsigned char c = 260;
printf(“%d\n”,c);-----(4)
1 0000 0100
signed char a = 130;
printf(“%d\n”,a);-----(-126)
1000 0010---------------1111 1101------------------1111 1110-----------(-126)
字符串
<1>.用双引号引起来称为叫字符串常量 如: "helloworld"
<2>.字符串本身表示的是第一个字符的首地址 char * pc=“helloworld”;
<3>.字符串常量中的内容是不能被修改的
<4>.字符串常量本身有一个'\0'结束标志
(二)复合数据类型
1.指针
定义
指针是一种保存地址(&i)的数据类型
//定义一个int变量
int i=5;
//定义一个指向int的指针
int * pi;
pi=&i; //pi指向i float f=12.5 pi=&f;(×)
//定义一个指向int的指针的指针
int ** ppi;
ppi=π //ppi=&i(×)
指针的相关操作
指针相关的运算
指针+数值 pc+1 , pc++ (指针自增)
指针+数值
int * pi=0x100;
int n=2;
int * pt=NULL;
0x100 2
pt= pi + n
=0x100+2*sizeof (int)
=0x108
指针-指针
int * pi=0x100, *pt=0x108,假设n=pt-pi 求n=?
0x108 - 0x100
n= pt - pi
n*sizeof (int)=pt-pi;
n=(pt-pi)/sizeof (int)
2.函数
变量
全局变量:定义在函数体外部的变量 作用域:自定义开始到文件结束,一般默认为0
局部变量:定义在函数体内部的变量 作用域:自定义开始到最近的}结束
自定义函数
函数声明
返回值类型 函数名(形式参数列表);
//函数声明
void menu(void); //void 空类型
调用函数
变量名=函数名(实际参数列表);
变量名=函数名(实际参数1,实际参数2,实际参数3);
//函数调用
menu();
函数定义
返回值类型 函数名(形式参数列表)
{
函数体
return 变量名; //若无返回值该句话可以省略
}
void menu(void)
{
printf("(+)--------add\n");
printf("(-)--------sub\n");
printf("(*)--------mul\n");
printf("(/)--------div\n");
printf("(#)--------exit\n");
}
实例
//简易计算器
#include<stdio.h>
//带自定义函数
//函数声明
//返回值类型 函数名(形式参数列表);
//编写一子函数,实现菜单
void menu(void); //void 空类型
//函数功能:编写一子函数,实现两个小数求和
//参数有几个类型分别是什么
//返回值类型是什么
float add(float num1,float num2); //形式参数 类型名1 变量名1,类型名2 变量名2
//函数功能编写一子函数,实现两个小数求差
float sub(float num1,float num2);
//函数定义
/*
* 返回值类型 函数名(形式参数列表)
* {
* 函数体
* return 变量名// 若无返回值该句话可以省略
* }
*/
float sub(float num1,float num2)
{
float result=0;
result=num1-num2;
return result;
}
float add(float num1,float num2)
{
float result=0;
result=num1+num2;
return result;
}
void menu(void)
{
printf("(+)--------add\n");
printf("(-)--------sub\n");
printf("(*)--------mul\n");
printf("(/)--------div\n");
printf("(#)--------exit\n");
}
int main(void)
{
float num1=0,num2=0,result=0;
char op='\0';
while(1)
{
printf("请输入两个小数\n");
scanf("%f%f",&num1,&num2);
//函数调用
menu();
printf("请输入选项\n");
//scanf("%*c%c",&op); //%*c表示忽略掉一个字符
getchar(); //专门用来获取字符的函数,putchar()
scanf("%c",&op);
if('#'==op) break;
switch(op)
{
case '+':
//add获得两个小数之和
//函数调用:
//变量名=函数名(实际参数列表);
result=add(num1,num2);
break;
case '-':
result=sub(num1,num2);
break;
case '/':
result=num1/num2;
break;
case '*':
result=num1*num2;
break;
default:
printf("error\n");
}
printf("%.1f %c %.1f= %.1f\n",num1,op,num2,result);
}
return 0;
}
库函数
引入头文件
#include <stdio.h>
调用库函数
变量名=函数名(实际参数列表);
变量名=函数名(实际参数1,实际参数2,实际参数3);
函数和指针关联
#include<stdio.h>
/*
//编写子函数,实现两个数的交换
//返回值类型:void
//参数有两个,int,int
void swap1(int a,int b);
void swap1(int a,int b)
{
int temp=0; 不能交换,子函数的更改不影响main函数
temp=a;
a=b;
b=temp;
}*/
//编写子函数,实现两个数的交换
//返回值类型:void
//参数有两个,int *,int *
void swap2(int *pa,int *pb);
void swap2(int *pa,int *pb)
{
int temp=0;
temp=*pa;
*pa=*pb;
*pb=temp;
}
int main(void)
{
int a=5,b=6;
printf("swap before a=%d b=%d\n",a,b);
// swap1(a,b);
swap2(&a,&b);
printf("swap after a=%d b=%d\n",a,b);
return 0;
}
运行结果:
swap before a=5 b=6
swap after a=6 b=5
字符串中库函数的调用
#include <stdio.h>
#include <string.h>
void menu(void);
void menu(void)
{
printf("1.获得字符串的长度 --------------------------strlen\n");
printf("2.获得特定字符在字符串中第一次出现的地址---strchr\n");
printf("3.比较两个字符串大小-----------------------strcmp\n");
printf("4.将字符串1复制给字符串2-------------------strcpy\n");
printf("5.将字符串1连接到字符串2-------------------strcat\n");
printf("-1-----------------------------------------exit\n");
printf("请输入选项\n");
}
int main(void)
{
int op=0;
int len1=0;
int len2=0;
char * pFirst=NULL;
char str1[50]="helloworld";
//"username=gao&&pwd=123456"
char str2[50]="helloxian";
char ch='\0';
int cha=0;
while(1)
{
printf("请输入字符串1\n");
scanf("%s",str1);
printf("请输入字符串2\n");
scanf("%s",str2);
menu();
scanf("%d",&op);
if(-1==op) break;
switch(op)
{
case 1:
len1=strlen(str1);
len2=strlen(str2);
printf("str1=%d str2=%d\n",len1,len2);
break;
case 2:
printf("请输入你要查找的字符\n");
scanf("%*c%c",&ch);
pFirst=strchr(str1,ch);
if(NULL==pFirst)
{
printf("未找到该字符\n");
}
printf("%s\n",pFirst);
break;
case 3:
cha=strcmp(str1,str2);
if(cha>0)
{
printf("str1>str2\n");
}else if(cha<0)
{
printf("str1<str2\n");
}else if(cha==0)
{
printf("str1==str2\n");
}
break;
case 4:
printf("copy before str2=%s\n",str2);
strcpy(str2,str1);
printf("copy after str2=%s\n",str2);
break;
case 5:
printf("cat before str2=%s\n",str2);
len2=strlen(strcat(str2,str1));
printf("cat after str2=%s len2=%d\n",str2,len2);
}
}
return 0;
}
3.数组
一维数组
一维数组的定义
存储一堆数据类型相同的数据
每个元素的数据类型 数组名[元素的个数]; //元素的个数必须为常量
//定义一个长度为5的float数组
float scores[5];
//定义一个长度为20的char数组
char str[20];
一维数组的初始化
部分初始化
float scores[5]={78,98,67};//初始化的为它的值,未进行初始化自动默认(int,float)为0,
char('\0')
char str[20]={'h','e','l','l','o'};
char str[20]="hello"; //char * pc="hello";
//初始化的为它的值,未进行初始化自动默认(int,float)为0,char('\0')
//使用该特点,清空我们的数组
float scores[5]={0};//对数组进行清空
char str[20]={'\0'};
全部初始化
float arr[];//error
float scores[5]={78,98,67,88,90};
//当全部初始化的时候,可以将元素的个数省略,
//如何获得元素的个数:由后面的赋值个数所决定
sizeof(scores)/sizeof(float) //整个数组的大小/一个元素的大小
float scores[]={78,98,67,88,90};
sizeof(scores)/sizeof(scores[0])
char str[]={'h','e','l','l','o','w','o','r','l','d','\0'};
char str[]="helloworld"; //sizeof(str)=?11
sizeof(str)/sizeof(char)
sizeof(str)/sizeof(str[0])
一维数组的排序
// 冒泡排序
for(i=0;i<SIZE-1;i++)
{
for(j=0;j<SIZE-1-i;j++)
{
if(scores[j]>scores[j+1])
{
float temp=0;
temp=scores[j];
scores[j]=scores[j+1];
scores[j+1]=temp;
}
}
}
二维数组
二维数组的定义
每个元素的数据类型 数组名[元素的个数] //元素的个数的必须为常量
//定义一个长度为5的float数组
float scores[5];
//定义一个长度为20的char的数组
char str[20];
//定义一个长度为3的数组,该数组中的每个元素又是(长度为4的float)一个数组
float arr[3][4];
二维数组的初始化
#include <S tdio.h>
int main(void)
{
//定义一个长度为3的数组,该数组中的每个元素又是(一个长度为4的float)数组
float arr[3][4]={{1,2,3,4},
{5,6,7,8},
{9,10,11,12}
};
float arr[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}; //是上面的定义的简化操作
//当全部初始化时,可以省略元素的个数
float arr[][4]={1,2,3,4,5,6,7,8,9,10,11,12}; //注意4是坚决不能省略的
return 0;
}
打印杨辉三角
#include <stdio.h>
int main(void)
{
int arr[10][10]={0};
int i=0,j=0;
//输入
for(i=0;i<=9;i++)
{
for(j=0;j<=i;j++)
{
if(j==0||i==j)
{
arr[i][j]=1;
}else
{
arr[i][j]=arr[i-1][j-1]+arr[i-1][j];
}
}
}
//输出
for(i=0;i<=9;i++)
{
for(j=0;j<=i;j++)
{
printf("%-5d",arr[i][j]);
}
printf("\n");
}
return 0;
}
二、相关运算符
1.算术运算符
C语言提供了 6 个算术运算符,包括加、减、乘、除、取余和自增、自减。这些运算符常常用于数学计算,可以对数字进行加减乘除运算,以及获取数字的余数。
- 加法运算符(+):加法运算符用于两个数字相加,并返回它们的和。例如,3 + 4 将返回 7;
- 减法运算符(-):减法运算符用于两个数字相减,并返回它们的差。例如,5 - 2 将返回 3;
- 乘法运算符(*):乘法运算符用于两个数字相乘,并返回它们的积。例如,2 * 6 将返回 12;
- 除法运算符(/):除法运算符用于两个数字相除,并返回它们的商。例如,8 / 2 将返回4;
- 取余运算符(%):取余运算符用于获取两个数字相除的余数,并返回余数。例如,5 % 2 将返回 1;
- 自增自减运算符(++、--):自增自减运算符分为前置自增自减和后置自增自减,分别表示先进行运算再进行自增自减操作和先进行自增自减操作再进行运算。例如,i++ 表示先返回 i 的值再将 i 加 1,而 ++i 表示先将 i 加 1 再返回i的值。
2.赋值运算符
赋值运算符用于将一个值赋给变量。赋值运算符的语法格式为“=”,左边是变量名,右边是要赋给变量的值。例如,a = 10;将把值 10 赋给变量 a。
在 C语言中,赋值运算符还有一些扩展的形式,如“+=”、“-=”、“*=”、“/=”等等。这些运算符的作用是将左边变量的值和右边的值进行运算后再赋给左边的变量。例如,a += 10;等同于a = a + 10;,即将变量 a 的值加上 10 后再赋给 a。
3.比较运算符
比较运算符用于比较两个值的大小,并返回布尔值 true 或 false。C语言提供了多个比较运算符,包括等于运算符、不等于运算符、大于运算符、小于运算符、大于等于运算符和小于等于运算符。
- 等于运算符(==):等于运算符用于比较两个值是否相等,并返回布尔值 true 或 false。例如,
if(a == 10)
将判断变量 a 的值是否等于 10,如果条件为真,将返回 true; - 不等于运算符(!=):不等于运算符用于比较两个值是否不相等,并返回布尔值 true 或 false。例如,
if(a != 10)
将判断变量 a 的值是否不等于 10,如果条件为真,将返回 true; - 大于运算符(>):大于运算符用于比较两个值的大小,判断左边的值是否大于右边的值,并返回布尔值 true 或 false。例如,
if(a > 10)
将判断变量 a 的值是否大于 10,如果条件为真,将返回 true; - 小于运算符(<):小于运算符用于比较两个值的大小,判断左边的值是否小于右边的值,并返回布尔值 true 或 false。例如,
if(a < 10)
将判断变量 a 的值是否小于 10,如果条件为真,将返回 true; - 大于等于运算符(>=):大于等于运算符用于比较两个值的大小,判断左边的值是否大于或等于右边的值,并返回布尔值 true 或 false。例如,
if(a >= 10)
将判断变量 a 的值是否大于或等于 10,如果条件为真,将返回 true; - 小于等于运算符(<=):小于等于运算符用于比较两个值的大小,判断左边的值是否小于或等于右边的值,并返回布尔值 true 或 false。例如,
if(a <= 10)
将判断变量 a 的值是否小于或等于 10,如果条件为真,将返回 true。
4.逻辑运算符
C语言提供了三个逻辑运算符,包括与运算符、或运算符和非运算符。这些运算符用于比较条件表达式的结果,并返回布尔值 true 或 false。
- 与运算符(&&):与运算符用于比较两个条件是否都为真,并返回布尔值 true 或 false。例如,
if(a > 5 && b < 10)
将判断变量 a 是否大于 5,并且变量 b 是否小于 10,如果两个条件都为真,将返回 true; - 或运算符(||):或运算符用于比较两个条件是否有一个为真,并返回布尔值 true 或 false。例如,
if(a > 5 || b < 10)
将判断变量 a 是否大于 5,或者变量 b 是否小于 10,如果有一个条件为真,将返回 true; - 非运算符(!):非运算符用于取反一个条件的结果,并返回布尔值 true 或 false。例如,
if(!(a > 5))
将判断变量 a 是否小于等于 5,如果条件为真,将返回 true。
5.位运算符
C语言提供了多个位运算符,用于对数字的二进制位进行操作。这些运算符包括按位与运算符、按位或运算符、按位异或运算符、按位取反运算符、左移运算符和右移运算符。
- 按位与运算符(&):按位与运算符用于对两个二进制数的每一位进行比较,并返回二进制结果。例如,1010 & 1100 将返回 1000;
- 按位或运算符(|):按位或运算符用于对两个二进制数的每一位进行比较,并返回二进制结果。例如,1010 | 1100 将返回 1110;
- 按位异或运算符(^):按位异或运算符用于对两个二进制数的每一位进行比较,并返回二进制结果。如果两个数的某一位相同,则返回 0;如果不同,则返回 1。例如,1010 ^ 1100 将返回 0110;
- 按位取反运算符(~):按位取反运算符用于对一个二进制数的每一位进行取反,并返回二进制结果。例如,~1010 将返回 0101;
- 左移运算符(<<):左移运算符用于将一个二进制数的所有位向左移动指定数量的位数,并返回二进制结果。例如,1010 << 2 将返回 101000;
- 右移运算符(>>):右移运算符用于将一个二进制数的所有位向右移动指定数量的位数,并返回二进制结果。例如,1010 >> 2 将返回 0010。
三、三大结构
1.顺序结构
标准输入scanf()函数
//可变参数的函数,第一个参数也是字符串
scanf("格式符号",地址列表);
scanf("%d",&i);
scanf("%f",&f);
scanf("%c",&ch);
//scanf中不管小数还是整数,只能控制宽度
scanf("%md",&i);
scanf("%mf",&ft)
标准输出printf()函数
//可变参数的函数,第一个参数一定是字符串 ""
printf("字符串")
printf("helloworld"); //字符串会原样输出
%d--->有符号的十进制整数
%f--->单精度的浮点数(默认保留小数点后6位)
%c---->字符
printf("字符串+格式化符号",变量名列表);
printf("%-m.nf",ft); //m表示可以控制数据的宽度 m<实际宽度 原样输出
// m>实际宽度 用空格来补,默认右对齐 -表示左对
齐
//n表示小数点默认n位
printf("%md",i); //整数中可以控制宽度
2.选择结构
单分支选择结构
if(条件为真)
{
语句1;
}
双分支选择结构
if(条件为真)
{
语句1;
}else
{
语句2;
}
多分支选择结构
if()else if()else if()....else{}
if(条件1为真)
{
语句1;
}else if(条件2为真)
{
语句2;
}else if(条件3为真)
{
语句3;
}.....
else if(条件n为真)
{
语句n;
}else
{
语句n+1;
}
switch,case
//1.条件必须是处于某一点上
//2.case 后面的标号必须为常量
//3.表达式==标号时,执行标号后面的语句,直到switch,case结束为止,或者碰到break语句
//4.case语句之间无顺序而言,甚至说你都可以default都可以写在最前面
//5.表达式不能为实型(单精度(float),双精度(double))
switch(表达式)
{
case 标号1:
语句1;
case 标号2:
语句2;
case 标号3:
语句3;
....
case 标号n:
语句n;
default:
语句n+1
}
3.循环结构
while()
//(1).循环的初始条件
while((2).条件判断)
{
(4).循环体
(3).条件更新
}
for()
//for其实就是while的变形
for((1).循环初始条件(多个就逗号隔开);(2).条件判断;(3).条件更新(多个条件逗号隔开))
{
(4).循环体
}
do....while()
(1).循环的初始条件
do
{
(4).循环体
(3).条件更新
}while((2).条件判断);
循环中常用的关键字
break 跳出循环
continue 结束本次循环,继续执行下一次循环
死循环
while(1)
{
}
for(;1;)
{
}
例题
乘法口诀表
1*1=1
1*2=2 2*2=4
......
1*9=9 2*9=18 ......9*9=81
程序:
#include<stdio.h>
int main(void)
{
int i,j;
for(i=1;i<=9;i++)
{
for(j=1;j<=i;j++)
{
printf("%d × %d= %2d ",j,i,i*j);
}
printf("\n");
}
return 0;
}