值传递/指针传递

在这篇博客里面,我主要讲一下值传递,参数传递
一步一步深刻剖析,所有由代码来讲话
#include <stdio.h>
#include <stdlib.h>

//这里为形参从新分配一个存储单元
//因此形参的改变不影响实参
//因此获得的打印值是a1=0,a2=0
void swap1(int x,int y)
{
            x=1;
            y=1;
}

//一级指针x指向的是a的地址
//*x就是a的地址中存的值,也就是a的值,
//因此改变*x就是改变a的值
void swap2(int *x,int *y)
{
            *x=2;
            *y=2;
}

//这里直接就是x和a指向同一片内存区,
//x只不过是a的别名,因此改x就是改a
//可是这个在c里面是编译通不过的,由于c里面尚未引用
//惋惜,我以为引用真是个好东西
void swap3(int &x,int &y)
{
             x=3;
             y=3;
}

int main()
{
         int a=0,b=0;
    
         swap1(a,b);
         printf( "a1=%d,b1=%d\n",a,b);
//这里必定要注意,若是传的参数是a,b,编译也不会出错,由于a,b和地址同样,都是int类型
//只是把a,b的值当地址传,传的地址是不对的,会出现segmentation fault
         swap2(&a,&b);
         printf( "a2=%d,b2=%d\n",a,b);
    
         swap3(a,b);
         printf( "a2=%d,b2=%d\n",a,b);
}

在进一步,传指针的时候怎么办?
#include <stdio.h>
#include <stdlib.h>

//这里新建一个指针,由于函数调用的缘由,初始化指向 NULL
//可是在函数里面,指针指向了新的地址&temp
//可是,和实参a没有什么关系
//因此a的地址依旧为 NULL(0),
//问这个地址中的值,固然会出现segmentation fault
void func1(int *x)
{
            int temp=11;
            printf( "&temp=0x%x\n",&temp);
            x=&temp;
}

//执行函数调用为int **x=&a
//x为二级指针,所指向的地址为&a,也就是存一级指针的那个地址
//*x为一级指针,为*(&a)=a;所指向的地址为存int类型值的那个地址
//a本来是指向 NULL的,可是这里*x=a把它强制指向了另一个地址&temp
//这样实参a的地址的获得了改变,但是值不是22
//由于temp这里是栈,函数过了,站也就销毁了,因此值就靠不住了
//怎么办?
//temp移到全局区域去,这样就是堆了,要不malloc,也是堆
void func2(int **x)
{
            int temp=22;
            printf( "&temp=0x%x\n",&temp);
            (*x)=&temp;
    
}

//这个函数就是用malloc来实现堆的
//给*x=a从新malloc一片存储区,而后指定这个地址上存33这个数
void func3(int **x)
{
            *x=(int *)malloc(4);
            **x=33;
}
int main()
{
         int *a;
         a= NULL;
/*    
         func1(a);
         printf( "0x%x\n",a);
         printf( "%d\n",*a);
*/
/*
         func2(&a);
         printf( "0x%x\n",a);
         printf( "%d\n",*a);
*/
///*
         func3(&a);
         printf( "0x%x\n",a);
         printf( "%d\n",*a);
//*/
}
最后,我举一个单链表的操做的实例,觉得我以为它也是涉及二级指针中一个蛮不错的例子,并且我在网上都没有找到在个人电脑上立马编译经过,能够执行年该的单链表的例子,就从网上下了一个,而后改了下
#include<stdio.h>
#include<stdlib.h>

#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define LIST_INIT_SIZE 100 //线性表存储空间初始分配量
#define LISTINCREMENT 10     //线性表存储空间的分配增量

typedef int Status;
typedef int ElemType;
typedef struct LNode
{
      ElemType    data;
      struct LNode    * next;
}LNode,*LinkList;

Status printf_L(LinkList L)
{
       //输出单链表L中的元素
       LinkList p=L;
       while(p-> next)
       {
            p=p-> next;
            printf( "%d,",p->data);
       }
       printf( "\n");
       return OK;
}//printf_L
void CreateList_L(LinkList *L)
{
        //单链表初始化
        //逆位序输入n个元素的值,创建带表头结点的单链线性表L
        int i,n;
        (*L)=(LinkList)malloc(sizeof (LNode));
        (*L)-> next= NULL;                    //创建一个带头结点的单链表
        printf( "n=");
        scanf( "%d",&n);
        printf( "\ndata=");
         for(i=n;i>0;--i)
        {
              LinkList p=(LinkList)malloc(sizeof(LNode));    //生成新结点                                                        
              scanf( "%d",&(p->data));                       //输入元素值
              p-> next=(*L)-> next;                            //插入到表头
              (*L)-> next=p;
         }
}//CreateList_L

Status ListInsert_L(LinkList *L,int i,ElemType e)
{
          //在带头结点的单链线性表L中第i个位置以前插入元素e
          LinkList p=(*L);
          int j=0;
           while(p&&j<i-1)
          {
               //寻找第i-1个结点
               p=p-> next;
               ++j;
           }
            if(!p||j>i-1)
                 return ERROR;                   //i小于1或者大于表长+1
           LinkList s;
           s = (LinkList)malloc( sizeof (LNode)); //生成新结点
           s->data=e;
           s-> next=p-> next;
           p-> next=s;
           return OK;
}//ListInsert_L

Status ListDelete_L(LinkList *L,int i,ElemType *e)
{
          //在带头结点的单链线性表L中,删除第i个元素,并由e返回其值
          LinkList p=(*L);
          int j=0;
           while (p-> next&&j<i-1)
          {
               //寻找第i-1个结点,并令p指向其前驱
               p=p-> next;
               ++j;
          }
           if(!(p-> next)||j>i-1) return ERROR; //删除位置不合理
          LinkList q=p-> next;                      //删除并释放结点
          p-> next=q-> next;
          (*e)=q->data;
          free(q);
          return OK;
}//ListDelete_L

int main()
{
         LinkList La,Lb;
         int e;
         //建立一个链表,而且插入
         CreateList_L(&La);
         printf( "\nLa=");
         printf_L(La);

         ListInsert_L(&La,3,7);//往第三个结点处插入7
         printf( "\nInsetLa=");
         printf_L(La);
         printf( "\n");

         //建立一个链表,而且删除  
         CreateList_L(&Lb);
         printf( "\nLb=");
         printf_L(Lb);
         ListDelete_L(&Lb,4,&e);//删除第四个结点,并获得第四个结点的值
         printf( "\nDeleteLb=");          printf_L(Lb);          return 0; }
相关文章
相关标签/搜索