加入收藏 | 设为首页 | 会员中心 | 我要投稿 河北网 (https://www.hebeiwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

C说话指针5分钟教程

发布时间:2018-04-22 11:53:00 所属栏目:编程 来源:伯乐在线
导读:指针、引用和取值 什么是指针?什么是内存地点?什么叫做指针的取值?指针是一个存储计较机内存地点的变量。在这份教程里引用暗示计较机内存地点。从指针指向的内存读取数据称作指针的取值。指针可以指向某些详细范例的变量地点,譬喻int、long和double。
副问题[/!--empirenews.page--]

指针、引用和取值

什么是指针?什么是内存地点?什么叫做指针的取值?指针是一个存储计较机内存地点的变量。在这份教程里“引用”暗示计较机内存地点。从指针指向的内存读取数据称作指针的取值。指针可以指向某些详细范例的变量地点,譬喻int、long和double。指针也可所以void范例、NULL指针和未初始化指针。本文会对上述全部指针范例举办切磋。

按照呈现的位置差异,操纵符 * 既可以用来声明一个指针变量,也可以用作指针的取值。当用在声明一个变量时,*暗示这里声明白一个指针。其余环境用到*暗示指针的取值。

&是地点操纵符,用来引用一个内存地点。通过在变量名字前行使&操纵符,我们可以获得该变量的内存地点。

// 声明一个int指针
int *ptr;
// 声明一个int值
int val = 1;
// 为指针分派一个int值的引用
ptr = &val;
// 对指针举办取值,打印存储在指针地点中的内容
int deref = *ptr;
printf("%dn", deref);

第2行,我们通过*操纵符声明白一个int指针。接着我们声明白一个int变量并赋值为1。然后我们用int变量的地点初始化我们的int指针。接下来对int指针取值,用变量的内存地点初始化int指针。最终,我们打印输出变量值,内容为1。

第6行的&val是一个引用。在val变量声明并初始化内存之后,通过在变量名之前行使地点操纵符&我们可以直接引用变量的内存地点。

第8行,我们再一次行使*操纵符来对该指针取值,可直接得到指针指向的内存地点中的数据。因为指针声明的范例是int,以是取到的值是指针指向的内存地点存储的int值。

这里可以把指针、引用和值的相关类比为信封、邮箱地点和屋子。一个指针就仿佛是一个信封,我们可以在上面填写邮寄地点。一个引用(地点)就像是一个邮件地点,它是现实的地点。取值就像是地点对应的屋子。我们可以把信封上的地点擦掉,写上其它一个我们想要的地点,但这个举动对屋子没有任何影响。

void指针、NULL指针和未初始化指针

一个指针可以被声明为void范例,好比void *x。一个指针可以被赋值为NULL。一个指针变量声明之后但没有被赋值,叫做未初始化指针。

int *uninit; // int指针未初始化
int *nullptr = NULL; // 初始化为NULL
void *vptr; // void指针未初始化
int val = 1;
int *iptr;
int *castptr;
 
// void范例可以存储恣意范例的指针或引用
iptr = &val;
vptr = iptr;
printf("iptr=%p, vptr=%pn", iptr, vptr);
 
// 通过表现转换,我们可以把一个void指针转成
// int指针并举办取值
castptr = (int *)vptr;
printf("*castptr=%dn", *castptr);
 
// 打印null和未初始化指针
printf("uninit=%p, nullptr=%pn", uninit, nullptr);
// 不知道你会获得奈何的返回值,会是随机的垃圾地点吗?
// printf("*nullptr=%dn", nullptr);
// 这里会发生一个段错误
// printf("*nullptr=%dn", nullptr);

执行上面的代码,你会获得相同下面临应差异内存地点的输出。

iptr=0x7fff94b89c6c, vptr=0x7fff94b89c6c
*castptr=1
uninit=0x7fff94b89d50, nullptr=(nil)

第1行我们声明白一个未初始化int指针。全部的指针在赋值为NULL、一个引用(地点)可能另一个指针之前都是未被初始化的。第2行我们声明白一个NULL指针。第3行声明白一个void指针。第4行到第6行声明白一个int值和几个int指针。

第9行到11行,我们为int指针赋值为一个引用并把int指针赋值为void指针。void指针可以生涯各类其余指针范例。大大都时辰它们被用来存储数据布局。可以留意到,第11行我们打印了int和void指针的地点。它们此刻指向了同样的内存地点。全部的指针都存储了内存地点。它们的范例只在取值时起浸染。

第15到16行,我们把void指针转换为int指针castptr。请留意这里必要表现转换。固然C说话并不要求表现地转换,但这样会增进代码的可读性。接着我们对castptr指针取值,值为1。

第19行很是故意思,在这里打印未初始化指针和NULL指针。值得留意的是,未初始化指针是有内存地点的,并且是一个垃圾地点。不知道这个内存地点指向的值是什么。这就是为什么不要对未初始化指针取值的缘故起因。最好的环境是你取到的是垃圾地点接下来你必要对措施举办调试,最坏的环境则会导致措施瓦解。

NULL指针被初始化为o。NULL是一个非凡的地点,用NULL赋值的指针指向的地点为0而不是随机的地点。只有当你筹备行使这个地点时有用。不要对NULL地点取值,不然会发生段错误。

指针和数组

C说话的数组暗示一段持续的内存空间,用来存储多个特定范例的工具。与之相反,指针用来存储单个内存地点。数组和指针不是统一种布局因此不行以相互转换。而数组变量指向了数组的第一个元素的内存地点。

一个数组变量是一个常量。纵然指针变量指向同样的地点可能一个差异的数组,也不能把指针赋值给数组变量。也不行以将一个数组变量赋值给另一个数组。然而,可以把一个数组变量赋值给指针,这一点好像让人感想费解。把数组变量赋值给指针时,现实上是把指向数组第一个元素的地点赋给指针。

int myarray[4] = {1,2,3,0};
int *ptr = myarray;
printf("*ptr=%dn", *ptr);
 
// 数组变量是常量,不能做下面的赋值
// myarray = ptr
// myarray = myarray2
// myarray = &myarray2[0]

第1行初始化了一个int数组,第2行用数组变量初始化了一个int指针。因为数组变量现实上是第一个元素的地点,因此我们可以把这个地点赋值给指针。这个赋值与*ptr = &myarray[0]结果沟通,表现地把数组的第一个元素地点赋值到了ptr引用。这里必要留意的是,这里指针必要和数组的元素范例保持同等,除非指针范例为void。

指针与布局体

就像数组一样,指向布局体的指针存储了布局体第一个元素的内存地点。与数组指针一样,布局体的指针必需声明和布局体范例保持同等,可能声明为void范例。

struct person {
  int age;
  char *name;
};
struct person first;
struct person *ptr;
 
first.age = 21;
char *fullname = "full name";
first.name = fullname;
ptr = &first;
 
printf("age=%d, name=%sn", first.age, ptr->name);

(编辑:河北网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读