概述
文章目录
- 一、指针
- 1.1、指针是什么
- 1.2、指针和指针类型
- 1.2.1 指针的类型
- 1.2.2 指针的意义
- 1.3、野指针
- 1.3.1 野指针的成因
- 1.3.1.1. 指针未初始化
- 1.3.1.2 指针越界访问
- 1.3.1.3 指针指向的空间释放
- 1.3.2 如何规避野指针
- 1.4、 指针运算
- 1.4.1 指针+-整数
- 1.4.2 指针-指针
- 1.4.3 指针的关系运算
- 1.5、 指针和数组
- 1.6、二级指针
- 1.7、 指针数组
- 二、结构体
- 2.1、结构体类型的声明
- 2.1.1 结构体的基础知识
- 2.1.2 结构体的声明和创建
- 2.1.3、结构成员的类型
- 2.1.4、结构体变量的定义和初始化
- 2.2、结构体成员的访问
- 2.3、结构体传参
一、指针
1.1、指针是什么
指针是什么?
指针理解的2个要点:
- 指针是内存中一个最小单元的编号,也就是地址
- 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量
总结:指针就是地址,口语中说的指针通常指的是指针变量。
#include <stdio.h>
int main()
{
int a = 10; //a是整形变量,占用四个字节的内存空间
int* pa = &a;
// pa 是一个指针变量,指针变量里面存放的是地址,通过这个地址可以找到一个内存单元
//口语中的指针是指针变量,是用来存放地址的变量
return 0;
}
指针变量 :
- 我们可以通过&(取地址操作符)取出变量的内存其实地址,把地址可以存放到一个变量中,这个变量就是指针变量。
#include <stdio.h>
int main()
{
int a = 10; //在内存中开辟一块空间
int* p = &a; //这里我们对变量a,取出它的地址,可以使用&操作符。
//a变量占用4个字节的空间,这里是将a的4个字节的第一个字节的地址存放在p变量
//中,p就是一个之指针变量。
return 0;
}
总结 :
指针变量,用来存放地址的变量。(存放在指针中的值都被当成地址处理)。
指针变量的大小 :
- 在32位的机器上,地址是32个0或者1组成二进制序列,那地址就得用4个字节的空间来存储,所以一个指针变量的大小就应该是4个字节。
- 那如果在64位机器上,如果有64个地址线,那一个指针变量的大小是8个字节,才能存放一个地址。
简单来说:
- 指针变量是用来存放地址的,地址是唯一标示一块地址空间的。
- 指针的大小在32位平台是4个字节,在64位平台是8个字节
1.2、指针和指针类型
1.2.1 指针的类型
这里我们在讨论一下:指针的类型 我们都知道,变量有不同的类型,整形,浮点型等。
那指针有没有类型呢? 准确的说:有的。
int num = 10;
p = #
要将&num(num的地址)保存到p中,我们知道p就是一个指针变量,那它的类型是怎样的呢?
我们给指针变量相应的类型。
#include <stdio.h>
int main()
{
char* pc = NULL;
short* ps = NULL;
int* pi = NULL;
double* pd = NULL;
//sizeof返回值是无符号整形 unsiged int
printf("%zun", sizeof(pc)); // 4
printf("%zun", sizeof(ps)); // 4
printf("%zun", sizeof(pi)); // 4
printf("%zun", sizeof(pd)); // 4
return 0;
}
这里可以看到,指针的定义方式是: type + * 。
其实:
- char* 类型的指针是为了存放 char 类型变量的地址。
- short* 类型的指针是为了存放 short 类型变量的地址。
- int* 类型的指针是为了存放 int 类型变量的地址。
1.2.2 指针的意义
意义 1 :
#include <stdio.h>
//指针的意义
//十六进制
// 0 1 2 3 4 5 6 7 8 9 a b d e f
int main()
{
int a = 0x11223344;
//int* pa = &a;
//*pa = 0;
char* pc = (char*)&a;
*pc = 0;
//从下面图可以看出 a 从 44 33 22 11 在 int 类型中完全变成了 00 00 00 00
//而在 char 类型中变成了 00 33 22 11
//结论1 ;
//指针类型决定了指针在被解引用时访问几个字节
//如果 int* 的指针,解引用访问4个字节
//如果 char* 的指针,解引用访问1个字节
//double* 的指针,8个字节
return 0;
}
意义 2 :
注 :int 和 float 不可以混用**
1.3、野指针
概念: 野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)
1.3.1 野指针的成因
1.3.1.1. 指针未初始化
#include <stdio.h>
int main()
{
int* p;
//p没有初识话,就意味着没有明确的指向
//一个局部变量不初始化,放的是随机值:0xcccccc
*p = 10;//非法访问内存了,这里的p就是野指针
return 0;
}
1.3.1.2 指针越界访问
#include <stdio.h>
int main()
{
int arr[10] = { 0 };
int* p = arr;
int i = 0;
for (i = 0;i <= 11;i++)
{
//当指针指向的范围超出数组arr的范围时,p就是野指针
*p = i;
p++;
}
return 0;
}
1.3.1.3 指针指向的空间释放
#include <stdio.h>
int* test()
{
int a = 10;
return &a;
}
int main()
{
int* p = test();
return 0;
}
1.3.2 如何规避野指针
- 指针初始化
- 小心指针越界
- 指针指向空间释放即使置NULL
- 避免返回局部变量的地址
- 指针使用之前检查有效性
#include <stdio.h>
int main()
{
int* p = NULL;//不知道初始化什么值,就初始化NULL
if (p != NULL)//可以这样初始化
{
*p = 20;
}
return 0;
}
1.4、 指针运算
1.4.1 指针±整数
#include <stdio.h>
int main()
{
int arr[10] = { 0 };
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
int* p = arr;
for (i = 0;i < sz;i++)
{
//指针+-整数;指针的关系运算
*p = 1;
p++;
}
return 0;
}
1.4.2 指针-指针
例一 :
#include <stdio.h>
int main()
{
int arr[10] = { 0 };
printf("%dn", &arr[9] - &arr[0]);
//指针减指针的绝对值得到的是指针之间元素的个数
//指向同一个空间的自己真才有意义!!!!!!
return 0;
}
例二 :
#include <stdio.h>
int my_strlen(char* str)
{
char* start = str;
while (*str !='