例:const char* pp[2] = { "asd","1123" }; //指针数组
这里的字符串常量其实就是它的地址。
[]的优先级高,所以先和p结合表明其是一个数组,*表示其数组元素为指针,char为指针类型。
2.元素访问:
pp[0]代表数组第一个元素(指针)即第一个字符串的地址:pp[0]+1则代表第一个字符串中s的地址
输出结果:
分析:
pp相当于数组名,和普通数组一样pp[0]代表第一个元素,此时pp[0]="asd"的地址,pp+i=pp[i];
对于一维数组a,a,&a,&a[0]他们的地址一样。而地址就是指针,所以pp,pp[0],pp[1]都是指针。
系统告诉我们pp这个数组名是一个二级指针(它是pp[0]的地址,而pp[0]也是地址), 对其做一次解引用即*pp=pp[0],再次解引用即**pp='a'.*(*(pp+i)+j)=*(pp[i]+j).
测试用例代码:
#include
#include
#include
int main()
{
const char* pp[2] = { "asd","1123" }; //指针数组
printf("pp[0]=%s\n", pp[0]);
printf("*(pp[0]+2)=%c\n", *(pp[0]+2));
printf("*(pp[1]+0)=%c\n", *(pp[1] + 1));
printf(" pp[1]=%s\n",pp[1]);
printf("pp=%s\n", pp);
printf("*pp=%s\n", *pp);
printf("*pp+1=%s\n", *pp+1);
printf("*(pp+1)=%s\n", *(pp + 1));
printf("%d\n", strlen(pp));
printf("{pp[0] + 1}地址 =%p\n", pp[0] + 1 );
printf("pp地址=%p\n", pp);
printf("&pp地址=%p\n", &pp);
printf("&pp+1 地址%p\n", &pp + 1);
printf("(pp+1)地址%p\n", pp + 1);
printf("pp[0]地址=%p\n", pp[0]);
printf("&pp[0]地址=%p\n", &pp[0]);
printf("pp[1]地址=%p\n", pp[1]);
printf("*pp[1]地址=%p\n",*( pp+1));
printf("*pp地址=%p\n", *pp);
system("pause");
}
在程序中定义了一个函数,那么在编译时系统会自动为其分配一段空间,这段存储空间的首地址就成为这个函数的地址,并且函数名表示的就是这个地址。地址就是指针,所以可以用一个指针变量来存放。
先来了解下一下typedef,其实就是为了偷懒,简化代码用的,例如:定义一个无符号长整型 数据
#include
typedef unsigned long long int uint_64 ;
int main()
{
unsigned long long int a = 12;
uint_64 b = 12;
}
用变量替换类型名,使其成为该类型名的别名,可简化代码规模。
测试用例代码:
#include
#include
#include
//函数指针
typedef unsigned long long int uint_64;
typedef int(*Parr)[3];
typedef int(*Px)(double);
int xsug(double a)
{
printf("xsug\n");
return 2;
}
int xsuj(double b)
{
printf("xsuj\n");
return 1;
}
int main()
{
unsigned long long int a = 12;
uint_64 b = 12;
int ar[] = { 1,3,5 };
Parr Pc = &ar;
int(*p)[3] = &ar;
int(*q)(double) = NULL;
Px pq = NULL;
char s;
scanf("%c", &s);
switch (s) {
case '1': q = xsug; pq = xsug; break;
case '2': q = xsuj; pq = xsuj; break;
default: break;
}
printf("%p,%p\n",q,pq);
q(1.0);
pq(2.0);
}
有两种定义:使用typedef重定义,或者不使用。测试代码均已给出;
平时调用函数时:函数名(实参);得到了函数名地址后,可以用: 地址(实参)来调用函数。
测试结果: