多级指针
基本概念
语法:<数据类型>**<指针名>;
可以理解为:
1.<数据类型>*:表示指针的目标。
2.*<指针名>; :指针变量。
#include<string.h>
#include<stdio.h>
#pragma warning(disable:4996);
int main()
{
int a = 10;
int* p = &a;
int** pp = &p;
printf("&a = %p p = %p pp = %p\n", &a, p, pp);
//&a = 00000034F4D2F694 p = 00000034F4D2F694 pp = 00000034F4D2F6B8
printf("&a = %p &p = %p &pp = %p\n", &a, &p, &pp);
//&a = 00000034F4D2F694 &p = 00000034F4D2F6B8 &pp = 00000034F4D2F6D8
//--------------------结论:p的地址 == qq的值-----------------------
//2.解引用:
printf("a = %d *p = %d **pp = %d\n", a, *p, **pp);
//a = 10 *p = 10 *pp = 10
return 0;
}
多级指针的运算
问题:多级指针移动一个,多少字节?
#include<stdio.h>
#pragma warning(disable:4996);
int main()
{
int a = 10;
int* p = &a;
int** pp = &p;
printf("%ld %ld\n", sizeof(int), sizeof(int*));
// 4 8
printf("before:%p %p\n", p, pp);
// before:0000005849D1FB74 0000005849D1FB98
p = p + 1;
pp = pp + 1;
printf("after :%p %p\n", p, pp);
// after :0000005849D1FB78 0000005849D1FBA0
// 移动了: 4字节 8字节
return 0;
}
问题:如何用多级指针打印数组?
#include<stdio.h>
#pragma warning(disable:4996);
int main()
{
int arr[] = { 4,6,8,9,10,20 };
int n = sizeof(arr) / sizeof(int);
int* p[6];//p为:指针数组名
int** pp;
int i;
for (i = 0; i < n; i++)
{
p[i] = &arr[i];
}
for (i = 0; i < n; i++)
{
printf("%d %d", arr[i], *p[i]);
putchar('\n');
}
printf("-------\n");
pp = p;//pp = &p[0];
for (i = 0; i < n; i++)
{
printf("%d %d\n", **(pp + i), *pp[i]);
}
return 0;
}
多级指针和指针数组
问题:如何用多级指针打印多维数组?
#include<stdio.h>
#pragma warning(disable:4996);
int main()
{
int arr[3][3] = { {1,2,3},{2,3,4},{3,4,5} };
int* parr[3] = { arr[0],arr[1],arr[2] };
int** ppar = parr;//ppar = &parr[0];
int i = 0;
int j = 0;
//1.利用指针数组
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
printf("%d ", *(parr[i] + j));
}
putchar('\n');
}
//2.利用多级指针
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
printf("%d",*(*(ppar[i]) + j));
}
putchar('\n');
}
return 0;
}
问题:如何打印New York city?
#include<stdio.h>
#pragma warning(disable:4996);
int main()
{
const char* ps[5] = { "Beijing city","Moscow city","New York city","London city","Paris city" };
const char** pps = ps;//pps = &ps[0];
printf("%s %s\n", ps[2],pps[2]);
printf("%s %s\n", ps[2],*(pps+2));
return 0;
}
void指针
语法:void * <指针变量名称>;
对于void指针,在没有进行强制类型转换前,不能算术运算和解引用。
示例:
#include<stdio.h>
#pragma warning(disable:4996);
int main()
{
int a = 10;
float b = 3.14;
char c = 'c';
void* p;
p = &a;
printf("%d\n", *(int*)p);
p = &b;
printf("%lf\n", *(float*)p);
p = &c;
printf("%c\n", *(char*)p);
return 0;
}
//10
//3.140000
//c
问题:用void指针遍历一遍数组。
#include<stdio.h>
#pragma warning(disable:4996);
int main()
{
int arr[] = { 1,2,3,4,5 };
//void* p = arr;
void* p = &arr[0];
int i = 0;
for (i = 0; i < 5; i++)
{
printf("%d ", *((int*)p+i));
}
return 0;
}
const变量、const指针
const变量
常量化变量:为了使变量的值不能修改。
语法:const <数据类型> 变量名 = [<表达式>] ;
有const修饰的时候,若想用指针间接访问变量,指针也要有const修饰。
注意:const 数据类型 变量名 == const 变量名 数据类型
const指针
1. 常量化指针目标:是限制通过指针改变其目标的数值,但<指针变量>存储的地址值可以修改。
语法:const <数据类型> * <指针变量名称> = <指针运算表达式>;
#include<stdio.h>
#pragma warning(disable:4996);
int main()
{
int n = 10;
int m = 20;
const int* pn = &n;
//*pn = 30;//error:const限制通过指针改变其目标的数值。
pn = &m; //right:const没有限制指针存储的地址值。
printf("%d\n", *pn); //20:因为m = 20。
return 0;
}
2. 常量化指针变量:使得<指针变量>存储的地址值不能修改。但可以通过*<指针变量名称>可以修改指针所指向变量的数值。
语法:<数据类型> * const <指针变量名称> = <指针运算表达式>;
#include<stdio.h>
#pragma warning(disable:4996);
int main()
{
int n = 10;
int m = 20;
int* const pn = &n;
*pn = 30; //right:const没有限制通过指针改变其目标的数值。
//pn = &m;//error:const限制指针存储的地址值。
printf("%d\n", *pn); //30
return 0;
}
3.常量化指针变量及其目标表达式:既不可以修改<指针变量>的地址,也不可以通过*<指针变量名称>修改指针所指向变量的值。
语法:const <数据类型> * const <指针变量名> = <指针运算表达式>;
main函数的参数
int main (int argc , const char * argv [ ] )
argc: 命令行参数的个数。
argv:为保存命令行参数的字符串指针。
其中第0个参数是程序的全名,以后的参数为命令行后面跟的用户输入的参数。
argv参数是字符串指针数组,其各元素值为命令行中各字符串的首地址。指针数组的长度即为参数个数argc。