Let function return a correct value you want



/* return.c by vinco at 2011-08-04
   Ubuntu9.10 CC/GCC
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int  return_value_0(void);
void return_value_1(int j);
int* return_value_2(void);
void return_value_3(int* j);
void return_value_4(int* j);

char* strrev(char* str);
char* strrev_1(void);
char* strrev_2(void);
char* strrev_3(void);

int main()
{
#if 1
	int j=0;
	int* k=NULL;

	j = -1;
	j = return_value_0( );
	printf("return_value_0: j== %d\n",j);

	j = -1;
	return_value_1( j );
	printf("return_value_1: j== %d\n",j);

	k = NULL;
	k = return_value_2( );
	printf("return_value_2: k==%d\n",*k);

	*k = -1;//do not :k = NULL;
	return_value_3( k );
	printf("return_value_3_point:  k==%d\n",*k);
	
	j = -1;
	return_value_3( &j );
	printf("return_value_3_adress: j==%d\n",j);

	*k = -1;//do not :k = NULL;
	return_value_4( k );
	printf("return_value_4_point:  k==%d\n",*k);

	j = -1;
	return_value_4( &j );
	printf("return_value_4_adress: j==%d\n",j);


#else
	#if 0
	char str[] = "vinco zhang";
	#else
	//char* str = "vinco zhang";  "segmetation fault"---> do not try to modified the valule in const region
	char* p = "vinco zhang";  
	char* str = (char*) malloc(32);  
	strcpy(str,p); 
	#endif

	//strrev(str); printf("strrev \t\t: str = %s\n",str);
	printf("strrev \t\t: str = %s\n",strrev(str));

	printf("out strrev_1 \t: str = %s\n",strrev_1());
	printf("out strrev_2 \t: str = %s\n",strrev_2());

	char* str3 =strrev_3();
	printf("out strrev_3 \t: str = %s\n",str3 );
	free(str3);
#endif

	return 0;
}


int return_value_0(void)
{
	int i = 100;
	int j = i;
	return j;
}

void return_value_1(int j)
{
	int i = 100;
	j = i;
}

int* return_value_2(void)
{
	int i = 100;
	int* j = &i;
	return j;
}
void return_value_3(int* j)
{
	int i = 100;
	*j = i;
	//j = &i;
	//*j = &i;
}

void return_value_4(int* j)
{
	int i = 100;
	//*j = i;
	j = &i;
}

char* strrev(char* str)
{
	char* p = str;
	char t;
	int i=0, len = strlen(str) - 1;

	for(i=0 ; i<len ; i++, len--)
	{
		t = *(p+i) ;
		*(p+i) =  *(p+len) ;
		*(p+len) = t ;
	}
	return str;
}

char* strrev_1(void)
{
	char str[32]="vinco zhang";
	
	char* p = str;
	char t;
	int len = strlen(str) - 1;
	int i;
	for(i=0 ; i<len ; i++, len--)
	{
		t = *(p+i) ;
		*(p+i) =  *(p+len) ;
		*(p+len) = t ;
	}
	printf("in  strrev_1\t: str = %s\n",str);
	return str;
}

char* strrev_2(void)
{
	static char str[32]="vinco zhang";

	char* p = str;
	char t;
	int len = strlen(str) - 1;
	int i;
	for(i=0 ; i<len ; i++, len--)
	{
		t = *(p+i) ;
		*(p+i) =  *(p+len) ;
		*(p+len) = t ;
	}
	return str;
}

char* strrev_3(void)
{
	char* s ="vinco zhang";  
	//char s[] ="vinco zhang";  
	char* str = (char*) malloc(32);  
	strcpy(str,s); 

	char* p = str;
	char t;
	int len = strlen(str) - 1;
	int i;
	for(i=0 ; i<len ; i++, len--)
	{
		t = *(p+i) ;
		*(p+i) =  *(p+len) ;
		*(p+len) = t ;
	}
	return str;
}




1. case #if 0 :line 54~71


root@vinco:/home/vinco# make return
cc     return.c   -o return
return.c: In function ‘strrev_1’:
return.c:147: warning: function returns address of local variable
root@vinco:/home/vinco# ./return
strrev 		: str = gnahz ocniv
in  strrev_1	: str = gnahz ocniv
out strrev_1 	: str = ��$
out strrev_2 	: str = gnahz ocniv
out strrev_3 	: str = gnahz ocniv
root@vinco:/home/vinco# 

strrev() work well certainly;

strrev_1() try to return address/point of local variable (  in stack section ) , obviously fail !

if you have to return local variable, strrev_3() and strrev_4() will give you inspire, but you cannot be more careful:

    i. define a static variable , the vairant will not be freed until the process run over , but it's not a thread-safe idea ( I will discuss it in next blog)

    ii.  allocate some heap memory to the point variable you want to return , always keep remembering to free it after you do not want it again, whether it in or out of a function, especially if you are going to porting the code to a larger project


2. case #if 1 :line 21~52


root@vinco:/home/vinco# make return
cc     return.c   -o return
return.c: In function ‘strrev_1’:
return.c:143: warning: function returns address of local variable
root@vinco:/home/vinco# ./return
return_value_0: j== 100
return_value_1: j== -1
return_value_2: k==100
return_value_3_point:  k==100
return_value_3_adress: j==100
return_value_4_point:  k==100
return_value_4_adress: j==-1


i. return_value_0() : 

 it will create a temporary variant ,and assigned the value you want  to it when function return, so it work well

ii return_value_1() and return_value_2:() :

cannot get  the value in stack section , in C language ,the paramemter is passed by value , not by itself  ( it can be passed by reference in C++ ), only the replica that be modified 

3. return_value_3() and return_value_4():

it's the first time I notice that  "*j = i" is not always equivalent to "j = &i"  in some cases ( in function ,in this case),but as you see:( j is a point variable)

 " *j = i " means give the value of i to the area that the point pointed to;

 " j = &i " means give the address of i to the point/address itself;

(point as lvalue means address, as rvalue means the area it pointed to)

 

when try to pass adress of a variant (&j) to return_value_4(), it's same with the return_value_1()

 

I recommend that adopt the format of return_value_3() once write code , the advantage is show in the result
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值