分析等号两边的数据类型一致
二级指针
概念
又名:指针的指针
因为指针变量的本质也是一个变量,在32位机中占4字节,在64位机中占8字节
如
int a=10; //假设此时a在栈内的地址编号为0x00 00 00 00,长度4字节
int *p=&a; //将a的地址赋值给变量p,此时p存储的地址为a的地址。即0x00 00 00 01,
p本身也需占用内存,其地址假设为0x00 00 00 06
int **p2=&p; //将p的地址即0x00 00 00 06赋值给p2,p2本身也是变量,顾问也需
占用内存,其地址假设为0x00 00 00 14,该指针就是二级指针;
int ***p3=&p2; //该指针就是三级指针
...
问题
1.二级指针使用*取出的是什么?
存储的一级指针本身的地址,不是一级指针存储的地址
int num01=10;
int num02=1;
int *p1=&num01;
int *p2=&num02;
*p1=100;
printf("num01=%d\n",num01);
printf("num02=%d\n",num02);
int **p3=&p1;
*p3=p2;
printf("num01=%d\n",num01); //100
printf("num02=%d\n",num02); //1
printf("**p3=%d\n",**p3); //1
void与指针
void作用
1,void作为函数的返回值类型,表示没有返回值或返回值为NULL
void test()
{
for(int i = 0; i < 10; i++)
{
xxx
if(xx)
{
return;
}
}
}
2,void与指针结合称为万能指针,可以存储任何一种类型变量的地址
int num = 10;
int *p1 = #
char c = 'a';
char *p2 = &c;
void *p3 = #
void *p4 = &c;
p3 = &c;//
修改
p3
存储的地址
万能指针的作用
万能指针主要用于作为函数的形参
万能指针的注意事项
不能直接对void *p中的p直接取*,因为无法确定p的取值宽度
const与指针
常量指针
概念
指向常量的指针,本质是一个指针
作用
不能通过指针改变其指向的地址的类型,但是可以改变其存储的地址
语法
const 数据类型 *指针名
或
数据类型 const *指针名
示例
#include <stdio.h>
int main(int argc, char const *argv[])
{
int a = 10;
int b = 1;
//
常量指针
,
本质是指针
,
可以修改其存储的地址
,
但是无法修改其存储的地址对应
的值
//const int *p = &a;
int const *p = &a;
p = &b;//
改变
p
存储的地址
//*p = 100;//
改变
p
存储的地址对应的值
,
此处报错
return 0;
}
指针常量
概念
本质是一个常量,该指针存储的地址无法修改,但是可以修改其存储的地址对应的值
语法
数据类型 *const 指针名;
示例
#include <stdio.h>
int main(int argc, char const *argv[])
{
int a = 10;
int b = 1;
//
指针常量
,
本质是一个常量
,
不能修改其存储的地址
,
但是可以修改其存储的地址
对应的值
int * const p = &a;
//p = &b;//
不可以改变
p
存储的地址
*p = 100;//
改变
p
存储的地址对应的值
printf("a = %d\n",a);
return 0;
}
常量指针常量
概念
常量指针指向常量
语法
const 数据类型 * 指针类型;
或
数据类型 const * 指针名;
示例
#include <stdio.h>
int main(int argc, char const *argv[])
{
int a = 10;
int b = 1;
//
常量指针常量
//const int * const p = &a;
int const * const p = &a;
p = &b;//
不可以改变
p
存储的地址
*p = 100;//
也不可以改变
p
存储的地址对应的值
printf("a = %d\n",a);
return 0;
}
数组与指针
数组名的本质
数组名就是数组中第一个元素的地址
示例1
#include <stdio.h>
int main(int argc, char const *argv[])
{
int nums[] = {1,5,10};
printf("nums
的地址
= %p\n",nums);
printf("nums[0]
的地址
= %p\n",&(nums[0]));
int *p = nums;
printf("nums[1] = %d\n",nums[1]);//
取数组下标为
1
的元素
printf("p[1] = %d\n",p[1]);//
取数组下标为
1
的元素
//1
个步长
=
数组中存储的元素的数据类型所占的字节数
printf("*(p+1) = %d\n",*(p+1));//
将当前位置
+1
个步长
,
取的是数组下标为
1
的元素
printf("*p+1 = %d\n",*p+1);
return 0;
}
示例2
#include <stdio.h>
int main(int argc, char const *argv[])
{
char str[] = "hIc";
char *p = str;
//
此时数组中存储的元素为
char,
一个
char
的长度为
1
字节
,
顾此时
1
个步长
=1
字节
printf("%c\n",*(p+1));
printf("%c\n",*(p+2));
printf("%c\n",*(p+3));
printf("%c\n",*p+1);//*p
获取的是其地址对应的值
,
其地址的值为
h,h+1=i
printf("%c\n",(*p)+1);
return 0;
}
指针数组与数组指针
概念
数组指针(数组的指针):指向数组,本质是指针
指针数组(存储指针的数组):本质是一个数组
示例1
#include <stdio.h>
int main(int argc, char const *argv[])
{
int nums[] = {1,2,3};
//
数组指针
(
数组的指针
,
指向数组
,
本质是指针
)
int *p = nums;
int a = 1;
int b = 2;
int c = 3;
int *p11 = &a;
int *p12 = &b;
int *p13 = &c;
//
指针数组
(
存储指针的数组
,
本质是一个数组
)
int *p2[] = {p11,p12,p13};
return 0;
}
示例2
#include <stdio.h>
int main(int argc, char const *argv[])
{
int nums01[] = {1,2,3,4,5};
int nums02[] = {11,22,33,44,55};
int nums03[] = {111,222,333,444,555};
//
二维数组
int nums04[][5] = {
{1,2,3,4,5},
{11,22,33,44,55},
{111,222,333,444,555}
};
//
指针数组
int *ps[]={nums01,nums02,nums03};
printf("nums04[0][1] = %d\n",nums04[0][1]);
printf("ps[0][1] = %d\n",ps[0][1]);
printf("nums04[1][1]
的
=%d\n",nums04[1][1]);
printf("(*(ps+1))[1]=%d\n",(*(ps+1))[1]);
printf("*(*(ps+1)+1)=%d\n",*(*(ps+1)+1));
return 0;
}
示例3
#include <stdio.h>
int main(int argc, char const *argv[])
{
// char strs[][50] = {"GaoLei","WangChenHui","YueZheng"};
char *strs[] = {"GaoLei","WangChenHui","YueZheng"};
printf("strs[0] = %s\n",strs[0]);
printf("strs[1] = %s\n",strs[1]);
printf("strs[2] = %s\n",strs[2]);
printf("*(strs+0) = %s\n",*(strs + 0));
printf("*(strs+1) = %s\n",*(strs + 1));
printf("*(strs+2) = %s\n",*(strs + 2));
printf("(*(strs + 0))+3 = %s\n",(*(strs + 0))+3);
printf("(*(strs + 0))[3] = %c\n",(*(strs + 0))[3]);
return 0;
}
示例4
#include <stdio.h>
int main(int argc, char const *argv[])
{
// char strs[][50] = {"GaoLei","WangChenHui","YueZheng"};
char *strs[] = {"GaoLei","WangChenHui","YueZheng"};
printf("strs[0]
的地址
=%p\n",&strs[0]);
printf("strs
的地址
=%p\n",strs);
printf("&strs
的地址
=%p\n",&strs);
char * p;
p = strs;
//char **p2 = &p;
//char **p2 = &strs;
char **p2 = strs;
printf("*p2 = %s\n",*p2);
printf("**p2 = %c\n",**p2);
printf("*(p2+1) = %s\n",*(p2+1));
printf("*(p2+2) = %s\n",*(p2+2));
printf("(*(p2+1))+4 = %s\n",(*(p2+1))+4);
return 0;
}
函数与指针
函数名的本质
函数名的本质上就是函数在代码区存储的首地址
函数指针
作用:
记录函数的地址
语法:
返回值类型 (*指针名称)(指向的函数的形参列表的数据类型) = 函数名;
注意
:
形参列表的数据类型可有可无
函数指针调用函数
指针名
(
实参列表
);
变量名
=
指针名
(
实参列表
);
示例
#include <stdio.h>
extern void add(int a,int b);
extern void sub(int a,int b);
extern void test(void (*p)(int,int));
int main(int argc, char const *argv[])
{
printf("main
函数的地址
=%p\n",main);
int (*p)(int,char *[]) = main;
//
返回值类型
(*
指针名称
)(
指向的函数的形参列表的数据类型
) =
函数名
;
void (*p2)(int,int) = add;
//
函数指针调用函数
//
指针名
(
实参列表
);
//
变量名
=
指针名
(
实参列表
);
// p2 = sub;
p2(1,2);
test(p2);
return 0;
}
void test(void (*p)(int,int))
{
p(10,12);
}
void add(int a,int b)
{
printf("%d+%d=%d\n",a,b,a+b);
}
void sub(int a,int b)
{
printf("%d-%d=%d\n",a,b,a-b);
}
指针作为形参
#include <stdio.h>
extern void showArray(int nums[],int len);
int main(int argc, char const *argv[])
{
int nums[] = {1,2,3,4,5};
showArray(nums,5);
return 0;
}
void showArray(int *nums,int len)
{
for (int i = 0; i < len; i++)
{
// printf("%d\t",nums[i]);
printf("%d\t",*(nums+i));
}
printf("\n");
}
指针作为返回值
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// extern int* getNums();
extern void getNums(int nums[],int len);
int main(int argc, char const *argv[])
{
srand(time(NULL));
// int *p = getNums();
// for (int i = 0; i < 10; i++)
// {
// printf("%d\t",p[i]);
// }
// printf("\n");
int nums[10] = {0};
getNums(nums,10);
for (int i = 0; i < 10; i++)
{
printf("%d\t",nums[i]);
}
printf("\n");
return 0;
}
// int* getNums()
// {
// static int nums[10] = {0};
// for (int i = 0; i < 10; i++)
// {
// nums[i] = rand() % 100;
// }
// return nums;
// }
void getNums(int nums[],int len)
{
for (int i = 0; i < len; i++)
{
nums[i] = rand() % 100;
}
}