指针
1.动态内存
2.字符串与指针
3.指针作为函数返回值
4.指针数组
5.数组指针
6.指针的指针
7.结构体指针
动态分配内存:
int i = 10;
int *p = &i;
就是跟系统申请一块内存,然后将该块内存的起始地址给了p。而这个地址不是固定的,所以称为动态分配内存。
动态分配内存涉及到几个常用函数:malloc(),free(),calloc()。 这些函数声明放在 stdlib.h头文件中。
malloc函数
用于跟系统申请一块内存,这块内存的大小有参数决定,而参数的单位为字节(Byte)。然后将申请后的其实内存地址返回,我们就可以使用指针变量来接收这个地址,建议将这个地址强制转换成对应的指针类型
如:int *p1 = (int *)malloc(sizeof(int) * 100); //申请一个占100个整型变量的内存空间
float *p3 = (float *)mallco(sizeof(float) * 100); //申请一个占100个float变量的内存空间
申请内存空间,需要判断成与否,如果不成功,就会返回空指针(NULL)
if(p1 != NULL)
{
printf("动态内存申请成功");
}
else
{
return 0; //main函数遇到return会结束
}
使用malloc()函数申请内存后一旦使用完毕,需要释放内存,否则那块内存就变成了垃圾内存
使用方法:free(p1);
free()函数只能释放动态分配的内存空间,不能任意的释放内存
calloc()函数同样可以申请内存,但数值分配完毕后数值初始化为0
字符串与指针:
指针变量可以指向一个字符数组
char str[] = "Hello World!"; char *p = str; 此时printf("%s\n",p); 输出Hello World!
printf()函数中控制字符串%s,代表要打印一个字符串,后面传入的参数需要的是字符数组的名称(其实就是字符数组首元素的地址),p4中存放的就是这个字符数组的首元素地址。printf()函数会一直将该字符串打印到结尾,知道遇到末端字符 '\0'
如果想要存储20个字符,那么定义的长度应该是21个字节,因为还有一个末端字符
char *p5;
p5 = (char *)malloc(sizeof(char)*21);
指针处理二维数组:
2个for循环来访问二维数组:*(*(string+i)+j)
指针作为函数返回值
使用指针,可以返回一个数组,因为数组名就是一个地址,我们可以使用指针来代替
指针作为函数返回值基本形式如下:
类型标识符 *函数名(参数列表)
需要注意函数返回指针指向的 数据类型 是类型标志符 所标识的类型(int ,float,double,char)
指针数组:
是一个数组,该数组中的每一个元素还是指针,而这些指针可以继续指向其他的地址
例如:int *p[4];
这里的中括号优先级比*号要高,先结合p[4],这是数组,再与前面的*结合,表示指针类型
数组指针:
是一个指针变量,我们定义出来的指针变量中存放的地址必须是数组的地址才行,其他的数据类型的地址不可以存放到这个指针变量中。
定义代码如下:
(*p)[4];
注意:(*p)的括号不能省略,省略了*p[4]就是一个指针数组了,该指针只能指向一个包含4个整数元素的一维数组,不能单独指向数组中的某一元素
指向指针的指针:
定义一个指针变量指向一个地址,而这个低智商存储的又是一个存储数据,而该指针数据指向的才是实际的数据
指针的指针 定义的形式:
int **p;
结构体指针变量:
意思说指针变量指向的是一个结构体,
结构体指针变量中的值是指向结构体变量的首地址
结构体指针变量声明的一般形式:
struct 结构体名称 *结构体指针变量
或者
typedef struct 定义的结构体名 *结构体指针变量名 (一般使用这种形式)
通过结构体访问结构体变量的成员的一般形式:
(*结构体指针变量).成员变量
或者
结构体指针变量 -> 成员名