求教C语言指针作为实参取不到值的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求教C语言指针作为实参取不到值的问题相关的知识,希望对你有一定的参考价值。

#include <stdio.h>
#include <string.h>
main()
int *inputTenNum();
void doing(int *p);

int *p1 = NULL;

p1 = inputTenNum();
printf("%d\n",*p1);
doing(p1);



int *inputTenNum()

int a[10];
scanf("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",&a[0],&a[1],&a[2],&a[3],&a[4],&a[5],&a[6],&a[7],&a[8],&a[9]);

return a;


void doing(int *p)
printf("%d\n",*p);


输入 1,2,3
输出 1
-858993460
为什么 最后一个是-858993460,都是同一个地址变量啊

参考技术A 在一个函数内所分配的空间是静态的当这个函数执行完后这个函数的空间就没有了!所以你在访问该空间就会出错!就如你上的int *inputTenNum()

int a[10];//这个是inputTenNum函数里面分配的 scanf("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",&a[0],&a[1],&a[2],&a[3],&a[4],&a[5],&a[6],&a[7],&a[8],&a[9]);

return a;
如何你想跨函数使用内存就可以用malloc函数如下:
#include <stdio.h>
#include <string.h>
#include <malloc.h>
main()
int *inputTenNum();
void doing(int *p);

int *p1 = NULL;

p1 = inputTenNum();
printf("%d\n",*p1);
doing(p1);



int *inputTenNum()

int * a,i;
a=(int *)malloc(sizeof(int)*10);
for(i=0;i<10;++i)
scanf("%d",&a[i]);

return a;


void doing(int *p)
printf("%d\n",*p);
参考技术B a[10]这个数组是静态的,只能在int *inputTenNum()函数里使用,函数结束,a[10]就出栈释放了,逻辑上返回a[10]的地址是不允许的,如楼上所说,使用动态变量就能跨函数使用,来解决这一问题 参考技术C

/*

36 25 14 74 85 96 32 65 98 45

36  25  14  74  85  96  32  65  98  45

Press any key to continue

*/

#include <stdio.h>
#include <string.h>
int main() 
int *InputnNum(int n);
void Doing(int *p,int n);
int *p = InputnNum(10);
// printf("%d\\n",*p);
Doing(p,10);
return 0;


int *InputnNum(int n) 
static int i,a[10];
for(i = 0; i < n; ++i)
scanf("%d",&a[i]);
return a;


void Doing(int *p,int n) 
int i;
for(i = 0; i < n; ++i)
printf("%d  ",*(p + i));
printf("\\n");

C语言指针用法详解 指针作为函数的参数

欢迎指正!!!!

标明出处,欢迎转载!!!!


函数传参:就是形参复制一份实参的值,抱回函数体里算

  • 函数内部修改外部变量的值,需要一级指针;
  • 函数内部修改外部指针变量的值,需要二级指针;

经典问题1 :交换CET1 和 CET2 的值(一级指针交换值)

  • Wrong:

void swap_val(int a, int b)
{
    int tmp = a;
    a = b;
    b = tmp;
}

  

错误:因为交换的是副本,真品没改变的
 
  • Practice:

#include <bits/stdc++.h>
using namespace std;
/*** 通过一级指针交换值  */
void swap_val(int *a, int *b)
{
    /***
    **  ————>> here
    **   a == &CET1 , b == &CET2
    **  *a ==  CET1 ,*b ==  CET2
    ***/
    cout<<"      函数体 交换前  a == "<<a<<"   b == "<<b<<endl;
    cout<<"      函数体 交换前 *a == "<<*a<<" *b == "<<*b<<endl;
    int tmp = *a; /// 三变量换的不是值,是a、b 分别指向的值
    *a = *b;
    *b = tmp;
    cout<<"      函数体 交换后  a == "<<a<<"   b == "<<b<<endl;
    cout<<"      函数体 交换后 *a == "<<*a<<" *b == "<<*b<<endl<<endl<<endl;;
}
int main()
{
    int CET1 = 424;
    int CET2 = 426;
    cout<<"函数前 CET1 == "<<CET1<<" CET2 == "<<CET2<<endl;
    cout<<"函数前  &CET1 == "<<&CET1<<" &CET2 == "<<&CET2<<endl<<endl<<endl;
    swap_val(&CET1,&CET2);
    /***
    **   传入的是形参是&CET1和 &CET2
    **   相当于  int *a = & CET1 , int *b = &CET2
    **   三醒指针: 指针 a 的类型是 int * ,指向的类型 int  指向的值是 &CET1
    **   三醒指针: 指针 b 的类型是 int * ,指向的类型 int  指向的值是 &CET2
    **  ----->> 出门左转
    ***/
    cout<<"函数后 CET1 == "<<CET1<<" CET2 == "<<CET2<<endl;
    cout<<"函数后  &CET1 == "<<&CET1<<" &CET2 == "<<&CET2<<endl<<endl<<endl;
}

技术分享

  • Reason

技术分享

1.此时形参(a 、b )和实参建立的是 指针初始化,指向为&CET1,&CET2 的关系
2.通过改变指针指向完成交换
3.传入的是地址,指针操作的是唯一的

