一、数组:
1、char型数组中的内容可修改
一维数组:
列: char arr1[3]={'1','2','3'};
一维数组:
列: char arr1[3]={'1','2','3'};
下标表示可存字符个数
2、二维数组:
列: char arr2[2][4]={"123","456"};
第一个下标表示字符串个数,第二个下标表示字符串长度(字符串末尾有隐含'\0')
传参:void arr(char (*arr)[3])
void arr(char arr[][3])
传参: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 *类型可在定义时直接初始化。
(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],而不一定都从起始地址算起,
注:将当前的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)、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 (*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);
}