C语言高级部分学习总结二

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:自己复习整理,仅供参考

本文学习总结关于C语言高级部分的第二部分,指针与结构体


提示:以下是本篇文章正文内容,案例可供参考。欢迎指正交流学习。

一、字符串函数

使用字符串函数时需要引用头文件:#include<string.h>

1.字符数组的输入输出

字符数组的输入输出可以像前面的输入输出数字一样,用格式输入输出控制符。
1、逐个字符串输入输出,用格式%c输入或者输出一个字符
2、将整个字符串一次输入或者输出,用%s格式符
也可以用 puts和gets函数
puts(字符数组):其作用是将一个字符串输出到终端,因此噶函数用的不是很多,我们可以编写一个小程序实现。

gets(字符数组):其作用是从终端输入一个字符串到字符数组,并得到一个函数值。
注意:
gets函数读取字符串,直到遇到回车符或遇到EOF停止读取
gets函数缺陷:只知道输入目标的地址,不知道需要需要输入的目标大小,可能会造成栈内存溢出
在这里插入图片描述

2.stract 函数-字符串连接函数

stract(字符数组1,字符数组2);
功能:
把两个字符数组中的字符串连接起来,把字符串2接到1后面,结果放到字符串1中。
注意:
1、连接前两个字符串后面都有’\0’;连接时将字符串1后面的’\0取消,只在新串后面保留’\0’
2、字符串1必须足够大,以便于容纳字符串2。

3.strlen 函数-测字符串长度的函数

strlen(字符数组)
功能:
它测量字符串长度的函数。函数的值为字符串中的实际长度。

sizeof和strlen的区别
1.	strlen是一个库函数使用时需要引用#include<string.h>这个头文件,而sizeof是一个运算符号;

2.strlen计算的是'\0'之前的字符个数,sizeof计算的是所占空间内存的大小,单位是字节;

3.strlen计算时不包含'\0',而sizeof包含'\0';

4.strlen遇到'\0'才结束;

5.sizeof的类型是unsigned int ,是一个无符号的整型;

6.strlen只能用char做参数,sizeof可以用任何类型做参数;

4.strcpy 函数-字符串复制函数

strcpy(字符串1,字符串2)
功能:
将字符串2复制到字符串1中。
注意:
1、字符数组1必须定义的足够打,以便容纳被复制的字符串2。
2、字符数组1必须写成数组名形式(如str1),字符数组2可以是字符数组名,也可以是一个字符串常量。
3、不能用赋值语句将一个字符串常量直接给一个字符数组。

5.strcmp 函数-字符串比较函数

strcmp(字符串1,字符串2)
功能:
比较字符串1和字符串2.
比较规则:
将两个字符串自左向右逐个字符比较(按ASCLL码值大小比较),知道出现不同的字符或者遇到’\0’为止。
1、如果全部字符相同,则认为两个字符串相同。
2、若出现不同的字符,则以第1个对不相同的字符的比较结果为准。
3、比较结果由函数值带回。
字符串1=字符串2,则函数值为0;
字符串1>字符串2,则函数值为一个正整数
字符串1<字符串2,则函数值为一个负整数。

二、指针

指针变量是一种特殊的变量,他存放的不是数据,而是另一种变量的地址。这个存放数据的变量被称为指针变量所指向的目标变量。由于通过指针变量中的地址可以直接访问它指向的目标变量,常把指针变量简称为指针

1.指针概念:

int main()
{
	int a=10;
	int b=20;
	int *p=&a;//
	p=&b;//等同于int *p=&b;
	printf("%d: "p);
}

指针变量是一种存放地址的特殊变量,其特殊性表现在类型和值上。从变量的角度讲,指针变量也具有变量的要素:
指针变量的命名,与一般变量命名相同,遵循c语言的命名规则。
指针变量的类型,是指针变量所指向的变量的类型,而不是自身的类型。

定义指针变量
定义指针变量的一般形式为:
类型名 *指针变量名

int *point_1,*point_2;//只能用来指向整型的指针变量