经典问题2 :交换CET1 和 CET2 的地址(二级指针交换地址)

  • practice

#include <bits/stdc++.h>
using namespace std;
/*** 通过二级指针交换值的地址  */
void swap_val(int **a, int **b)
{
    /***
    **  ————>> here
    **   Int **a = &CET1
    **   1.a 赋值于&CET1,a == &CET1
    **   2.*a == CET1
    **   3.&(*a) ==a
    **   Int **b = &CET2
    **   1.b 赋值于&CET2,b == &CET2
    **   2.*b == CET2
    **   3.&(*b) ==b
    ***/
    cout<<"             函数体  交换前      a == "<<a<<" b == "<<b<<endl;
    cout<<"             函数体  交换前     *a == "<<*a<<" *b == "<<*b<<endl;
    cout<<"             函数体  交换前  &(*a) == "<<&(*a)<<" &(*b) == "<<&(*b)<<endl;
    cout<<"             函数体  交换前    **a == "<<**a<<" **b == "<<**b<<endl<<endl<<endl;
    int *tmp = NULL;
    tmp = *a;
    *a = *b;
    *b = tmp;
    cout<<"             函数体  交换后      a == "<<a<<" b == "<<b<<endl;
    cout<<"             函数体  交换后     *a == "<<*a<<" *b == "<<*b<<endl;
    cout<<"             函数体  交换后  &(*a) == "<<&(*a)<<" &(*b) == "<<&(*b)<<endl;
    cout<<"             函数体  交换后    **a == "<<**a<<" **b == "<<**b<<endl<<endl<<endl;
}
int main()
{
    int *CET1 = (int*)malloc(sizeof(int));
    int *CET2 = (int*)malloc(sizeof(int));
    ///**   三醒指针: 指针 CET1,CET2 的类型是 int * ,指向的类型 int  只是初始化指针,没有给定指向  指针本身的内存是系统分配的 值也是组织分配的
    cout<<"初始化   CET1 == "<<CET1<<" CET2 == "<<CET2<<endl;
    int mark1 = 424;
    int mark2 = 426;
    CET1 = &mark1;
    CET2 = &mark2;
    ///**    指针 CET1,CET2 指向  mark1 ,mark2  值是mark1 ,mark2 的地址
    cout<<"初始化 &mark1 == "<<&mark1<<" &mark2 == "<<&mark2<<endl;
    cout<<"函数前   CET1 == "<<CET1<<"   CET2 == "<<CET2<<endl;
    cout<<"函数前  &CET1 == "<<&CET1<<"  &CET2 == "<<&CET2<<endl<<endl<<endl;
    swap_val(&CET1,&CET2);
    /***
    **   本来 CET1,CET2 是个指针
    **   取址符后传入的当然就是 指针的地址
    **   相当于  int **a = & CET1 , int **b = &CET2
    **   三醒指针: 指针 a 的类型是 int ** ,指向的类型 int * 指向的值是 &CET1
    **   三醒指针: 指针 b 的类型是 int ** ,指向的类型 int * 指向的值是 &CET2
    **  ----->> 出门左转
    ***/
    cout<<"最后结果  CET1 == "<<CET1<<" CET2 == "<<CET2<<endl;
    cout<<"函数后   &CET1 == "<<&CET1<<"  &CET2 == "<<&CET2<<endl;
}

 技术分享

技术分享

技术分享

  • Reason

技术分享

重点语句的解释:

技术分享


经典问题 3:函数体中为指针的指针分配地址(二级指针分配新的内存)

  • practice

#include <bits/stdc++.h>
using namespace std;
/*** 通过二级指针购置指针新的地址  */
void allocte(int **a)
{
    /***
    **   int **a = &ptr ;
    **     a = &ptr
    **     *a = ptr
    **   三省指针: 指针a的类型是 int ** ,指针 a的指向类型为int* ,指向&ptr
    ***/
   *a = (int *)malloc(sizeof(int));
   /// 新的地址 : 改变了*a的指向 ,改变了ptr
}
int main()
{
   int *ptr = NULL;
   /// 三省指针: 指针ptr的类型是 int * ,指针 ptr的指向类型为int ,指向NULL
   /// ** 记得 ptr 是指针 就是地址  *ptr 才是值
   cout<<"  ptr : "<<ptr<<endl;
   cout<<" &ptr: "<<&ptr<<endl<<endl<<endl;
  // cout<<" *ptr: "<<*ptr<<endl; /// ptr是空  然后 ptr的指向  当然是非法
   allocte(&ptr);
   cout<<"  ptr : "<<ptr<<endl;
   cout<<" &ptr: "<<&ptr<<endl;
   cout<<" *ptr: "<<*ptr<<endl; /// ptr是空  然后 ptr的指向
}

技术分享

  • Reason

技术分享

 

 

 

 

以上是关于求教C语言指针作为实参取不到值的问题的主要内容,如果未能解决你的问题,请参考以下文章

c拾遗-二级指针数组内函数

c拾遗-二级指针数组内函数

c语言 指针传参

C语言指针用法详解 指针作为函数的参数

C 语言二级指针作为输入 ( 指针数组 | 将 二级指针 作为函数输入 | 抽象函数业务逻辑 )

关于C语言中函数修改结构体的值的问题