C++,无法根据字符指针输出 里面的内容
#include<stdio.h>#include<conio.h>#include<iostream>#include<string>usingnamespacestd...
#include <stdio.h>
#include<conio.h>
#include<iostream>
#include<string>
using namespace std;
char *mid(char oldstring[],int start ,int num)
{
int sumoldstring=strlen(oldstring); //获取数据块大小
start=start-1; //转换为常规索引
char newstring[100];
char *p;
p=newstring;
printf("%d\n",newstring);
for (int i=0;i<num;i++)
{
newstring[i]=oldstring[start+i];
if (i+1==num)
{
newstring[i+1]='\0';
}
}
return p;
}
void main()
{
char b[11]={"1234567890"};
printf("%s",mid(b,2,2));
getch();
} 展开
#include<conio.h>
#include<iostream>
#include<string>
using namespace std;
char *mid(char oldstring[],int start ,int num)
{
int sumoldstring=strlen(oldstring); //获取数据块大小
start=start-1; //转换为常规索引
char newstring[100];
char *p;
p=newstring;
printf("%d\n",newstring);
for (int i=0;i<num;i++)
{
newstring[i]=oldstring[start+i];
if (i+1==num)
{
newstring[i+1]='\0';
}
}
return p;
}
void main()
{
char b[11]={"1234567890"};
printf("%s",mid(b,2,2));
getch();
} 展开
展开全部
你好,你提出的这个问题属于子函数返回了局部堆栈指针,因为在mid函数中定义的char newstring[100]不是静态的,所以作用只在mid中,而你操作的P指针只是一个副本,真正的地址内容并没有改变,程序修改方法只需要在定义 char newstring[100]; 时 改为 static char newstring[100]; 另外printf("%d\n",newstring);这句没有任何意义,若想查看
newstring内容可以改成 printf("%s\n",newstring); 并放置到循环体之后。
可能你一下不能接受,我举几个简单的例子,仔细读完,你就懂了,尤其是第四种,看懂之后,你就恍然大悟了。这也是我之前遇到的问题。
由于在程序设计中发现子函数内动态分配的内存数据在子程序中完全正确, 但是返回后就乱七八糟了. 于是想到了其中可能的奥妙, 应该与函数调用和指针的传递和返回有关系, 下面设计了4种方案:
#include "stdafx.h"
#include "conio.h"
#include <malloc.h>
void readint(int *y)
{
y = (int*)malloc(sizeof(int));
scanf("%d",y);
}
void readint2(int *y)
{
scanf("%d",y);
}
int *readint3()
{
int* x = (int*)malloc(sizeof(int));
scanf("%d",x);
return x;
}
void readint4(int **x)
{
int *y = (int*)malloc(sizeof(int));
scanf("%d",y);
*x = y;
}
int main()
{
int x=-1,*y,*z,*x4;
/*
printf("First:");
readint(y);
printf("It is %d\n",*y);
*/
printf("Second: ");
readint2(&x);
printf("It is %d\n",x);
printf("Third: ");
z = readint3();
printf("It is %d\n",*z);
printf("Forth: ");
readint4(&x4);
printf("It is %d\n",*x4);
getch();
return 0;
}
执行后, 可以发现第2,3,4种情况都能得到期望的输出, 只有第一种情况不行. 分析如下:
1. 传递的是一个指针值(地址值), 但是值传递, 也就是copy一份给子函数, 对原来的指针值没有影响. 所以即使在子函数中分配了内存也不能反应到主函数中去. 相当于张三有个很PP的抽屉, 李四同样打造了一个, 但是两人的钥匙不一样, 李四在他的抽屉里干什么, 张三无权过问. 注意: 这里会产生内存泄漏.
2. 传递的是主函数中声明的一个整数的地址, 在子函数中直接将输入的数据存放到该地址中. 相当于一个抽屉张三和李四共用一把钥匙, 李四放在里面的东西, 张三当然能拿到.
3. 子函数返回的是在子函数中分配的内存地址, 该地址的内存中存放有输入的数据, 主函数根据该地址获取正确的值. 相当于张三没有抽屉, 李四有一个抽屉, 放了些宝贝在里面, 然后把钥匙交给张三保管, 你说张三能拿到李四的宝贝吗?
4. 这个比较费周折. 这里主函数传递给子函数一个指针变量的地址, 也就是存放这个指针变量的值的内存的地址, 但是现在其中的值是不确定的. 进入子函数后, 动态分配了一点内存, 其中放上输入的数据, 然后将这个内存的地址放到前面传进来的地址指示的内存中. 那么返回后, 先前不确定值的那个内存中的值确定下来了, 也就是指向期望数据的地址. 这个过程相当于张三给李四说: 小李子, 你去网上淘点宝贝回来, 放在你那个宝贝抽屉里, 然后把钥匙放在我的抽屉里, 我晚上回来了要瞧你的宝贝呢!
注意: 由于指针的存储空间的问题, 子函数4必须以整数指针为参数.
newstring内容可以改成 printf("%s\n",newstring); 并放置到循环体之后。
可能你一下不能接受,我举几个简单的例子,仔细读完,你就懂了,尤其是第四种,看懂之后,你就恍然大悟了。这也是我之前遇到的问题。
由于在程序设计中发现子函数内动态分配的内存数据在子程序中完全正确, 但是返回后就乱七八糟了. 于是想到了其中可能的奥妙, 应该与函数调用和指针的传递和返回有关系, 下面设计了4种方案:
#include "stdafx.h"
#include "conio.h"
#include <malloc.h>
void readint(int *y)
{
y = (int*)malloc(sizeof(int));
scanf("%d",y);
}
void readint2(int *y)
{
scanf("%d",y);
}
int *readint3()
{
int* x = (int*)malloc(sizeof(int));
scanf("%d",x);
return x;
}
void readint4(int **x)
{
int *y = (int*)malloc(sizeof(int));
scanf("%d",y);
*x = y;
}
int main()
{
int x=-1,*y,*z,*x4;
/*
printf("First:");
readint(y);
printf("It is %d\n",*y);
*/
printf("Second: ");
readint2(&x);
printf("It is %d\n",x);
printf("Third: ");
z = readint3();
printf("It is %d\n",*z);
printf("Forth: ");
readint4(&x4);
printf("It is %d\n",*x4);
getch();
return 0;
}
执行后, 可以发现第2,3,4种情况都能得到期望的输出, 只有第一种情况不行. 分析如下:
1. 传递的是一个指针值(地址值), 但是值传递, 也就是copy一份给子函数, 对原来的指针值没有影响. 所以即使在子函数中分配了内存也不能反应到主函数中去. 相当于张三有个很PP的抽屉, 李四同样打造了一个, 但是两人的钥匙不一样, 李四在他的抽屉里干什么, 张三无权过问. 注意: 这里会产生内存泄漏.
2. 传递的是主函数中声明的一个整数的地址, 在子函数中直接将输入的数据存放到该地址中. 相当于一个抽屉张三和李四共用一把钥匙, 李四放在里面的东西, 张三当然能拿到.
3. 子函数返回的是在子函数中分配的内存地址, 该地址的内存中存放有输入的数据, 主函数根据该地址获取正确的值. 相当于张三没有抽屉, 李四有一个抽屉, 放了些宝贝在里面, 然后把钥匙交给张三保管, 你说张三能拿到李四的宝贝吗?
4. 这个比较费周折. 这里主函数传递给子函数一个指针变量的地址, 也就是存放这个指针变量的值的内存的地址, 但是现在其中的值是不确定的. 进入子函数后, 动态分配了一点内存, 其中放上输入的数据, 然后将这个内存的地址放到前面传进来的地址指示的内存中. 那么返回后, 先前不确定值的那个内存中的值确定下来了, 也就是指向期望数据的地址. 这个过程相当于张三给李四说: 小李子, 你去网上淘点宝贝回来, 放在你那个宝贝抽屉里, 然后把钥匙放在我的抽屉里, 我晚上回来了要瞧你的宝贝呢!
注意: 由于指针的存储空间的问题, 子函数4必须以整数指针为参数.
展开全部
无法输出内容的原因上面都说了,其实最好的解决方式是将newString定义在外面,然后用参数传进来,这样在mid内部不用再定义了,这样的好处是比较通用,举个例子如果我取的子串长度大于100,那么你在mid里面定义长度为100的newstring就有问题了。所以说最好将newstring的定义放到main函数中。当然这样做的前提就是允许修改函数mid的原型,也就是添加一个参数。参考如下:
char *mid(char oldstring[],int start ,int num, char newstring[])
{
int sumoldstring=strlen(oldstring); //获取数据块大小
start=start-1; //转换为常规索引
//static char newstring[100]; //把newstring定义为静态数组,这样函数结束后空间不会释放
//char* newstring=new char[100]; //或者分配堆空间,不过这样的话最后要人工释放
char *p;
p=newstring;
//printf("%d\n",newstring); //10进制输出这个地址是什么目的?
for (int i=0;i<num;i++)
{
newstring[i]=oldstring[start+i];
if (i+1==num)
{
newstring[i+1]='\0';
}
}
return p;
}
int main()
{
char b[11]={"1234567890"};
char newString[100];
printf("%s\n",mid(b,2,5,newString));
printf("%s\n",mid(b,3,2,newString));
getch();
}
char *mid(char oldstring[],int start ,int num, char newstring[])
{
int sumoldstring=strlen(oldstring); //获取数据块大小
start=start-1; //转换为常规索引
//static char newstring[100]; //把newstring定义为静态数组,这样函数结束后空间不会释放
//char* newstring=new char[100]; //或者分配堆空间,不过这样的话最后要人工释放
char *p;
p=newstring;
//printf("%d\n",newstring); //10进制输出这个地址是什么目的?
for (int i=0;i<num;i++)
{
newstring[i]=oldstring[start+i];
if (i+1==num)
{
newstring[i+1]='\0';
}
}
return p;
}
int main()
{
char b[11]={"1234567890"};
char newString[100];
printf("%s\n",mid(b,2,5,newString));
printf("%s\n",mid(b,3,2,newString));
getch();
}
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
//你这个就是常说的返回了一个局部栈地址,newstring的空间在mid函数结束后就释放了,那么返回这个空间的首地址就没意义了,把newstring定义为静态的就没这个问题了,或者用动态分配方法分配堆空间
#include <stdio.h>
#include<conio.h>
#include<iostream>
#include<string>
using namespace std;
char *mid(char oldstring[],int start ,int num)
{
int sumoldstring=strlen(oldstring); //获取数据块大小
start=start-1; //转换为常规索引
static char newstring[100]; //把newstring定义为静态数组,这样函数结束后空间不会释放
//char* newstring=new char[100]; //或者分配堆空间,不过这样的话最后要人工释放
char *p;
p=newstring;
printf("%d\n",newstring); //10进制输出这个地址是什么目的?
for (int i=0;i<num;i++)
{
newstring[i]=oldstring[start+i];
if (i+1==num)
{
newstring[i+1]='\0';
}
}
return p;
}
void main()
{
char b[11]={"1234567890"};
printf("%s",mid(b,2,2));
getch();
}
#include <stdio.h>
#include<conio.h>
#include<iostream>
#include<string>
using namespace std;
char *mid(char oldstring[],int start ,int num)
{
int sumoldstring=strlen(oldstring); //获取数据块大小
start=start-1; //转换为常规索引
static char newstring[100]; //把newstring定义为静态数组,这样函数结束后空间不会释放
//char* newstring=new char[100]; //或者分配堆空间,不过这样的话最后要人工释放
char *p;
p=newstring;
printf("%d\n",newstring); //10进制输出这个地址是什么目的?
for (int i=0;i<num;i++)
{
newstring[i]=oldstring[start+i];
if (i+1==num)
{
newstring[i+1]='\0';
}
}
return p;
}
void main()
{
char b[11]={"1234567890"};
printf("%s",mid(b,2,2));
getch();
}
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
我帮你改了下,你参考下:
#include<iostream>
#include<string.h>
using namespace std;
char *mid(char oldstring[],int start ,int num)
{
int sumoldstring=strlen(oldstring); //获取数据块大小
start=start-1; //转换为常规索引
char newstring[100];
char *p;
p=newstring;
printf("传入字符串长度:%d\n",sumoldstring);
for (int i=0;i<num;i++)
*(p+i)=oldstring[start+i];
newstring[i]='\0';
return p;
}
void main()
{
char b[]="1234567890";
printf("截得字符串:%s",mid(b,2,2));
getchar();
}
#include<iostream>
#include<string.h>
using namespace std;
char *mid(char oldstring[],int start ,int num)
{
int sumoldstring=strlen(oldstring); //获取数据块大小
start=start-1; //转换为常规索引
char newstring[100];
char *p;
p=newstring;
printf("传入字符串长度:%d\n",sumoldstring);
for (int i=0;i<num;i++)
*(p+i)=oldstring[start+i];
newstring[i]='\0';
return p;
}
void main()
{
char b[]="1234567890";
printf("截得字符串:%s",mid(b,2,2));
getchar();
}
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
由于char newstring[100];的作用域在函数mid中,退出函数时被释放,所以p指针指向地址就没有了
修改后:
#include <stdio.h>
#include<conio.h>
#include<iostream>
#include<string>
using namespace std;
char *mid(char oldstring[],int start ,int num)
{
int sumoldstring=strlen(oldstring); //获取数据块大小
start=start-1; //转换为常规索引
char *p = new char(100);
for (int i=0;i<num;i++)
{
p[i]=oldstring[start+i];
if (i+1==num)
{
p[i+1]='\0';
}
}
return p;
}
void main()
{
char b[11]={"1234567890"};
printf("%s",mid(b,2,2));
getch();
}
修改后:
#include <stdio.h>
#include<conio.h>
#include<iostream>
#include<string>
using namespace std;
char *mid(char oldstring[],int start ,int num)
{
int sumoldstring=strlen(oldstring); //获取数据块大小
start=start-1; //转换为常规索引
char *p = new char(100);
for (int i=0;i<num;i++)
{
p[i]=oldstring[start+i];
if (i+1==num)
{
p[i+1]='\0';
}
}
return p;
}
void main()
{
char b[11]={"1234567890"};
printf("%s",mid(b,2,2));
getch();
}
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询