注意:
定义指针变量时,指针变量前面的“*”号表示该变量的类型为指针型变量。
point_1表示的是变量的值,
point_1表示变量的地址。
定义指针变量和取值的时候一定要加上“

引用指针变量

//1.给指针变量赋值
p=&a;//把a的地址给指针变量p

//2.引用指针变量指向的变量。
*p=1;//表示将整数1赋值给p当前所指向的变量,如果p指向变量a相当于,把1赋值给a,即a=1
printf("%d",*p);
//3.引用指针变量的值
printf("%o",p);//以八进制形式输出指针变量P的值,如果p指向了a,就是输出了a的地址,即&a.

//

例题:指针p指向变量a,修改a的值为10
在这里插入图片描述
指针偏移
在这里插入图片描述

插入一起定义的单个变量,地址相互之间没有必然联系,可能分散,可能连续;
地址+1,表示偏移一个存储单元,存储单元字节数和类型相关
在这里插入图片描述
++在值上,就是值改变;++在地址上就是地址偏移;
++和*优先级一样高;优先级一样高,结合方向从右往左

空指针和野指针:
在这里插入图片描述
在这里插入图片描述
指针要先指向一块既定内存,比如这里的p=&a;防止出现野指针和空指针

**和普通变量一样,指针变量也可以被多次写入,只要你想,随时都能够改变指针变量的值

"是一个特殊符号,表明一个变量是指针变量,定义 p1、p2 时必须带"”。而给 p1、p2 赋值时,因为已经知道了它是一个指针变量,就没必要多此一举再带上"",后边可以像使用普通变量一样来使用指针变量。也就是说,定义指针变量时必须带,给指针变量赋值时不能带。
对星号
的总结
在我们目前所学的语法中,星号*主要有三种用途:
1、表示乘法
2、表示定义一个指针变量
3、表示获取指针指向的数据

2.指针作为函数参数

函数的参数不仅可以是整型,浮点型等数据,也可以是指针类型。他的作用是将一个变量的地址送到另一个函数中。
两数之间求较大值,被调函数返回最大值地址
在这里插入图片描述

3.数组指针

数组指针:是指向数组的指针,它还是一个指针,只不过指向数组而已
行指针定义形式:int (p)[10] 一定要加(),因为[]优先级高于,所以必须要(*p)指一行,这里10为列的元素个数
在这里插入图片描述

4.指针数组

指针数组:实际是一个数组,长度是由数组本身决定,这个数组的所有元素都是指针类型,存放的都是地址。
指针数组是一个由指针变量组成的数组,也就是说其中的元素都是指针变量。

指针数组的声明:
类型 *数组名[常量表达式]

int *ptr[MAX];

在这里插入图片描述
const限定一个变量不允许被改变,产生静态作用;使用const在一定程度上可以提高程序的安全性和可靠性。
1、const int Maxnum=100; const让Maxnum不能被修改;Maxnum=90;//错误
单独使用const可以被define命令代替
2、const和指针
(1)const int *p1;
(2)int const p2;
//上面这两种情况,指针指向的数据是只读,p1,p2本身的值可以更改
(3)int
const p3;//指针是只读,p3本身的值不能更改
3、const和函数形参
防止在函数内部修改指针指向的数据
size_t strlen(const char *str);

5.二维数组传参的常见方式

1、传递一个二维数组
str[][3]
在这里插入图片描述
(*str)[3]
在这里插入图片描述
2、传递一个指针数组

先创建char*型的数组,这个数组的每个元素是这个字符串数组中每个字符串地址
在这里插入图片描述

6.函数指针:

函数指针指向函数的指针
指针,指向函数的指针
声明格式:数据类型 (*函数名)(参数) 函数名就是函数的入口地址
在这里插入图片描述
在这里插入图片描述

三、结构体、

结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合,叫做结构体。
结构体同时也是一些元素的集合,这些元素称为结构体的成员。
为了定义结构体,必须使用struct语句。struct语句定义了一个包含多个成员的新的数据类型。
定义方式:
struct 结构体名{
成员列表
};//注意不忘记这里的;

