C入门
C是面向过程的结构化语言,具有 高效、灵活、功能丰富、表达力强、移植性、兼容性、普遍性、基础性的特性。
1、使用bsearch()函数在包含300万个元素的数组中查找一个元素,最多需要进行多次比较?
解答:21。公式:log2(3000000)=21
2、如果使用下标超出了数组声明的界限,将发生什么情况?
解答:程序通过编译,甚至能够运行,但结果是不可预测,这会造成内存溢出问题。
3.第一个c语言程序
#include <stdio.h>//预处理指令:在编译之前执行的指令
int main(int a)
{
//输出字符串到控制台,这个函数声明在stdio.h文件中
ptintf(“Hello world”);
return 0;//退出函数的意思
}
系统自带文件使用<>,自己写的文件用双引号“”。
.h成为头文件,用来声明一些常用函数,假如想使用这些函数,就必须包含这个头文件。
程序结构:
c程序由函数构成,任何一个c语言程序都是由一个或者多个程序段构成的就叫函数。不管整个程序中有多少个函数,都是先执行main函数,并且只有一个main函数。
函数定义放.c文件,函数的声明放.h文件。
4C语言程序的开发运行过程:
1编写程序
2编译:把c语言源代码编译0和1
将一个源文件(cc -c文件名.c )编译,编译成功会生成一个.o目标文件(cc文件名.o )(./当前路径)
3链接:其实就是把.o相关联的所有目标文件和函数库合并一起生成可执行文件。
4运行:运行可执行文件./a.out
总结:
.c是语言源文件,在编写程序时候创建
.o是目标文件,在编译成功时候产生
.out是可执行文件,在链接成功时候产生
总结change指令:
编译:cc -c xxx.c 链接:cc xxx .o
编译,链接:cc xxx.o
运行当前路径下可执行文件:./a.out
更改可执行文件的名称:cc xxx.c -o xxxx
源程序通过编译成目标文件接着通过链接将目标文件和系统函数合并就可以执行了。
编译器只会检测语法,不会检测有没有main函数,可执行文件必须要有且只有一个main函数才能执行,链接器检测是否有main函数。
5函数
定义函数目的:将一个常用的功能封装起来方便以后调用
定义函数的步骤:
函数名--函数体--明确函数参数和返回值
函数的声明:int sum(int a,int b);
函数的定义:
返回值类型 函数名(形式参数列表)
{
函数体
}
形参和实参:
比如:int sum(int num1,int num2);
括号里面的是形式参数简称形参
调用函数时候把实际参数简称实参
一个函数可以没有形参,也可以有无限多个形参
return的作用:1退出函数
2返回一个具体值给函数调用者
6printf函数:
printf函数和scanf函数都是在stdio.h中声明的一个函数。
用法:printf(字符串);printf(字符串,格式符参数)
常用格式符及其含义:
%d 输出整数int(
%c 输出一个字符char
%s 输出一个或多个字符也就是字符串
%f 输出小数默认6位float,double
7scanf函数:
调用scanf函数时,需要传入变量地址作为参数,scanf函数会等待标准输入设备输入数据,并且将输入数据赋值给地址对应的变量。(只接受变量的地址)
scanf函数是一个阻塞式函数,等用户输入
用户输入完毕后就会将用户的值赋给number变量,函数调用完毕
1输入字符
2一次性输入多个数值,并且以某些符号隔开输入字符
3scanf中不能写\n
8数据类型和类型修饰符
数据的分类:静态(存在硬盘里面)和动态数据(存在内存中)
静态占用硬盘空间;动态数据占用内存空间。
不管是静态还是动态都是0和1组成
c语言中数据类型分为:
一、基本数据类型(整型int,浮点型float,double,字符型char(-128到127))
二、指针类型void*
三、构造类型(数组,结构体struct,共用体union,枚举enum)
四、空类型void
变量:
变量含义:可变的数据 整形变量。字符变量。字符串变量。
定义变量目的:在内存分配一块存储空间给变量,方便以后存放数据(为何加上变量类型?是为了更好的让内存分配一定的存储空间给变量以及可读性。
格式:变量类型+变量名 比如:int a
变量-赋值:
每一次赋值都会将原来的赋值给覆盖。只要有不确定数据就应该定义变量.
在函数内部定义的变量就是局部变量
在函数外部定义的变量是全局变量。
声明一个局部变量要先初始化
变量在函数中的作用域:
1从定义变量那行代码开始一直到所在的代码块结束
2及时回收不再使用的变量为提升性能
不同变量类型占据的存储空间:
64位编译器:char 1个字节
int 4个字节
float4个字节
double8个字节
16位编译器:char 1
int 2
float4
double8
修饰符:
short long signed unsigned
这些修饰符是用来修饰int类型比如:
long int 11=2等价long 11 =2
常量:有3种:数值。字符常量。字符串常量。
9基本运算
c语言一共有34种运算符包括加+减-乘*除/
取余运算(模运算):两个整数相除之后的余数
1算术运算符-使用:
自动类型转换
强制类型转换
自动类型提升
2赋值运算符:
a+=5就是相当于a=a+5
3自增自减运算-使用:
a++相当于a+=1就是相当于a=a+1
a--相当于a-=1就是相当于a=a-1
自增自减运算a++和++a的区别:
a++就是a原来的值进行运算
++a就是先a加1再运算
基本运算--条件判断:
判断条件是否成立,就是判断条件的真假
C语言规定:任何非0值都是真,只有0才是假
关系运算比较:在C语言中,条件成立就返回1就是真,不成立就返回0是假
4关系运算符-优先级:
关系运算符中==、!=的优先级相等,<、<=、>、>=的优先级相等且前者的优先级低于后者:2==3>1
关系运算符的优先级小于算术运算符
-1+2*(2-4)>=1%2
4>3>0 true 1
4>3>2 false 0
5逻辑运算符简介:
逻辑运算结果只有2个:真为1,假为0
1逻辑与
使用格式:条件A&&条件B
只有当A和B结果都成立才是真,否则为假
2逻辑或
使用格式:条件A||条件B
只有当A和B结果只要有一个成立就是真,只有当A和B都不成立时候才为假
3逻辑非
使用格式:!条件A
对条件A进行取反:若条件A成立,结果为0,就是假,不成立结果为1就是真(真的变假,假的变真)
6逗号运算符和逗号表达式:
逗号运算符主要用于连接表达式,如:int a=9;
7.三目运算基本使用:
双目运算符如4+3>6-2
单目运算符如!10
三目运算符:条件?数值1:数值2
8sizeof:
作用:用来表示一个变量或者一个常量,一种数据类型所占的内存字节数
基本形式:
sizeof(变量或者常量)
sizeof变量\常量
sizeof(数据类型)
不能是sizeof数据类型
10一维数组---属于构造类型
字节和地址:
计算机中的内存以字节为单位,每个字节都有自己唯一的地址。
相邻字节是联系的;不同类型字节不一样,数据越大,所占字节越多;
特点:
1内存寻址由大到小,优先分配内存地址比较大的字节给变量
2变量越先定义内存地址越大
3取得变量的地址:&变量名
地址运算符:&是一个地址运算符,取得变量的地址
当定义一个变量时,系统会分配一个带有唯一地址的存储单元来存储这个变量。
变量存储单元的第一个字节的地址就是该变量的地址。
一维数组的定义:类型 数组名[元素]
例如:int a[5];
数组的定义:int a [3] 数组的初始化:int a [2] ={8,7};
11.字符串的定义、初始化、输入、输出
关键字:
c语言一共提供了32个关键字,都被赋予特殊含义
特点:
1都是小写
2在Xcode中都会显示特殊颜色例如紫褐色
标识符:程序员自定义的一些符号和名称(命名)
命名规则:
1只能是26个字母的大小写,10个阿拉伯数字0到9,下划线组成
2严格区分大小写
3不能以数字开头
4不可以使用关键字作为标识符
注释:
注释含义是解释程序或者代码的意思
单行注释:以//开头,只能注释一行
多行注释:以/*开头,以*/结尾
作用:被注释的代码不会参与编译
1检查代码作用
2排除错误
常量:
定义:表示一些固定数据(const)
常量分类:
1整型常量包括所有整数
2浮点型常量分为double和float也就是小数(注意0.0也算是小数)
注意:float型数据都是以f结尾的
3字符常量
将一个数字,英文字母或者其它符号用单引号括起来构成就是字符常量例如:‘6',‘a',‘+’注意:单引号只能括住1个字符,而且不能是中文字符
4字符串常量string:
将一个或者多个字符用双引号串起来构成的就是字符串常量
‘\0'表示字符串结束的一个标志,什么也不干
字符串的定义和初始化:
char s3 = “mj";//字符串MJ
字符串的输出:
使用printf和puts函数来输出。
区别:printf可以输出多个字符串,puts只能输出一个字符串,puts会自动换行。
字符串的输入:
使用scanf函数和gets函数输入
从第一个地址开始赋值用户输入的字符序列,在尾部会自动加上一个\0
都能读写一个字符串,scanf函数可输入多个字符串,gets只能输入一个字符串,scanf函数不能接受输入回车,tab键,空格
12.二维数组
定义:类型 数组名[行数] [列数]
二维数组的存储:把二维数组当做是一维数组的集合,即二维数组是一个特殊的一维数组,它的元素就是一维数组,存放顺序按行存放。
初始化:按行进行初始化。按存储顺序进行初始化。对部分元素进行初始化
15.字符和字符串处理函数
字符处理函数:
putchar,只能输出一个字符,printf函数可以输出多个字符;字符输入函数getchar,只能读入一个字符,scanf函数可以输入多个字符
字符串处理函数:
使用时候加上#include <string.h>
strlen函数用来测量字符串的字符个数,不包括\0
strcpy函数是将右边的字符串拷贝到字符数组中,从字符数组的首地址开始逐个字符拷贝,直到拷贝到\0为止,在字符数组的尾部肯定会保留一个\0
strcat函数将右边的oc字符串拼接到字符数组的尾部
strcmp函数用来比较字符串大小,调用形式为:strcmp(字符串1,字符串2)
如果字符相同返回值为0,不相同返回两个字符串中第一个不相同的字符ASCII码值的差。即字符串1大于字符串2时函数返回值为正,否则为负。
strlwr函数用来将字符串中大写字母换成小写字母
strupr函数将字符串中小写字母换成大写字母
16 指针的定义
什么是指针?用来存放变量的地址。
指针的定义:char *b;//定义了一个指针变量b,而且b 只能指向char类型的变量
b=&a; //让指针变量a指向b
char *b=&a;和上面两行同等
错误做法:char *p;*p=10;应该在指针确定指向变量后再进行相应操作
错误做法:char *p;p=100;指针变量是存储地址的,不能随便赋值一个常数
17.关于指针的一些疑惑
1个指针变量占用多少字节的内存空间?占用的空间是否会跟随所指向变量类型而改变?
在同一种编译器环境下,一个指针变量所占用的内存空间是固定的,char类型和int类型,一个指针变量不会随着类型改变而改变。
在16位编译器环境下,任何一个指针变量都只占用2个字节;32位占用4个字节,64位占用8个字节。
2既然每个指针变量所占用内存空间是一样的,而且存储都是地址,为何指针变量还要分类型?而且只能指向一种类型变量?
18.指针与一维数组
数组及其数组元素都占有存储空间,都有自己的地址,因此指针变量可以指向整个数组也可以指向数组元素。
19.指针、数组与函数参数
如果一个函数,它的参数是数组类型,可以传数组名,也可以传指针,只要是地址就可以;
如果一个函数的参数是指针类型情况下,可以传数组名,也可以传指针变量。
20.流程控制分为三种结构:
1顺序结构
2选择结构if语句
3循环结构
if语句使用注意:一个分号也是一条语句叫做空语句(if后面语句不要添加分号)
如果要在if后面的语句中定义新的变量,必须用大括号{}
switch-基本使用
选择结构除了可以使用if语句,还可以使用switch。
switch(数值)
{
case 数值1;
语句1 ;
break;
case 数值2;
语句2;
break;
default;
语句3;
break;
}
break:退出整个switch语句
如果case后面没有break就会执行后面所有case中的语句,一直到遇到break为止
switch作用域的问题:如果要在case后面定义新的变量,必须用大括号{}包住
if和switch的对比:
if语句能完成的功能,switch并不一定能完成例如比较大小;在有些情况下,if语句和switch是可以同时完成,switch能完成的功能if一样都能完成
循环结构:
while基本使用
while(条件)
{
循环体
}
运行原理:如果条件 不成立永远不会执行循环体;
如果条件成立就会执行循环体,执行完毕再次判断条件是否成立
while使用注意死循环:while语句中不能写;(;是一个空语句,导致形成死循环,不断执行空语句)
do while:
do {
}while (条件);
1很多情况下,while和do while 可以互换
2while的特点:如果一开始条件不成立,永远不会执行循环体;dowhile特点不管一开始条件是否成立,至少会执行一次循环体
for基本使用
for(语句1 ;条件;语句2)
{
循环体
}
语句1 :初始化语句
语句2:增量语句(执行完循环体后执行的语句)
1for一开始就会执行一次语句1
2判断条件是否成立,如果条件成立就会执行一次循环体,然后就会执行语句2,再次判断条件是否成立,如果条件成立就会执行一次循环体,然后就会执行语句2。。。。
for使用注意:for()后面不要写分号;死循环:for(;;) ;
continue和break的使用注意:
break
1使用场合switch语句:退出整个switch语句
2循环结构:退出整个循环语句
continue 1使用场合循环结构:结束当前这次的循环体,进入下一次循环体
21.指针与字符串
可以使用字符数组来存放字符串,不过在数组尾部加上一个空字符\0
用指针遍历字符串的所有字符
先定义一个字符串数组装着一个字符串;指针间接指向这个字符串
22.指针与函数
返回指针的函数;
指向函数的指针;
指向函数的指针可以作为函数的形参
23.C语言预处理指令1宏定义
一般形式:#define 宏名 字符串
#define num 6//6是用来替换宏名的字符串
#define sum(a,b)a+b带参数的
纯粹字符串替换,没有参数,没有返回值,没有类型
24.预处理指令2条件编译
#if 条件1
code1编译进去,不是执行
#elif 条件2
code2
#else
code3
#endif
注意:只能放宏定义,在编译之前做的事情,不能放变量
其他用法
#defined
code
#endif
//如果已经定义过宏,就编译代码
#if!defined
code
#endif相反
还有:
#ifdef和#!ifndef(同上)
25.C语言预处理指令3文件包含
一般形式:#include <文件名>系统自带
#include “文件名”自己命名的
#include不会检测有木有包含头文件,导致头文件重复。每次需要加:
#ifndef——
#define——
#endif
26.变量类型
根据变量作用域不同,分为局部变量和外部变量
所有的全局变量都是静态变量;被关键字static修饰的局部变量也是静态变量
根据变量的存储类不同,分为:自动变量,静态变量,寄存器变量
所有局部变量都是自动变量;被关键字auto修饰的局部变量也是自动变量
27.extern与函数
外部函数:默认情况下是外部函数。允许其他文件访问,调用
内部函数:不允许其他文件访问,调用
完整地定义一个外部函数需要extern关键字;默认情况下就是外部函数,可以省略extern
完整地声明一个函数需要extern关键字;表示引用一个外部函数,可以省略extern
28.static与函数
完整地定义一个内部函数需要static关键字;默认情况下就是内部函数,说明不能在其他文件访问
完整地声明一个函数需要static关键字
29.extern与变量
完整声明全局变量需要extern关键字,也可省略,不能定义变量
如果在不同的不同源文件中有同名的全局变量,那么这些变量代表同一个变量
30.static与变量
用static修饰的全局变量,被成为内部变量,别人访问不了
定义一内部变量,不能被其他文件访问;如果在不同源文件出现了同名的内部变量,那么这些变量互不干扰
31.结构体
结构体的定义:strict 结构名{成员表列} 变量名表列[];
结构体作为函数参数;void test(){
struct person person={27};
}
定义一个结构体变量;struct person person={27};
定义指向结构体的指针:struct person *p;
32.枚举
枚举的定义:enum 枚举名{枚举值表};
声明一组常数;
在定义枚举类型的同时定义一个枚举变量:enum season{spring,summer,fall,winter}s=spring;
33.typedef
typedef 原类型名 新类型名
1、使用bsearch()函数在包含300万个元素的数组中查找一个元素,最多需要进行多次比较?
解答:21。公式:log2(3000000)=21
2、如果使用下标超出了数组声明的界限,将发生什么情况?
解答:程序通过编译,甚至能够运行,但结果是不可预测,这会造成内存溢出问题。