地址编号:计算机为了存储数据,每一个程序在 32位 机中 占4G,
最小操作单位
是一个字节
,每一个字节都有其对应的地址,该地址就是地址编号
。指针:地址编号这个数据 的 数据类型。
指针变量:存储地址编号的 变量,其 数据类型为 指针。
注意:
在32位平台下, 地址总线是32位的, 所以地址是32位编号, 所以指针变量是32位的, 即4个字节。 在64位平台下, 地址总线是64位的, 所以地址是64位编号, 所以指针变量是64位的, 即8个字节。
代码:
#include
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 * 大小为:8 short * 大小为:8 int * 大小为:8 long * 大小为:8 float * 大小为:8 double * 大小为:8
语法:
数据类型 变量名
指针的类型:
char * 存储字符型数据的地址编号的数据类型 字符指针 short * 存储short型数据的地址编号的数据类型 短整形指针 int * 存储int型数据的地址编号的数据类型 整形指针 long * 存储long型数据的地址编号的数据类型 长整形指针 float * 存储float型数据的地址编号的数据类型 单精度浮点型指针 double * 存储double型数据的地址编号的数据类型 双精度浮点型指针 ...
如:
//案例1: int num = 10; 定义一个指针变量存储num的地址 int *p; //案例2: char c = 'a'; 定义一个指针变量存储c的地址 char *p //案例3: int *p = # 定义一个指针变量存储变量p的地址 int **p2;
注意:
如果在一行中定义多个指针变量,每个指针变量前面都需要加*来修饰 void fun05() { int a,b,c; int *p1,*p2,*p3; }
(1)、定义指针变量时,赋真实的地址
int num = 10;
int *p = #
(2)、当指针变量的值 等于 NULL
时,这种指针叫做 空指针
int *p = NULL;
(3)、当指针变量是局部变量,在其定义时没有赋值,此时系统将随机给其一个值
,这种指针称为 野指针
int *p;
作用:取地址
& 取地址符 可取区域
:只能获取变量地址
栈区
静态全局区
代码:
#include
char c = 'a';
int main(int argc, char const *argv[])
{
int num = 10;
int *p = #
printf("p = %p\n", p);
char *p2 = &c;
printf("p2 = %p\n", p2);
// int *p3 = &10; //& 取常量10的地址会报错
const int num02 = 20;
int *p4 = &num02;
printf("p4 = %p\n", p4);
return 0;
}
// 输出:
// p = 0x7ffe8dfe59f8
// p2 = 0x601040
// p4 = 0x7ffe8dfe59fc
作用:取值 或 改值(修改指针指向的地址的值)
语法:*指针变量名
#include
int main(int argc, char const *argv[])
{
int num = 10;
int *p = # //此时 * 表示 变量p是int型指针变量
printf("*p = %d\n", *p); //此时 * 表示为取值
*p = 20;
printf("num = %d\n", num);
return 0;
}
// 输出:
// *p = 10
// num = 20
指针变量 去除 变量名,剩余的就是 指针本身的类型
如:
int *p1; // int *
int **p2; //int **
int (*p)(int int);//int (*)(int,int)
...
例:
#include
int main(int argc, char const *argv[])
{
int num = 10;
int *p = # //去除变量名,剩余指针类型 int *,便于判断等号左右两边类型是否一致
printf("p = %p\n", p);
char *p2 = # //语法错误,=两边类型不一致,但是编译器会做优化,只报警告,不报error
printf("p2 = %p\n", p2);
return 0;
}
指针变量 去除 变量名与最近的一个,剩余的就是
指针
指向的数据的 类型如:
int *p1; // int int **p2; // int * int (*p)(int int); //int (int int) ...
int num = 0x01020304;
int *p = #
print("*p = %d\n", *p);
问题:num为int型变量,占4个字节,那就是4个地址(1个字节,一个地址),
那么指针变量p在存储num的地址时,是怎么存储的?存储的是哪个地址?
答:指针变量有取值宽度,如下:
指针变量的数据类型 决定了 取值宽度:
int * 取值宽度为4字节
char * 取值宽度为1字节
short * 取值宽度为2字节
...
例:与单位跨度同一代码
指针变量的数据类型 决定了 单位跨度:(就是地址在进行加减时地址增减的字节数)
int * 单位跨度为4字节
char * 单位跨度为1字节
short * 单位跨度为2字节
例:
#include
int main(int argc, char const *argv[])
{
int num = 0x01020304;
//对应的十六进制:0x0000 0001 0000 0010 0000 0011 0000 0100
//Linux系统存储是倒叙存储的:
//0000 0100 0000 0011 0000 0010 0000 0001
//0x04 0x03 0x02 0x01
int *p = #
printf("*p = %d\n", *p); //*p = 16909060
char *p2 = (char *)# //强制转换为char *类型
printf("*p2 = %d\n", *p2); //*p2 = 4
short *p3 = (short *)#
printf("*p3 = %d\n", *p3); //*p3 = 772 对应的十六进制:0x0304
printf("*p2 = %d\n", *(p2+1)); //*p2 = 3 对应的十六进制:0x03 此时p2为首个字节存储的地址+1,加的是一个单位跨度即1字节
printf("*p2 = %d\n", *(p2+2)); //*p2 = 2 对应的十六进制:0x02 步长为1,+2表示向后挪二位
printf("*p3 = %d\n", *(p3+1)); //*p3 = 258 对应的十六进制:0x0102 步长为2,+1表示向后挪二位
return 0;
}
作用:
1、当函数没有返回值时,返回值类型为void;
2、void和指针结合作为一种指针类型,如
void *
, 这种指针被称为万能指针
,意味着任何一种地址
都可以赋值
给该类型的指针变量
例:
#include
int main(int argc, char const *argv[])
{
char c = 'a';
short s = 1;
int num = 10;
char * p1 = &c;
short * p2 = &s;
int * p3 = #
printf("*p1 = %d\n", *p1);
printf("*p2 = %d\n", *p2);
printf("*p3 = %d\n", *p3);
void * p4 = &c;
void * p5 = &s;
void * p6 = #
return 0;
}
void fun01()
{
//野指针
int *p;
printf("*p=%d\n",*p);
}
void fun02()
{
//空指针
int *p = NULL;
printf("*p=%d\n",*p);
}
void fun03()
{
int num = 10;
int *p = #
printf("*p=%d\n",*p);
void *p2 = #
printf("*p2=%d\n",*p2);
}
#include
void fun04()
{
int num = 0x01020304;
int *p = #
char *p2 = (char *) p;
printf("%#p\n",*p2);
printf("%#p\n",*(p2+1));
char c = 'a';
char * p3 = &c;
//1
int *p4 = (int *)p3;
printf("%#p\n",*p4);
}
int main(int argc, char const *argv[])
{
fun04();
return 0;
}
// 输出:
// 0x4
// 0x3
// 0x2030461
案例1:以下赋值语句正确的是___
int num=10, *p=&num, **q=&p;
A:p=&num B:q =p; c:q=&num D:q=&p;
正确答案:AD
但是,Bc也可以通过,会有警告,相当于指针变量赋给二维指针变量