目录
5.2.1(除号)
5.2.2++,--
5.2.2.1单纯++
5.2.2.2++在变量之前
1.if()else if()else if()....else{}
1.1全局变量:定义在函数体外部的变量 作用域:自定义开始到文件结束,一般默认为0
1.2局部变量:定义在函数体内部的变量 作用域:自定义开始到最近的}结束
4.2指针出现错误:Segmentation fault (core dumped) (段 错误)
2.const char * pc1=&ch1 和char const * pc1=&ch1;
4.const char * const pc4=&ch1;
一、环境基本知识了解
1.编译环境介绍
在学习过程中采用Linux(ubantu)环境。使用vim编辑器编辑,gcc编译器编译代码。
2.windows目录和Linux目录的结构
windows:像一片倒置的森林
Linux(像一颗倒置的树):
/:表示根目录 是家目录(/home/用户名)
$:普通用户:在家目录没有操作权限。切换超级用户:sudo -s,退出:exit,在命令前面+sudo等于给这次命令一次超级用户权限
#:超级用户:在超级用户下的操作,普通用户无法操作。
绝对路径:从根目录开始的路径
相对路径:相对于目前所在的路径
3.Linux常用命令
命令格式:命令 【选项】【参数】【】中可以省略
以上三者之间需要空格隔开
打开终端:1、点击终端
2、ctrl+alt+t:打开一个目录为家目录的终端
3、ctrl+shift+n:打开一个与当前路径相同的终端
补全键:tab
清屏:ctrl+l or 在终端输入clear
查看历史命令:↑↓
查看当前绝对路径:pwd
查看当前目录下的内容:
ls(颜色的区别)白色:普通文件 蓝色:文件夹 绿色:可执行文件
ls+路径 查看该路径下内容
Ls -a:查看当前路径下的所有文件(包含隐藏文件) 隐藏文件:以.开头的文件
. :当前路径 .. :上一级路径
Ls -l:显示当前路径下的内容的详细属性
Ls -la:显示当前路径下的所有内容的详细属性
Ls Desktop:打印当前路径下的Desktop底下的内容
touch+文件名/文件路径:新建文件,一次可以创建多个
rm+文件名/文件路径:删除文件,一次可以删除多个
mkdir+文件夹名/文件夹路径:创建文件夹,可以同时创建多个
Rmdir+文件名/文件路径:删除空文件夹,一次可以删除多个
rm -rf:删除文件夹(空与非空皆可删除),不提示,直接删除
rm -ri:删除文件夹,并挨个提问是否删除
Cd+路径:切换路径(绝对路径/相对路径皆可)
Cd :直接返回家目录
Cd -:回到上一次操作的目录下
cp 源(文件/ -r 文件夹) 目标文件夹
mv的作用: 移动:mv 源文件/源文件夹 目标文件夹
重命名:mv 原来的名字 现在的名字
4.Vim编辑器
vim+文件名:打开该文件(如果没有该文件则创建并打开)
三种模式:
命令行模式:
命令行模式----------插入模式: i
命令行模式----------底行模式: shift+:
插入模式:
插入模式--------------命令行模式:esc
插入模式--------------底行模式:esc+shfit+:
底行模式:
底行模式-------------命令行模式:esc
底行模式-------------插入模式:esc+i
底行模式:
w:保存
q:退出
Wq:保存并退出
q!:强制退出
Wq!:强制保存退出
Set nu:显示行号
Set nonu:撤销行号
命令行模式:
yy:复制
Nyy:复制n行
P:粘贴
dd:剪切(不粘贴:删除)
ndd:剪切n行(删除n行)
u:撤销
Ctrl+r:反撤销
5.gcc 编译器
为什么要编译代码:
计算机看不懂,1.c是给我们看的,所以需要编译为计算机能够看懂的文件(二进制文件)
编译:
1、gcc 文件名 gcc hello.c //默认生成可执行文件a.out
2、gcc 文件名 -o 可执行文件名 gcc hello.c -o hello //生成指定的可执行文件hello 执行可执行文件:./可执行文件名 printf函数
头文件:#include Printf(“格式控制串”,输出表);
格式控制串:原样输出的内容+格式化符(%d,%c,%f) 输出表:输出的内容
注意:输出内容的个数 要与 格式化符一一对应!
6.计算机的基本结构
组成:
输入输出设备:(键盘、鼠标)
CPU处理器(控制器、运算器、寄存器)
存储器 程序 存储器: 内存:工作存储器,容量较小,读写速度快,掉电数据丢失
外存:长期保存数据,容量较大,读写速度较慢,掉电数据不会丢失
寄存器:cpu内部的存储器,容量极小,但是读写速度最快
7.什么是程序
程序:计算机能够识别的一组有序的指令
指令:计算机能够识别的操作
Hello.c和a.out那个是程序?a.out是程序
8.程序设计步骤
Vim(编辑)------> gcc(编译)------> ./可执行文件名
9.计算机的数据表示(进制转换)
数值数据和非数值数据
9.1 非数值数据(不能够直接进行算术运算的数据)
字符、图片、 ‘a’ ‘b’
ASCII码表:规定了每一个字符在计算机中对应的是哪八位二进制数(1字节 == 8bit)
‘A’ ------>65 ‘a’------->97 所有的大写字母都比小写字母小32 ‘0’------>48 ‘\0’---------->0
9.2 数值数据(能够直接进行算术运算的数据)
二进制、八进制、十进制、十六进制
二进制:逢2进1 0~1
八进制:逢8进1 0~7
十进制:逢10进1 0~9
十六进制:逢十六进1 0~9、a~f
为了区分不同的进制:八进制前加0,十六进制前加0x(0X)
76:(十进制) 076(八进制) 0x76(十六进制) 0X76 (0xafc4 0XAFC4)
二、基本数据类型
1. 字符型家族
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)
考点:(超范围)(如果超范围了,则转圈去数)
1、 Unsigned char c = 260; Printf(“%d\n”,c);-----(4) 1 0000 0100
2、 Signed char a = 130; Printf(“%d\n”,a);-----(-126) 1000 0010---------------1111 1101------------------1111 1110-----------(-126)
2.整型家族
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))
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
3.浮点型家族
浮点型的存储方式与整数的存储方式是不一样的
浮点型的存储方式决定了他不能准确的表示一个数,只能近似的表示一个数
Float(单精度浮点数):有效数字的位数:6~7位:%f
Double(双精度浮点数):有效数字的位数:15~16位:%lf
%f和%lf:默认输出小数点后6位
%.nf: 保留小数点后n位进行输出
4.变量名的命名规范
\1. 由数字,字母,下划线组成,首字母不能数字
\2. 不能为关键字和保留字
\3. 尽量见名知意
5.相关运算符
5.1赋值运算符(=)
5.2算术运算符
+,-,*,/,%,++,--
/ 除号 整数/整数=整数 7/3=2 7/3.0=2.333
% 求余/取模 7%3= 1
1.(除号)
// (/)除法
#include <stdio.h>
int main(void)
{
int i=7;
int j=3;
printf("%d\n",i/j); //整数/整数=整数
float ft=3;
printf("%f\n",i/ft);//整数/小数===小数去转
return 0;
}
2.++,--
1.单纯++
//++,--
//++,--
#include <stdio.h>
int main(void)
{
int a=5;
int b=0;
//++a; //单纯的++没有和其他运算在一起的,++a ,a++ 无区别
a++;
printf("a=%d\n",a);
return 0;
}
2.++在变量之前
3.++在变量之后
5.3(/,%) 输入
一个四位数,将每一位取出求和
3.3关系运算符
<,>,<=,>=,==(表示判断是否等于),!=
3.4逻辑运算符
&& (有一为假,结果就为假)
|| (有一为真,结果就为真)
!
6.数据类型之间的转换
6.1隐士转换 (范围小---->范围大的)
int+float ----->float
unsigned+signed--->unsigned
6.2强制转换 (范围大--->范围小)
#include <stdio.h>
int main(void)
{
float f=12.34;
int i=0;
i=(int)f; //(类型名)变量名 对该变量进行强制转换
printf("i=%d\n",i);
return 0;
}
三、三大结构
1.顺序结构(标准输入输出函数)
1.1scanf()函数
//可变参数的函数,第一个参数也是字符串
scanf("格式符号",地址列表);
scanf("%d",&i);
scanf("%f",&f);
scanf("%c",&ch);
//scanf中不管小数还是整数,只能控制宽度
scanf("%md",&i);
scanf("%mf",&ft)
1.2printf()函数
//可变参数的函数,第一个参数一定是字符串 ""
printf("字符串")
printf("helloworld"); //字符串会原样输出
%d--->有符号的十进制整数
%f--->单精度的浮点数(默认保留小数点后6位)
%c---->字符
printf("字符串+格式化符号",变量名列表);
printf("%-m.nf",ft); //m表示可以控制数据的宽度 m<实际宽度 原样输出
// m>实际宽度 用空格来补,默认右对齐 -表示左对
齐
//n表示小数点默认n位
printf("%md",i); //整数中可以控制宽度
2.选择结构
2.1单分支选择结构
if(条件为真)
{
语句1;
}
2.2双分支选择结构
if(条件为真)
{
语句1;
}else
{
语句2;
}
2.3选择语句---多分支选择结构
1.if()else if()else if()....else{}
if(条件1为真)
{
语句1;
}else if(条件2为真)
{
语句2;
}else if(条件3为真)
{
语句3;
}.....
else if(条件n为真)
{
语句n;
}else
{
语句n+1;
}
2.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.循环结构
3.1什么是循环
3.2循环语句
1.while()
//(1).循环的初始条件
while((2).条件判断)
{
(4).循环体
(3).条件更新
}
2.for()
//for其实就是while的变形
for((1).循环初始条件(多个就逗号隔开);(2).条件判断;(3).条件更新(多个条件逗号隔开))
{
(4).循环体
}
3.do....while()
(1).循环的初始条件
do
{
(4).循环体
(3).条件更新
}while((2).条件判断);
3.3循环中常用的关键字
1.break 跳出循环
2.continue 结束本次循环,继续执行下一次循环
3.4死循环
1.
while(1)
{
}
2.
for(;1;)
{
}
四、数组
1.一维数组的定义
数组: 存储一堆数据类型相同的数据 例如 存储全班(40)的C语言成绩
每个元素的数据类型 数组名[元素的个数]; //元素的个数必须为常量
//定义一个长度为5的float数组
float scores[5];
//定义一个长度为20的char数组
char str[20];
2.一维数组的初始化
2.1部分初始化
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'};
2.2全部初始化
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])
3.一维数组元素的访问
数组名[下标] 下标是0开始的
4.一维数组相关操作
4.1输入
4.2输出
4.3数组中的最大值/最小值
4.4数组的排序
#include <stdio.h>
#define SIZE 5
void menu(void);
void menu(void)
{
printf("1----------------input\n");
printf("2----------------output\n");
printf("3----------------calMax\n");
printf("4----------------calMin\n");
printf("5----------------sort\n");
printf("6----------------次大值\n");
printf("-1---------------exit\n");
}
int main(void)
{
//定义一个长度为5的float数组
float scores[SIZE]={0};
float max=0;
int op=0;
int i=0;
int j=0;
while(1)
{
menu();
printf("请输入选项\n");
scanf("%d",&op);
if(-1==op) break;
switch(op)
{
case 1:
//输入
printf("请输入%d个数\n",SIZE);
for(i=0;i<SIZE;i++)
{
scanf("%f",&scores[i]);
}
break;
case 2:
//输出
for(i=0;i<SIZE;i++)
{
printf("%7.1f",scores[i]);
}
printf("\n");
break;
case 3:
//1.假设第一个值为最大
max=scores[0];
//2.使用max和后面每个进行比较max<scores[i] max=scores[i]
for(i=1;i<SIZE;i++)
{
if(max<scores[i])
{
max=scores[i];
}
}
printf("max=%.1f\n",max);
break;
case 5:
// 冒泡排序
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;
}
}
}
printf("sort over\n");
break;
}
}
return 0;
}
5.二维数组
5.1二维数组的定义
每个元素的数据类型 数组名[元素的个数] //元素的个数的必须为常量
//定义一个长度为5的float数组
float scores[5];
//定义一个长度为20的char的数组
char str[20];
//定义一个长度为3的数组,该数组中的每个元素又是(长度为4的float)一个数组
float arr[3][4];
5.2二维数组的初始化
5.3二维数组的访问
5.4二维数组的相关操作
5.4.1输入、输出
5.4.2求鞍点: 在一行当中最大的,看是否为该列中最小的
#include <stdio.h>
void menu(void);
void menu(void)
{
printf("1----------input\n");
printf("2----------output\n");
printf("3----------求鞍点");
printf("-1----------exit\n");
printf("请输入选项\n");
}
4.打印杨辉三角
int main(void)
{
//定义一个长度为3的数组,该数组中的每个元素又是一个长度为4的float数组
int i=0,j=0;
int op=0;
int arr[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
while(1)
{
menu();
scanf("%d",&op);
if(-1==op) break;
switch(op)
{
case 1:
printf("请输入%d个元素\n",3*4);
for(i=0;i<3;i++)
{
for(j=0;j<4;j++)
{
scanf("%d",&arr[i][j]);
}
}
break;
case 2:
for(i=0;i<3;i++)
{
for(j=0;j<4;j++)
{
printf("%d ",arr[i][j]);
}
printf("\n");
}
break;
}
}
return 0;
}
5.4.3打印杨辉三角
int arr[10][10]
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
......
1 8 ...............1
#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.变量
1.1全局变量:定义在函数体外部的变量 作用域:自定义开始到文件结束,一般默认为0
1.2局部变量:定义在函数体内部的变量 作用域:自定义开始到最近的}结束
2.自定义函数
2.1函数声明
返回值类型 函数名(形式参数列表);
//函数声明
void menu(void); //void 空类型
2.2调用函数
变量名=函数名(实际参数列表);
变量名=函数名(实际参数1,实际参数2,实际参数3);
//函数调用
menu();
2.3函数定义
返回值类型 函数名(形式参数列表)
{
函数体
return 变量名; //若无返回值该句话可以省略
}
void menu(void)
{
printf("(+)--------add\n");
printf("(-)--------sub\n");
printf("(*)--------mul\n");
printf("(/)--------div\n");
printf("(#)--------exit\n");
}
3.库函数
1.引入头文件
#include <stdio.h>
2.调用库函数
变量名=函数名(实际参数列表);
变量名=函数名(实际参数1,实际参数2,实际参数3);
六、指针
1.什么指针
字符是一种保存字符('a','\n')的数据类型
实型是一种保存小数(12.5,17.8)的数据类型
整形是一种保存整数(12,18)的数据类型
指针是一种保存地址(&i)的数据类型
2.如何定义指针变量
//数据类型 变量名;
//定义一个int变量
//定义一个float变量
//定义一个char变量
//定义一个int变量
int i=5;
//定义一个指向int的指针
int * pi;
pi=&i; //pi指向i float f=12.5 pi=&f;(×)
//定义一个指向int的指针的指针
int ** ppi;
ppi=π //ppi=&i(×)
3.函数和指针关联
#include <stdio.h>
int main(void)
{
int a=5,b=6;
printf("swap before a=%d b=%d\n",a,b);
swap1(a,b); //传a和 b 去研究看能换,不能换,画图分析为什么
swap2(&a,&b); //传&a &b去换,看能换,怎么换,不能换,为什么
printf("swap after a=%d b=%d\n",a,b);
}
4.字符指针
4.1字符串常量特点
.用双引号引起来称为叫字符串常量 如: "helloworld"
.字符串本身表示的是第一个字符的首地址 char * pc=“helloworld”;
.字符串常量本身有一个'\0'结束标志
4.2指针出现错误:Segmentation fault (core dumped) (段 错误)
4.2.1修改了常量区的内容
4.2.2访问NULL指针或者野指针
5.指针相关的运算
5.1指针+数值 pc+1 , pc++ (指针自增)
5.2指针-指针
6.数组和指针的关系
6.1指针的一维数组的关系
#include <stdio.h>
#define SIZE 5
int main(void)
{
//定义一个长度为SIZE的float数组
float scores[SIZE]={78,89,96,93,71};
//定义一个指向float的指针
float * pf=NULL;
//将数组中第一个元素的首地址赋值给pf
pf=scores;// pf=&scores[0]
int i=0;
//输入
printf("请输入%d个元素\n",SIZE);
for(i=0;i<SIZE;i++)
{
//scanf("%f",&scores[i]);
scanf("%f",scores+i);
//scanf("%f",&pf[i]);
//scanf("%f",pf+i);
}
//输出
for(i=0;i<SIZE;i++)
{
//printf("%.1f ",scores[i]);
printf("%.1f ",pf[i]);
//printf("%.1f ",*(scores+i));
//printf("%.1f ",*(pf+i));
}
printf("\n");
return 0;
}
7.指针的二维数组的关系
//定义一个长度为3的数组,该数组中的每个元素又是一个长度为4的float数组
float arr[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
//定义一个指向float的指针
float * pf=NULL;
//&arr[0][0] ----> arr[0][0] (float) &arr[0][0] (float *)
pf=&arr[0][0];
int i=0;
for(i=0;i<3*4;i++)
{
if(i%4==0)
{
printf("\n");
}
printf("%.1f ",pf[i]);
}
printf("\n");
return 0;
}
8.指针数组
定义一个长度为4的数组,该数组中每个元素是一个指向float的指 针
float (*parr)[4]; //指针sizeof(parr)=8 是一个指向数组的指针 parr+1 sizeof(float [4])
数组定义的语法:
每个元素的数据类型 数组名[元素的个数] //元素的个数必须为常量
float * arrp[4];//----> float * [4]
//izeof(arrp)=sizeof(float *)*4
七、const关键字:定义常量的一种方式
1.const int b=23;
2.const char * pc1=&ch1 和char const * pc1=&ch1;
3.char * const pc3=&ch1;
4.const char * const pc4=&ch1;
pc4=&ch2 (error)
*pc4='B' (error)
八、main的参数
九、带参数的宏
十、位运算
单算移(左移<<,右移>>)关与(&),异(异或^)或(或|)逻条赋
& 有1为假,结果就为假
| 有1为真,结果为 真
~ 取反
^ (异或) 相同为0,不同为1
<<
>>
十一、gdb调试器
1.编译时必须添加-g参数
linux@ubuntu:~/23072/day9$ gcc -g scores.c -o scores1
2.打开调试工具
b main //设置在main函数处 (breakpoint)
b 20 //设置到20行
r //(run)
n //next 下一步 不进子函数
s //step 什么函数都进(库函数也进) 想进子函数,看见子函数按s
q //quit