学习的过程也是一种成长的过程,让自己更加成熟和自信
指针基础
概述
地址编号:就是计算机为了数据存储,每一个在32位机中占用4G,以一个字节(4B)为最小单位进行操作,每一个字节都有其对应的地址,该地址就是地址编号。(地址编号就是内存地址)
指针:地址编号的数据类型
指针变量:存放地址编号的变量,其数据类型为指针
32位机中一个指针占4B
64位机中一个指针占8B
如:
#include <stdio.h>
int main(int argc, char const *argv[])
{
printf("char * = %ld\n",sizeof(char *));
printf("short * = %ld\n",sizeof(short *));
printf("int * = %ld\n",sizeof(int *));
printf("long * = %ld\n",sizeof(long *));
printf("float * = %ld\n",sizeof(float *));
printf("double * = %ld\n",sizeof(double *));
return 0;
}
指针变量
定义
语法
数据类型 *指针变量名
指针的类型
char * 存储字符型数据类型的地址编号 字符指针
short * 存储short型数据类型的地址编号 短整型指针
int * 存储int型数据类型的地址编号 整型指针
long * 存储long型数据类型的地址编号 长整型指针
float * 存储float型数据类型的地址编号 单精度浮点型指针
double * 存储double型数据类型的地址编号 双精度浮点型指针
如
案例1:int num = 10; 定义一个指针变量存储num的地址
int *p;
案例2: char x = 'a';定义一个指针变量存储x的地址
char *p;
案例3:int *p = &num;定义一个指针变量存储变量p的地址
int **p;
注意
如果在同一行中定义多个指针变量,每个指针变量前面都需要加 * 来修饰
void fun05()
{
int a,b,c;int *p,*p1,*p2;
}
初始化
1.当指针变量是局部变量时,定义时并未给予固定值,此时系统将随机为其给一个值,该指针就会称之为野指针
如:
int *p;
2.当指针变量值为NULL时,该指针称之为空指针
如:
int *p = NULL;
3.定义指针变量时赋予真实的地址
int num = 10;
int *p = &num;
运算符
&
含义:取地址
&要取地址的变量
注意:只能获取变量的地址
示例
#include <stdio.h>
char c = 'a';
int main(int argc, char const *argv[])
{
int num = 10;
int *p = #
printf("p = %p\n",p);
char *x = &c;
printf("x = %p\n",x);
//int *j = &10; ❌
const int nums = 10;
int *j = &nums;
printf("j = %p\n",j);
return 0;
}
*
取值或改值
*指针变量名
例如:*p = 1;
示例
#include <stdio.h>
int main(int argc, char const *argv[])
{
int num = 10;
int *p = #
printf("num = %d\n",*p);
*p = 1;
printf("num = %d\n",num);
return 0;
}
指针的类型
指针本身的类型
口诀:将指针变量的变量名去除,剩余的就是指针本身的类型
int *p; //int *
int **p1 //int **
int (*p)(int int); //int (*)(int,int)
....
示例
int num = 10;
int *p = &num;
char *p1 = #
指针指向数据的数据类型
口诀:将指针变量去除变量名与最近的一个*,剩余的就是指针指向的数据类型
如
int *p; // int
int **p1; //int *
int (*p)(int int); //int (int,int)
....
取值宽度
注意:
指针变量的数据类型说明了取值宽度
chart * 取值宽度为1字节
short * 取值宽度为2字节
int * 取值宽度为4字节
....
单位跨度
就是地址在进行加减时地址增减的字节数
chart * 单位跨度为1字节
short * 单位跨度为2字节
int * 单位跨度为4字节
#include <stdio.h>
int main(int argc, char const *argv[])
{
int num = 0x01020304;
char *p = (char* )#
printf("p = %#p\n",*(p+1));
short *p1 = (short *) #
printf("p = %#p\n",*(p1+1));
return 0;
}
注意:
(1)在Linux系统中数据存储为倒叙存储与取值, 0x04 03 02 01
将num地址强制转换为char *类型,此时取值宽度为1字节,单位跨度为1字节
p为首个字节存储的地址+1,加的是一个单位跨度即为一个字节
所以从第二个字节开始取1个字节长度的数据,即为0x03
(2)将num地址强制转换为short *类型
此时取值宽度为2字节,单位跨度为2字节
p为首字节存储的地址+1,加的是一个单位跨度即为2字节
所以从第三个字节开始取2个字节长度的数据,即0x0102
void
作用
1.当函数没有返回值类型时为void
2.void与指针结合作为一种指针类型,如void *,这种指针称之为万能指针,意味着任何一种地址都可以赋值给类型的指针变量
#include <stdio.h>
int main(int argc, char const *argv[])
{
int num01 = 10;
char c = 'a';
short s = 1;
int *p1 = &num01;
char *p2 = &c;
short *p3 = &s;
void *p4 = &num01;
void *p5 = &c;
void *p6 = &s;
return 0;
}
指针变量使用的注意事项
1.野指针操作会出现段错误
void fun()
{
int *p;
printf("p = %d\n",*p);
}
2.空指针操作会出现段错误
void fun1()
{
int *p =NULL;
printf("%d",*p);
}
3.不能对万能指针进行操作
void fun2()
{
int num = 0;
void *p = #
printf("%d",*p);
}
4.操作指针变量不要越界(可以但不要)
void fun3()
{
int num = 0x01020304;
int *p = #
char *p2 = (char *) p;
printf("%#p\n",*p2);
printf("%#p\n",*(p2+1));
char c = 'a';
char * p3 = &c;
int *p4 = (int *)p3;
printf("%#p\n",*p4);
}