struct student//student是结构体名
{
//定义成员列表:类型名 变量名
	int num;
	int c_score;
	int ps_score;
	float avg;
}Tom;//Tom是结构体变量
//这里不再是定义声明结构体类型,而是直接创建了结构体变量,这个编译器就会分配内存

也可以用一下方法声明结构体变量
1、间接声明

struct student//student是结构体名
{
//定义成员列表:类型名 变量名
	int num;
	int c_score;
	int ps_score;
	float avg;
};
struct student Tom={};//声明结构体变量

2用别名

typedef struct student//student是结构体名
{
//定义成员列表:类型名 变量名
	int num;
	int c_score;
	int ps_score;
	float avg;
}Tom;//Tom是结构体别名

Tom list={};//list为结构体变量
//等同于
struct student list={}//list为结构体变量  

结构体变量的声明与普通变量的声明类似都是
(类型) 变量名
(int)Tom;
(struct student) Tom;

成员列表的写法:
类型标识符 成员名;
引用结构体变量中成员的值,应用方式:
结构体变量名.成员名
Tom.num;
.是成员运算符

结构体命名要符合命名规范,其次结构体名要具有意义
struct 结构体名:表示一种结构体类型
结构体定义完成,系统不会为其分配内存空间,只是构造出了一种类型,如果要使用该类型,需要定义该类型的变量。
结构体外面的大括号不能省略。
结构体可以被声明为变量、数组、指针等。

结构体变量的定义
结构体类型的定义(结构体声明),告诉编译器该如何表示数据
如果要使用结构体,必须要创建变量,也就是结构体变量,结构体变量的定义方式。
例题:
有n个学生的信息(包括学号、姓名、成绩),找出成绩最高的学生,输出该学生信息
在这里插入图片描述
结构体指针如何访问结构体成员变量
结构体指针->成员变量
(*结构体指针).成员变量
在这里插入图片描述

三、共用体、

共用体(Union)是一种特殊的数据类型,允许在相同的内存空间中存储不同的数据类型。共用体中的所有成员共享同一块内存空间,只能同时存储其中一个成员的值。

共用体的定义由关键字union开头,后面跟着成员列表,每个成员由数据类型和成员名称组成。共用体的大小取决于其中最大的成员的大小。

共用体的使用方式类似于结构体,可以通过成员名称来访问共用体中的数据。但不同的是,共用体中的成员只能一个一个地使用。当一个成员的值被修改后,其他成员的值会被覆盖。

共用体的主要应用场景是在节省内存空间的情况下存储多个不同的数据类型。例如,可以用共用体来表示一个变量可能是整数、浮点数或者字符的情况。

在这里插入图片描述
同一时间只能用到一个成员

总结

以上就是今天要讲的内容.
一、typedef 和define的区别:
1、定义不同:
define后面不加“;”,typedef后面加“;”
2、原理不同:
define宏定义,单纯替换。在编译的预处理阶段奇幻,不进行运算。
typedef是给数据类型起别名,起的名字可以代替类型直接使用。
3、作用域不同:
#define 没有作用域限制,只要之前预定义的宏,以后程序都能用。
typedef有自己的作用域
二、&名字 *名字
取地址 &名字
解地址 名字
指针之间赋值: 浅拷贝
空指针 :NULL
坏指针:指针变量的值是NULL 或者一个未知的地址值。
void 空类型 :编译器不允许void
类型的指针做接指针操作。
指针数组:是指一个数组里面装的全是指针,也即指针数组是一个数组
int *a[];

数组指针:是指一个指向数组的指针,它还是一个指针,只不过指向数组而已
int(*p)[10];一定要加(),因为[]优先级高于"**",所以(*p)
上面表示指一行数据。

static 不是指存储方式,而是指对函数的“作用域”仅局限于本文件。即可以延长局部变量的生命周期

静态全局变量:改变全局变量可见性。静态全局变量在声明它的文件之外是不可见的,仅从定义该变量开始的位置到文件结尾可见。

静态局部变量:改变局部变量的销毁时期。局部变量作用域结束,生命周期结束;静态局部变量离开作用域不会被销毁,再次调用该函数,该变量值为上次函数调用结束的值。
静态函数:改变函数可见性。

  • 16
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值