在这篇博客里面,我主要讲一下值传递,参数传递
一步一步深入剖析,全部由代码来说话
#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 <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 <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
#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;
}
{
//单链表初始化
//逆位序输入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;
}
转载于:https://blog.51cto.com/nnssll/206931