原文出处:http://blog.csdn.net/tigerjb/article/details/7425571#comments
1.先看程序:
#include<stdio.h>
char *returnStr()
{
char *p = “tigerjibo”;
return p;
}
int main()
{
char*str;
str =returnStr();
//str[0]=’T’;则会引起错误,不能修改只读数据段中的内容
printf(“%s\n”,str);
return0;
}
来分析下该程序。
(1)char *p = “tigerjibo”。系统在栈上分配四个字节的空间存放p的数值。“tigerjibo”是字符常量,存放在只读数据段内。指向完后,系统把”tigerjibo”的地址赋值给p。
(2)函数用return 把p的数值返回。该数值指向只读数据段(该数据段内的数据是静态的不会改变)。退出子函数后,系统把p的数值销毁。但是p的数值已经通过return 返回。且只读数据段中的内容不会被修改和回收(其输于静态区域)
(3)在主程序中把该地址又给了str。因此str指向了“tigerjbo”。
(4)该程序虽然能运行,担又一个缺点,就是在程序中不能修改字符常常量中的数值。如果修改会引起段错误。
2.先看程序
#include<stdio.h>
char *returnStr()
{
char p[]=”tigerjibo”;
return p;
}
int main()
{
char *str;
str =returStr();
printf(“%s\n”,str);
}
编译该程序后,系统会提示如下警告:
function returns address of local variable
(函数返回一个可变地址)
分析该错误:
1>”tigerjibo”是一个字符常量,存放在只读数据段中,是不能被修改的。
2>char p[],是一个局部变量,当函数被调用时,在栈上开辟一个空间来存放数组P的内容。
3>char p[]=”tigerjibo”,该语句是把”tigerjibo”的值赋值给数值P,存放在数组p地址处。而不是把”tigerjibo”的地址赋值给数组p。因此,“tigerjibo”此时在系统中有一处备份,一个在只读数据段中(不能修改,内容也不会被回收),一个在栈上存储(可以修改起内容,但函数退出后,其栈上存储的内容也会被回收)。
4>因此,当return p,返回了数组的首地址,但是当函数退出后,其栈上的内容也将被丢弃,局部变量的内存也被清空了,因此该数组首地址处的内容是一个可变的值。
3.先看一个程序:
#include<stdio.h>
char *returnStr()
{
static char p[]=”tigerjibo”;
return p;
}
int main()
{
char *str;
str =returnStr();
str[0]=’T’;
printf(“%s\n”,str);
}
此程序运行正确。
分析如下:
1>”tigerjibo”是一个字符常量,存放在只读数据段中,是不能被修改的。
2>static char p[],是一个静态局部变量,在读写数据段中开辟一个空间给p用来存放其数值。
3>static char p[]=”tigerjibo”,该语句是把”tigerjibo”的值赋值给数值P,存放在数组p地址处。而不是把”tigerjibo”的地址赋值给数组p。因此,“tigerjibo”此时在系统中有一处备份,一个在只读数据段中(不能修改,内容也不会被回收),一个在读写数据段中存储(可以修改其内容,当函数退出后,因其在读写数据段中存储,起内容不会被丢弃)。
4>因此,当return p,返回了数组的首地址,但是当函数退出后,虽然栈上的内容都清除了,但是p地址是读写数据段中的地址,其上的内容不会被回收。
4.先看一个程序:
#include<stdio.h>
#include<string.h>
#include<strdlib.h>
void getmemory(char *p)
{
p = (char *)malloc(100);
}
int main()
{
char *str=NULL;
getmemory(str);
strcpy(str,”helloworld”);
printf(“%s\n”,str);
}
编译后错误:
段错误
分析:在主程序中,str地址为空。在函数传递中将str的地址传给了子函数中的指针p(是拷贝了一份),然后在字函数中给p在堆上申请了一个100字节的空间,并把首地址赋值给p。但是函数传递中,p值改变不会影响到主函数中str的值。因此,str的地址仍为空。在strcpy中引用空指针会出现段错误。
分享到:
相关推荐
详解函数指针和指针函数 函数类型 (*指针变量名)(形参...“函数类型”说明函数的返回类型,由于“()”的优先级高于“*”,所以指针变量名外的括号必不可少,后面的“形参列表”表示指针变量指向的函数所带的参数列表。
参数为指针类型导出函数 c# Csharp调用 c++库 参数为导入和导出指针两种 包含C++ DLL源码 如fun(cont char* A,char*B) A为输入参数,B为输出参数-C# CSharp call C++ DLL lib dll function param use export and ...
当一个函数声明其返回值为一个指针时,实际上就是返回一个地址给调用函数,以用于需要指针或地址的表达式中。 格式: 类型说明符 * 函数名(参数) 当然了,由于返回的是一个地址,所以类型说明符一般都是int。 ...
指针函数的一个小demo,指针函数就是函数,返回类型为指针型。
让我们来分析一下 左边圆括弧中的星号是函数指针声明的关键 另外两个元素是函数的返回类型(void)和右边圆括弧中的入口参数(本例中参数是空) 注意本例中还没有创建指针变量 只是声明了变量类型 ">函数指针 ...
数据结构 C++ 详细注释 返回指针 返回结构类型的函数 返回结构引用的函数.
以下是对函数指针与返回函数的指针进行了详细的分析介绍,需要的朋友可以过来参考下
当一个函数声明其返回值为一个指针时,实际上就是返回一个地址给调用函数,以用于需要指针或地址的表达式中。 格式: 类型说明符 * 函数名(参数) 当然了,由于返回的是一个地址,所以类型说明符一般都是int。 ...
例如,定义一个返回类型为int,参数列表为两个int类型的函数指针: ```c int (*pFunc)(int, int); ``` 可以通过赋值将一个函数的地址赋给函数指针,然后就可以用该指针来调用函数了。例如: ```c int add(int a, ...
像其他指针一样,函数指针也指向某个特定的类型,函数类型有返回类型以及形参表确定,而与函数名无关。 bool (*pf) (const string ,const string &); 这个语句将pf申明为指向函数的...
指针函数是一个函数,只不过指针函数返回的类型是某一类型的指针。 格式: 类型名* 函数名(函数参数列表) 使用: /* * 指针函数,返回int* 指针变量 */ int* add(int a, int b) { int *p; int c = a + b; p = &...
和其他指针一样,函数指针指向某种特定类型,所有被同一指针运用的函数必须具有相同的形参类型和返回类型。 int (*pf)(int, int); // 声明函数指针 这里,pf指向的函数类型是int (int, int),即函数的参数是两个...
1.函数指针 函数指针是一个指针,只是这个指针它不像普通的指针指向是是一个变量,此时它指向的是一个函数,也就是它存储的是一...typedef 返回类型(*函数指针类型名)(函参列表); 代码如下:#include <iostream>us
本文主要介绍C语言 用指针作为函数返回值,这里整理了相关资料及示例代码,帮助大家学习理解此部分知识,有需要的同学可以参考下
可选的形参表指定委托的参数,而返回类型则指示委托的返回类型。如果下面两个条件都为真,则方法和委托类型是兼容的:(兼容的概念就是可以用此声明的委托对方法进行委托). 1它们具有相同的参数数目,并且类型相同,...
函数重载不能通过函数的返回类型来区分,因为在函数返回之前我们并不知道函数的返回类型。 函数隐藏和函数覆盖只会发生在基类和派生类之间。 函数隐藏是指派生类中函数与基类中的函数同名,但是这个函数在基类中并...
函数返回类型是某一类型的指针。类型标识符 *函数名(参数表) int *f(x,y); 这个函数的返回值是一个地址值。函数返回值必须用同类型的指针变量来接受,即指针函数一定有函数返回值,在主调函数中,函数返回值必须赋...
函数类型由其返回类型以及形参表确定,而与函数名无关。 定义: char (*fP)(char,int); 赋值: char function(char i,int j) { } fp=function; 调用 (*fp)(10,100); type char (*FUN)(char,int);/...
“函数类型”说明函数的返回类型,由于“()”的优先级高于“*”,所以指针变量名外的括号必不可少。 注意指针函数与函数指针表示方法的不同,千万不要混淆。最简单的辨别方式就是看函数名前面的指针*号有没有被括号...
该函数返回一个指针 ,指向已分配大小的内存。如果请求失败,则返回 NULL。 注: 一般搭配sizeof使用, sizeof() : 参数是数据类型, 基础数据类型和结构体, 以及变量名均可, 返回值是传入参数在内存中占用字节的大小...