返回值 是 指针的函数;
int *foo(void)
{
int i = 100; // i为局部变量,函数调用完,i的空间会销毁。因此应该改成 static int i = 100
return &i;
}
int main(void)
{
int *p;
p = foo(); // 错误,局部变量 i 空间已经销毁,因此会变成野指针。
return 0;
}
void * malloc(unsigned long size)
申请的是堆上的空间,申请空间在内存上一定连续。如果申请不到会返回 NULL。
需要包含
int main(void)
{
const char *s ={"Hello"};
const char *t ={"World"};
char * p= malloc(strlen(s) + 1); //申请空间大小为 s 指向字符串数 + 1,因为隐含'\0'。
if(p != NULL) //说明空间申请成功
{
strcpy(p,s); //字符串拷入堆中。
char *q = malloc(strlen(q) + strlen(t) +1); //重新申请空间,使得大小够装下 s和t指向
strcpy(q,p); //拼接后的字符串
strcat(q,t) ; //进行拼接
free(p); //释放p指向的堆空间,p变成野指针
p = q; // 不让p变成野指针
puts(q); //打印字符串
}
free(q); //释放p和q指向的堆空间
return 0;
}
void *realloc(void *ptr,unsigned long size)
第一个参数指原来的空间, 第二个参数指需要新开多少个字节的空间
并且会把原来空间的数据拷贝过来,且将原来空间释放掉。
int add(int a,int b)
{
return a + b;
}
int sub(int a,int b)
{
return a - b;
}
int main(void)
{
int a = 10;
int b = 20;
int(*p)(int a,int b) ; // 函数指针,未赋值的野指针
p = add; // 将add函数的入口地址赋值给p
p(a,b); //间接调用函数
(*p)(a,b); //两种写法都可调用函数
return 0;
}
int pow2(int n) //返回该数的平方
{
return n * n;
}
int fn(int n) //返回该数本身
{
return n;
}
void sort(int *a,int len,int(*pfn)(int)) //第三个参数用来说明,你要比较 数的平方 还是其本身
{ // 甚至可以继续扩展,只要函数返回值为int型,且形参
int i,j; // 只有 一个int型
for(i = 0;i < len - 1;++i)
{
for(j = i + 1;j < len;++j)
{
if(pfn(a[i]) > pfn(a[j])) //调用的函数比较
{
int t = a[i];
a[i] = a[j];
a[j] = t;
}
}
}
} //这是一个选择排序函数
int main(void)
{
int a[] = {8,9,-5,1,4,3,2};
int len =sizeof(a);
sort(a,len,pow2); //根据需求按他的平方大小排序。
return 0;
}
char *s[3] = {"Hello",''World","China"};
//该数组中是三个指针变量
//s[0]存着'H'的地址, s[1]存着'W'的地址, s[2]存着'C'的地址
void getMemory(char * p) //此处应该改成 char **p 即指针的指针
{
p = malloc(100);
}
int main(void)
{
char *s;
getMemory(s);
strcpy(s,"Hello"); // 错误,此时s是个野指针,因为s本身就是个指针,形参p也是个指针,
puts(s); //因此 ,相当于值传递,而应该把形参改成指针的指针
}
(形参) char **s <=> (实参)char *s[]
(实参)char s[][20] <=> (形参)char(*s)[10]
总结:二维数组作为函数的参数,形参为指向数组的指针。
指针数组作为函数参数,形参为指向指针的指针。