大一上半学期学习了C语言,第一次接触计算机语言,接触编程。从刚开始的不适应,到现在的熟悉,自己的C语言学的还算一般,写给知识点,总结一下自己的零碎知识。
在程序运行过程中,其值不能被改变的量成为常量。例如:5,9,32,1000,0.0225,0.0198是常量。数值常量就是数学中的常数。
常用的的常量有以下几类:
(1) 整型常量。如1000,12345,0,-345等都是整型常量。
(2) 实型常量。有两种表示形式:
①十进制小数形式,由数字和小数点组成。如:123.456,0.356。
②指数形式,如12.34e3(代表12.34*10^3),由于计算机输入或输出时,无法表示上角或下角,故规定以字母e或E代表10为底的指数。但应注意:e或E之前必须有数字,且e或E后面必须为整数。
(3)字符常量。有两种形式的字符常量:
①普通字符,用单撇号括起来的一个字符。
②转义字符
(4)字符串常量,用双撇号把若干给字符括起来。
(5)符号常量,用一个符号代表一个常量。
变量必须先定义,后使用。在定义时指定该变量的名字和类型。
如:const int a =3;
c语言规定标识符只能由字母、数字、下划线3种字符组成,且第一个字符不能由数字开头。
运算符 | 含义 |
---|---|
+ | 正号运算符(单目运算符) |
- | 负号运算符(单目运算符) |
* | 乘法运算符 |
/ | 除法运算符 |
% | 求余运算符 |
+ | 加法运算符 |
- | 减法运算符 |
算数运算符的结合方向都是“自左向右”。
作用是使变量的值加1或减1。
C语言中,实现数据输出是printf(格式输出),实现输人的是scanf(格式输入)。
**if语句的形式:
(1)if(表达式)语句1;
(2)
if(表达式)
语句1
else
语句2;
(3)
if(表达式1)语句1
else if(表达式2)语句2
……
else if(表达式n)语句n
else 语句n+1
关于优先级:
算术运算符 (高)
关系运算符
赋值运算符 (低)
&& 逻辑与
|| 逻辑或
! 逻辑非
**
switch(表达式)
{
case 常量1:语句1;
case 常量2:语句2;
……
case 常量n:语句n;
default: 语句n+1;
}
while(表达式)语句
;
表达式用来判断是否满足条件进入循环结构,语句即是要执行的循环体。
**
do
语句
while(表达式)
**
**
for(循环变量赋初值;循环条件;循环变量增值)
语句
不同的循环语句直接可以进行相互嵌套,以达成某种目标。
continue语句:跳出本次循环,进入下一个循环体。
break语句:跳出循环体,结束循环。
数组:一组有序数据的集合,数组的每一个元素都属于同一个数据类型。
类型符 数组名[常量表达式];
(1)数组名的命名规则和变量名相同,遵循标识符规则。
(2)C语言中不允许对数组大小作动态定义。
数组名[下标]
(1)在定义数组时对全部数组元素赋予初值。例如:
int a[10]={
0,1,2,3,4,5,6,7,8,9};
(2)可以只给数组中的一部分元素赋值。例如:
int a[10]={
0,1,2,3,4};
其他的元素,系统自动给后面补为0。
二维数组定义的一般形式:
类型说明符 数组名[常量表达式] [常量表达式];
二维数组引用:
数组名[下标][下标];
(1)分行给二维数组赋初值。例如:
int a[3][4]={
{
1,2,3,4},{
5,6,7,8},{
9,10,11,12}};
(2)可以将所有数据写在一个花括号内,按数组元素在内存中的排列顺序对各元素赋初值。
int a[3][4]={
1,2,3,4,5,6,7,8,9,10,11,12};
(3)可以对部分元素赋初值。
int a[3][4]={
{
1},{
2},{
3}};
//其他元素自动补位值为0。
定义:用来存放字符数据的数组是字符数组。字符数组的一个元素放一个字符。例如:
char c[5];
(1)用“初始化列表”,把各个字符依次赋给数组中各元素。例如:
char c[10]={
'I',' ','a','m',' ','h','a','p','p','y'};
(2)在定义时可以省略数组的长度 ,系统会自动根据初值个数确定数组长度。例如:
char c[]={
'I',' ','a','m',' ','h','a','p','p','y'};
(3)字符串数组
char c[10]={
“I am happy”};
(4)部分元素没有赋予初值,系统自动补上‘\0’,即空字符。\0也是字符串结束的标志。
(1)逐个字符输出。用格式符“%c”输入或输出一个字符。
(2)将整个字符串一次输入或输出。用“%s”格式符,意思是对字符串(String)的输入输出。
其一般形式:puts(字符数组)
其作用是将一个字符串(以‘\0’结束的字符序列)输出到终端。
其一般形式:gets(字符数组)
其作用是从终端输入一个字符串到字符数组,并且得到一个函数。该函数值是字符数组的起始地址。
其一般形式:strcat(字符数组1,字符数组2)
其作用是把两个字符数组中的字符串链接起来,把字符串2接到字符串1的后边,结果放在字符数组1中,函数调用后得到一个函数值——字符数组1的地址。
其一般形式:strcpy(字符数组1,字符串2)
其作用是将字符串2复制到字符数组1中。
其一般形式:strcmp(字符串1,字符串2)
其作用是比较字符串1和字符串2。
字符串比较规则:将两个字符串自左至右逐个字符相比(按ASCII码值大小比较),直到出现不同的字符或遇到‘\0’为止。
(1)如全部字符相同,则认为两个字符相等。
(2)若出现不相同的字符,则以第一对不相同的字符的比较结果为准。
(3)如果参加比较的两个字符串都由英文字母组成,则在英文字典中位置在后面的为“大”.但应注意小写字母比大写字母“大”。
比较的结果由函数值带回。
(1)如果字符串1=字符串2,则函数值为0。
(2)如果字符串1>字符串2,则函数值为正整数。
(3)如果字符串1<字符串2,则函数值为负整数。
其一般形式:strlen(字符数组)
其作用是测试字符串长度的函数,函数的值为字符串的实际长度(不包括‘\0’)。
其一般形式:strlwr(字符串)
函数作用是将字符串中大写字母换成小写字母。
其一般形式:strupr(字符串)
函数作用是将字符串中小写字母换成大写字母。
注意:在使用字符串处理函数时,应当在程序文件的开头用#include
类型名 函数名()
{
函数体
}
或
类型名 函数名(void)
{
函数体
}
类型名 函数名(形式参数列表)
{
函数体
}
类型名 函数名()
{
}
在调用函数过程中,系统会把实参的值传递给被调用函数的形参。
(1)函数类型 函数名(参数类型1参数名1,参数类型2参数名2……);
(2)函数类型 函数名(参数类型1,参数类型2……);
(1)在函数的开头定义
(2)在函数内的复合语句内定义
在函数之外定义的变量称为外部变量,外部变量就是就是全局变量。他的有效范围从定义开始到本源文件结束。
指针:就是内存的地址编号
指针变量:用来存放地址变量,通常所说的指针就是指针变量
定义指针 :格式 指针所指向的数据类型 *指针变量名称 int * a
作用 在定义变量的时候,*是一个类型说明符,说明定义这个变量是一个指针变量,在不是变量定义的时候,它是一个操作符,访问指针所指向的存储空间
(1)先定义指针变量然后初始化 int num=10 int *p ;
如果指针只有定义没有初始化,那么它里面是垃圾值,也就是它指向是不确定的,那么此时我们称这个指针为野指针
(2) 不能给指针变量直接赋值一个整形的数值
(1) 指针作为函数参数
1: 指针作为函数参数传递是地址传递
2:如果你仅仅是在被调函数中,去修改变量本身的值,是不会影响函数中变量的值的
3 基本数据类型作为函数参数是值传递
4 数组作为函数参数是地址传递
(2) 指针作为函数的返回值(指针函数)
1 不能使用局部变量的指针作为函数的返回值
2 可以是指向堆内存和常量去的指针作为函数返回值
(3) 函数指针:指向函数指针
格式:所指向的函数的返回值类型(*指针变量名称)(所指向的函数的形藏列表)
(4)写一个函数指针的步骤
1、把要指向的函数的头拷贝过来
2、用小括号把函数名称扩起来
3、在函数名称前面加 *
4、修改函数名称为指针变量名称
让函数指针指向某个函数 pointer = 函数名称 同过函数指针调用 pointer(实参列表)
注意点:函数指针与所指向的函数,返回值类型和形参列表必须一致
(1) 一维数组 1.1 指针像一个数组 使用数组方式和使用指针方式都可以去访问数组中某个元素
array[1] == pointer[1] == *(array+1) == *(pointer+1)
1.2 array = &array pointer != &pointer
1.3 指针的指向可以改变的,数组的指向时不可以改变的
1,4 当把一个数组赋值给一个指针变量的时候,有些信息就丢失了sizeof(array)!=sizeof(pointer)
(2) 指针数组:元素为指针的数组 指针类型 数组名称[数组的元素个数] 比如: int *nums[5];
(3) 数组指针:数组中元素数据类型(*pointer)[所指向的一维数组元素个数]
数组指针与二维数组的数组名称相似
(4) 指针与二维数组 int nums[2][3] ={ {12,13,14},{15,16,17}};
int (*pointer)[3] = nums;
*(nums+1) == nums[1] == *(pointer+1)它是加上一个一个一维数组所占用存储空间的字节数 int *p = nums[1] +1 == &num[1][1]
(1) 保存字符串的方式
1 使用char类型的一维数组 char name[]= “zxc”;
2 使用char类型的指针 char *name ="zxc"
3 区别 1 字符数组是保存在栈中的,它里面的元素是可以任意的修改的 2 字符指针是一个指向常量的区指针,字符串中的元素是不可以修改的
1 字符串数组 1 使用char类型的二维数组 char names[][20] = {"nc","qd"}; 3 字符串数组 char *names = {"nc","qd"};
(2) 内存分区
从上到下
栈:用来保存局部变量 ,它的内存由系统管理的
堆:用来存储对象的,它是由程序员管理的
全局区:用来存放全局变量和静态变量
常量区:用来存放常量,只读的
代码区:用来存放代码,只读的
(3) const关键字
1 const修改普通变量说明这个变量是只读的
2 const修改数组说明数组中元素是只读的
(4) const修饰指针
const在*前面,说明指针所指向的存储空间是制度的
const在*后面,说明指针的指向是不可以修改的
(5) const用来形参
1 函数内部不能修改函数外部的变量值
2 告诉函数的调用者你可以放心把数据传入我不会修改你的内容
5 const修饰函数的返回值
8 动态存储空间的使用
1 申请堆中的内存
int *pointer = malloc(sizeof(int));
2 使用内存
*pointer=20;
3 使用完了需要手动释放
free(pointer);
4 清空指针
pointer = NULL
注意点 1 : 不能重复释放
2 堆中的存储空间在没有释放之前必须有一个指针指向这快内存,否则永远不能释放
结构体是构造类型的一种
构造类型前面还有数组
数组的作用是用于储存一组相同类型的数据
结构体的作用是用于储存一组不同类型的数据
先定义结构体的类型
通过结构体的类型定义结构体的变量
struct 结构体类型名称{
数据类型 属性名称 ;
数据类型 属性名称 ;
};
定义结构体的变量
struct 结构体类型名称 变量名称;
定义的同时初始化
注意: 如果定义的同时初始化,那么初始化的顺序必须和结构体类型中的顺序一致
#include
int main(){
//定义结构体
struct Person{
char name;
int age;
int money;
};
//定义结构体变量同时初始化
struct Person p = {
"jack",22,1000};
return 0;
}
先定义再初始化
#include
int main(){
//定义结构体
struct Person{
char name;
int age;
int money;
};
//定义结构体变量 先定义再初始化
struct Person p;
p.name = "jack";
p.age = 22;
p.money = 100000;
return 0;
}
先定义结构体类型,在定义结构体变量
#include
int main(){
//定义结构体
struct Person{
char name;
int age;
int money;
};
//定义结构体变量
struct Person p;
return 0;
}
定义结构体类型的同时定义结构体变量
#include
int main(){
//定义结构体
struct Person{
char name;
int age;
int money;
} p; //结构体变量p
return 0;
}
因为结构体变量也会分配内存空间,所以结构体变量也有内存地址,所以可以使用指针保存结构体变量的地址
规律
定义结构体变量的指针的方法和定义普通变量的方法一样
如果指针指向了结构体变量,那么访问结构体变量的方法就有三中
(1)结构体变量.属性名称
(2)(*结构体指针变量名称).属性名称
(3)结构体指针变量名称->属性名称
磁盘上的文件,一般我们谈的文件有两种:程序文件和数据文件
(1)程序文件:源程序文件后缀为.c,目标文件后缀为.obj,可执行程序(windows环境下为.exe)。
(2)数据文件:程序运行需要从中读取的文件,或者输出内容的文件。
绝对路径:以盘符或者根目录开头的如C/D:
相对路径:以.或者…开头的,但是前提是你必须在当前目录下才能谈及相对路径。以.\开头的表示当前路径,以…\开头的表示当前路径的上一层路径。
二进制文件和文本文件的区分
假设在文件中保存一个数字1,文本文件的存储方式为‘1’;而二进制文件存储方式为00000000000000000000000000000001。以另外一种方式来说就是文本文件如果要输出到外存就必须先在存储前转换,然后以ASCII码的形式存储。而二进制文件是以二进制的形式存储。
FILE* fopen(const char* filename, const char* mode);
#include
int main(){
FILE* fp = fopen("./test.txt","r");
if(fp == NULL){
printf("fopen failed\n");
}else{
printf("fopen success\n");
}
return 0;
}
int fclose ( FILE * stream );
#include
int main(){
FILE* fp = fopen("./test.txt","r");
if(fp == NULL){
printf("fopen failed\n");
}else{
printf("fopen success\n");
}
fclose(fp);
return 0;
}
文件的读函数,就是把磁盘上的数据读取到内存中。
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
#include
int main(){
FILE* fp = fopen("./test.txt","r");
if(fp == NULL){
printf("fopen failed\n");
}else{
printf("fopen success\n");
}
char buf[1024] = {
0};
fread(buf,1,4,fp);
printf("%s\n",buf);//结果buf的内容就是fp所指向文件的内容
fclose(fp);
return 0;
}
文件的写函数,就是把内存中的数据写到磁盘上
#include
int main(){
FILE* fp = fopen("./test.txt","r");
if(fp == NULL){
printf("fopen failed\n");
}else{
printf("fopen success\n");
}
char buf[1024] = “haha”;
fwrite(buf,1,4,fp);
printf("%s\n",buf);//结果fp所指向文件的内容就是buf里面的内容
fclose(fp);
return 0;
}