指针深入

来源:互联网 发布:c语言编Newton 编辑:程序博客网 时间:2024/05/29 15:16

一、数组:
1、char型数组中的内容可修改
一维数组:
 列: char arr1[3]={'1','2','3'};
下标表示可存字符个数
 
2、二维数组:
列: char arr2[2][4]={"123","456"};
第一个下标表示字符串个数,第二个下标表示字符串长度(字符串末尾有隐含'\0')
 传参:void arr(char (*arr)[3])
            void arr(char arr[][3])
其它数组相关内容可访问(数组剖析):http://blog.csdn.net/wejboke626/article/details/78539838

二、指针数组
指针数组是数组而不是指针,数组存储的是地址
如:char * arr[3];
       char * arr[][3];
       char ** arr[3];
1、char *类型:
(1)、char*类型的字符串保存在文字常量区,即ch地址为文字常量区的地址,
 (2)、文字常量区的内容在编译时就已确定,不可更改。即ch的字符串不可修改
 (3)、只有 char *类型可在定义时直接初始化。
列: char * ch="123456"; 而 int * num=5;错误,因为num为野指针
注: char * ch=NULL;//ch未分配内存空间,是个野指针,不可赋值
内存分配:ch=(char*)malloc(sizeof(char)*10)

 2、数组引用char *
指针可以用数组的形式引用,数组也可以用指针去引用
列:char * ch="123456";
ch[0]=*p='1'; *++p=ch[1]='2'...ch[6]='\0'
 注:将当前的ch地址当作ch[0],然后依次往后退ch[2],而不一定都从起始地址算起,

3、char * 型数组
列:char * arrp[2]={"100","456"};
 (1)、arrp[0]表示第一个字符串的地址,arrp[1]表示第二个字符串的地址
 (2)、*arrp[0]表示取第一个字符串地址中的字符,即第一个字符'1',*arrp[1]表示取第二个字符串第一个字符'4'
 注:arrp[0]是代表整个字符串的地址,而不是代表第一个字符地址,地址相同,意义不同
 (3)、arr[i]+j表示第i+1个字符串中的第j+1个字符的地址  *(arr[1]+1)即取第二个字符串中第二个字符(5)

在其他函数中进行内存分配方法:
 1、调用函数进行内存空间分配,参数为保存ch地址的地址(&ch),而不是ch,(类似改变某个变量值传入的是变量的地址,而不是变量一样)
列:
int main(){ char *ch; pointer_arr(&ch); ch="123456";
return 0;}void pointer_arr(char **ch)//使用函数为指针分配内存空间{  *ch=(char*)malloc(sizeof(char)*100);}

三、数组指针
数组指针是指针,而不是数组。指针指向数组的地址
如:char (*arr)[3];
      
使用:
int arrr[10]={10};
 int (*p2)[10]=&arrr;
 printf("%p\n",p2[0]);//存储的是数组的地址(&arr)

四、二级指针
列:
int **pp;
pp存储的是地址的地址。
*pp代表地址,pp表示地址  pp--->&(地址)
**pp代表内容
使用:
int num=0;
int *p=#
int ** pp=&p; // pp---> &(地址)
char * arr[2]={"123","456"};

//传参时也必须是二级指针类型(地址的地址)
test(pp);//调用test函数,或test (&p);
test1(arr);//arr表示第一个字符串的地址

void test(int ** ptr)
{
 printf("num=%d \n",**ptr);
}


void test1(char **ptr)//传参降级,取地址的地址-->第一个字符串中的第一个字符地址

{

//表示的是第一个字符串的中的第一个字符地址,而不再是第一个字符的地址,所以只能得到第一个字符

 printf("%c \n",**ptr);

}


五、函数指针
返回类型(*函数名)(参数)
函数也有地址,地址存储在指针类型中,
列:
void (*pfun1)(int a ); //指针指的是某个函数
返回类型为void ,函数名(*pfun1),参数为int a
六、函数指针数组
可理解成:函数+指针数组
列:int (*parr[10]) (int x);//*parr[10]是一个指针数组,加上括号即成函数指针数组
(1)、指针指向的是具有相同类型的函数,数组的每一个下标指像一个函数
(2)、返回类型为int型,函数名(*parr[]),最多有10个子函数,参数为int x

代码实例讲解:
#include<stdio.h>#include<stdlib.h>//为了便于说明我将函数指针数组所指向的函数称之为子函数int add(int x,int y);//返回类型与函数指针数组返回类型相同int sub(int x,int y);//子函数的声明要在函数指针数组之前//返回int型,函数名(*pointer[]),最多有三个子函数(分别为add,sub,0未用),参数为两个int型,传给子函数int (*pointer[3])(int x,int y)={0,add,sub};//函数指针数组,不写此函数的实现int main(){int x=0;int y=0;int  num=0;//选择数即下标选择int ret=0;//计算结果printf("输入选择(0->退出,1->加,2->减);");scanf("%d",&num);while(num){printf("输入两个数:");scanf("%d %d",&x,&y);ret=(*pointer[num])(x,y);//num为数组下标选择printf("结果:%d\n",ret);break;}system("pause");return 0;}int add(int x,int y){        return x+y;}int sub(int x,int y){return x-y;}

六、指向函数指针数组的指针
指针+函数指针数组
指向函数指针数组的指针是一个 指针
指针指向一个 数组 ,数组的元素都是 函数指针
列:
void (*pfun)(const char *)=test;//函数指针
void (*pfunarr[5])(const char *str);//函数指针数组
pfunarr[0]=test;//获取test函数地址
void (*(*ppfunarr[10])(const char *)=&pfunarr;//指向函数指针数组的指针

void test (const char * str)//test 函数
{
  printf("%s \n",str);
}




原创粉丝点击