c语言指针超出范围怎么办,【C语言指针】两篇文章彻底搞懂指针终篇——彻底瓦解C语言指针的难点...

前文回顾

我们先回顾一下开篇中的重点

1、C语言程序在运行时的四个重要区域:堆区、栈区、静态区、只读区

2、*操作符是个单目运算操作符,返回操作数的值所指向的地址单元。

如果你找不到开篇在简书中搜索ID:孟南知 查看更多好文

C语言指针的基本操作

如果你已经非常熟悉指针操作,可以跳过这一段看靠后的重点!

定义一个指针

声明指针我们已经在上篇中详细的说过

我们在定义一个指针的时候仅仅是在栈中声明了一个8个字节(4个字节)的变量

这个指针型变量的值是一个地址,而变量类型用于分辨从地址读取多少个字节的内容

以上内容在上篇有详细说明这里不再讨论

指针和数组的关系

我们现在来说说数组,在我的理解中数组其实可以等价于一个指针

int a[20];    a[10]=100;

int *b=(int *)malloc(sizeof(int)*20) ;    b[10]=100;

cout<

上述代码我们分别用数组的方式输入和指针的方式输出

我们惊奇的发现,这两种方式的结果完全一样

这里我也不敢说这两种方式是否完全等价,但使用方法是完全等价的

对指针运算比如:p+5。这个运算是p的值加上5*指针类型长度。数组在程序中是顺序存储的。

这里我们特别说一下二维数组,二维数组实际上在内存中和一位数组的存储结构是一样的。

这里就不画图了,也就是第二行接着第一行后面继续存储。

当我们试图把一个二维数组赋值给一个指针,编译器报错了。

所以我们必须用这种方法声明。

inta[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}};

int(*p)[4]=a;

如果我们要操作这个指针需要用到这种结构*(*(p+i)+j),其中i和j分别代表一二维下标。

多维数组在本质上和一维数组是一样的,数字的作用即是界限。

所以在多维数组的使用中,必须指定后续的界限否则与一维数组无异,编译器禁止了这种情况发生。

指针作为函数参数

我们先来说说普通变量作为参数

函数被调用后,程序在栈中新建立一个变量,在把实参的值赋值给它,其实指针作为参数是一模一样的

我们看下面这段代码

void func(int *p){

*p=66;

}

void main(){

int a;    int *p=a;

func(p);

}

图-指针作为参数

最后我们输出a的结果必然是66,注意这里函数参数中的*p属于一个声明语句和*操作符无关。

我们发现,虽然我们改变了 函数体外变量的值,但是函数传参的过程和普通函数其实是一模一样的。

我们复制了实参指针变量p中的地址,新建了一个指针变量并把p的值赋值给了这个变量即形参p。

双重指针作为参数

在学习数据结构的过程中,令我最头疼的就是双重指针作为参数,让我彻底放弃C语法改用C++。

不过我们有了上面的基础,聪明的人已经明白为什么在C中要使用双重指针作为参数。

我们拿最经典的例子,即在无头结点单链表中,怎么在函数中删除第一个结点。

在看代码之前我们往回先看指针作为参数的图,如果我们不用双重指针,形参p与实参p并无任何关系

我们可以改变实参p所指向变量的值,却无法改变实参p自身的值。

#include     //下面是完整代码,涉及数据结构知识

#include    //printf用这不舒服,除了输入输出,并未用C++语法

using namespace std;

typedef struct List *LinkList;

struct List{

int data;

LinkList next;

};

void func(List **l){

LinkList p=(*l);    //*l即是实参l本身

(*l)=(*l)->next;

free(p);

}

int main(){

List *l=(LinkList)malloc(sizeof(List));

l->data=1;

l->next=(LinkList)malloc(sizeof(List));

l->next->data=2;

l->next->next=NULL;

func(&l);    //&在C中是取址符,是合法的,不能用于函数形参。

cout

return 0;

}

C++中的引用传参和指针究竟有什么区别

如果我们用C++语法,我们将再也不去管什么双重指针

因为我们有更好的选择就是引用传参,下面我们一张图解释什么是引用

所谓引用就是取代了传参的过程,自始至终使用的都是一个变量。

本节可能与现实情况存在出入,可以这么理解但我并不知道是否真的不会创建形参。

总结

最后我们说一句,岁月静好远离C语言,现在ARM指令集兴起,包括国产指令集也开始投入使用。

正是取代上个世纪遗产的好时候,也出现了一些新的编译型语言比如Go,现在搞编程的这么多,却都是在用和办公软件一样的的东西。

为何不想设计一个全新的编译型语言,彻底瓦解底层几乎全部用C语言的时代。

你可能感兴趣的:(c语言指针超出范围怎么办)