vb将指针指向内容传数组_C语言指针
指针:
指针的概念:
指针就是地址。
内存:
内存的每一字节都分配了一个编号,从0x00 00 00 00 开始到 0x ff ff ff ff
这个编号咱们称之为内存的地址。
指针变量:
存放地址编号的变量被称为指针变量。
指针变量的分类:
按类型分:
一级指针
char * p ; //字符指针变量 可以保存字符变量的地址,或字符串的地址。
int * p;//整型指针变量 可以保存整型变量的地址
long int *p;
float *p;//浮点型的指针变量,可以保存float类型变量的地址。
double *p //双浮点型的指针
多级指针:指针的指针
char **p;//可以保存char * 类型变量的地址。
int **p;
float **p;
数组指针:
int (*p)[4]; //定义了一个数组指针,p=p+1 一下跳一个整型数组(有四个元素)
函数指针:
int (*p)(char *,int );//定义了一个函数指针变量p ,可以保存函数的入口地址。
注意p所指向的函数,必须有一个int类型的返回值,第一个形参类型必须是char * ,第二个形参必须是int
指针数组:
指针数组,本身是一个数组。
int *p[5];//定义了一个整型的指针数组,数组有5个元素,每个元素都是 int *类型的指针变量。
int (*p[6])(char *,int );//定义了一个函数指针数组,有6个指针,分别是p[0]~p[5]
指针和函数的关系:
指针可以作为函数的返回值
void * malloc (int size);//malloc这个函数返回的就是一个指针。
举例1:
char * fun()
{
char str[]="hello world";
return str;
}
int main()
{
char *p;
p=fun();
printf("p=%s\n",p);
}
程序的执行结果。
打印乱码,因为str是一个局部数组,函数调用完毕后str数组就被释放了,内容就不确定了
举例2:
char * fun()
{
char *str="hello world";
return str;
}
int main()
{
char *p;
p=fun();
printf("p=%s\n",p);
}
程序执行结果:打印hello world
因为hello world在文字常量区,返回地址给p赋值,p就指向了文字常量区,文字常量区的东西
在程序运行过程中一直存在。
举例3:
char * fun()
{
static char str[]="hello world";
return str;
}
int main()
{
char *p;
p=fun();
printf("p=%s\n",p);
}
程序执行结果:打印hello world
因为str是静态数组,函数结束后,不释放其空间,还存在,所以可以打印str的内容。
指针可以作为函数的参数
1:传变量的地址
例1:
void fun(int *p)
{
*p=9;
}
int main()
{
int a=10;
fun(&a);
printf("a=%d\n",a);
}
程序的执行结果 a=9;
因为p指向main 函数中的a ,*p =9 其实就是给main函数中的a赋值.
例2:
void fun(int p)
{
p=9;
}
int main()
{
int a=10;
fun(a);
printf("a=%d\n",a);
}
//此程序执行的结果是 a=10;
注意a给p赋值,p的值是10 然后再fun中重新给p赋值为9 ,
p是一个局部变量,函数结束后p释放了,在fun中没有给main函数中的a赋值,所以
main函数中的a的值还是10
例3:
void fun(char *p)
{
p="I love China!!!";
}
int main()
{
char *str="hello world";
fun(str);
printf("str=%s\n",str);
}
此程序的运行结果,hello world
调用fun的时候用str给p赋值,p是局部变量,指向了hello world 在fun中
p又指向了 I love China!!!,fun结束后p被释放了,在fun中没有给str赋值。
所以str还是指向helloworld
例4:
void fun(char **p)
{
*p="I love China!!!";
}
int main()
{
char *str="hello world";
fun(&str);
printf("str=%s\n",str);
}
此程序的运行结果,I love China!!!
因为用str变量的地址给p赋值,*p等价于main函数中str 让其指向I love China!!!
总结:要想改变主调函数中变量的值,必须传变量的地址,无论它是什么类型的变量。
2:传数组的地址
指针可以保存函数的入口地址
传一维数组的地址
// 定义方法1
void fun(int p[])
{
}
// 定义方法二
void fun(int *p)
{
p[1]=10;
*(p+1)=10;
}
//方法一和方法二等价,形参将来都认为是 int *类型的
int main()
{
int a[10];
fun(a);//传数组的名字
}
传二维数组的地址
// 定义方法1
void fun(int p[][10])//行数可以不给出,但是列数一定要给出。
{
}
// 定义方法二
void fun(int (*p)[10])
{
}
//方法一和方法二等价,形参将来都认为是 数组指针类型的。
int main()
{
int a[4][10];
fun(a);//传数组的名字,数组的名字就是数组的首地址。
}
传指针数组的地址
int my_strtok(char *q,char *s,char **p)
{
int i=0;
p[i]=strtok(q,s);
while(p[i]!=NULL)
{
i++;
p[i]=strtok(NULL,s);
}
return i;
}
int main()
{
char str[]="秀涛:15010248451:你好,在吗?";
char *p[4];//该数组有4个元素p[0]~p[3] 每个元素是char *
char *str1=":";
int n;
n=my_strtok(str,str1,p);
for(i=0;i<3;i++)
{
}
}
动态内存申请:
动态申请的内存在堆里开辟
malloc
calloc
relloc
void * malloc (int size);
malloc会申请一块连续的size个字节的空间,并且返回首地址
申请的内存里存放的东西是未知的。
void* calloc(int count,int size);
在堆里开辟count块,每一块是size个字节,连续的存储空间,
并且会把申请的内存的每一个字节全部变成0
void *relloc(void *p,int newsize);
接着以前申请的内存(首地址是p)重新申请newsize个字节。
注意p必须指向堆,不能是文字常量区,也不能是静态全局区,也不能是栈区
char *p;
p=(char *)malloc(100);//申请100个字节,让p去指向
如果想追加申请50个字节。
不能再次malloc,因为两次malloc出来的内存,可能不连续
p=(char *)relloc(p,150);//在原先内存的后边追加申请50个字节的空间
如果100字节后边不够50个字节了
重新找一个150个字节的地方,申请150个字节,
将原先100个字节的内容拷贝过来。释放原先的100个字节,返回新内存的首地址。
如果想重新申请50个字节
p=(char *)relloc(p,50);//relloc会将原先100个字节的后边的50个字节释放掉。
释放:
free(p);
注意:释放的内存就不能再用了,并且同一块内存,不能释放多次。