必威的官网网络

当前位置:必威的官网-必威体育 > 必威的官网网络 > 先看这样一段代码

先看这样一段代码

来源:http://www.jlqfjt.com 作者:必威的官网-必威体育 时间:2019-11-15 19:01

前言
自作者对C指针的明亮平昔停留在:指针本身是一块内部存款和储蓄器,它保存了一块内部存款和储蓄器的地址,能够援用,但是近些日子在读代码的时候,各个指针的宣示搞得本身充足郁闷,赶紧去上学了风姿罗曼蒂克番,也只是精通了最基本的选择,总括如下。

基本知识
指南针的为主使用正如前言中说的,先看那样生机勃勃段代码:
[cpp]
#include <stdio.h>  
 
int main() 

        int i = 10; 
        int * p; 
        printf("p的地址:%dn",&p); 
        printf("未初始化时p的剧情:%dn",p); 
//      printf("未先河化访问p指向的内部存款和储蓄器:%dn",*p); // 那行代码访谈了个野指针,必然产生段错误  
必威的官网,        p = &i; 
        printf("--初始化p完毕--n"); 
        printf("p里面保存的地点:%dn",p); 
        printf("p指向的内部存款和储蓄器的剧情:%dn",*p); 
        printf("p的大小:%dn",sizeof(p)); 
        printf("p指向的内部存款和储蓄器大小:%dn",sizeof(*p)); 
        return 0; 

#include <stdio.h>

int main()
{
        int i = 10;
        int * p;
        printf("p的地址:%dn",&p);
        printf("未开端化时p的剧情:%dn",p);
//      printf("未早先化访谈p指向的内部存款和储蓄器:%dn",*p); // 这行代码访谈了个野指针,必然爆发段错误
        p = &i;
        printf("--初始化p完毕--n");
        printf("p里面保存的地址:%dn",p);
        printf("p指向的内部存款和储蓄器的剧情:%dn",*p);
        printf("p的大小:%dn",sizeof(p));
        printf("p指向的内部存储器大小:%dn",sizeof(*p));
        return 0;
}

输出结果为:[plain] view plaincopyprint?p的地址:1439276008 
未初始化时p的从头到尾的经过:0 
--初始化p完毕-- 
p里面保存的地址:1439276020 
p指向的内部存储器的剧情:10 
p的大小:8 
p指向的内部存款和储蓄器大小:4 

p的地址:1439276008
未初步化时p的从头到尾的经过:0
--初始化p完毕--
p里面保存的地址:1439276020
p指向的内部存款和储蓄器的内容:10
p的大小:8
p指向的内部存款和储蓄器大小:4

这正是指针的骨干接收,可用下图来证实:

 

指南针与数组
率先看那四个注明语句:
[cpp]
char (*a) [100]; 
char* a [100]; 

char (*a) [100];
char* a [100];
率先个是宣称了三个对准有玖十七个char成分的数组的指针(注意和指向数组首地址的char型指针分开卡塔尔;第二个是宣称了多个有九二十个char*要素的数组,数组里面装的是char *。
为了精通,大家来看那样风华正茂段代码:
[cpp]
#include <stdio.h>  
 
int main() 

        int arr[10][100]; 
        printf("sizeof(arr[0]) = %lun", sizeof(arr[0])); 
        printf("sizeof(arr[0][0]) = %lun", sizeof(arr[0][0])); 
        int *p; 
        int (*q)[100]; 
        p = &arr[0][0]; 
        q = &arr[0]; 
        printf("p = %dn",p); 
        printf("q = %dn",q); 
        printf("sizeof((*p)) = %lun", sizeof((*p))); 
        printf("sizeof((*q)) = %lun", sizeof((*q))); 
        p ; 
        q ; 
        printf("after add 1, p = %dn", p); 
        printf("after add 1, q = %dn", q); 
        return 0; 

#include <stdio.h>

int main()
{
        int arr[10][100];
        printf("sizeof(arr[0]) = %lun", sizeof(arr[0]));
        printf("sizeof(arr[0][0]) = %lun", sizeof(arr[0][0]));
        int *p;
        int (*q)[100];
        p = &arr[0][0];
        q = &arr[0];
        printf("p = %dn",p);
        printf("q = %dn",q);
        printf("sizeof((*p)) = %lun", sizeof((*p)));
        printf("sizeof((*q)) = %lun", sizeof((*q)));
        p ;
        q ;
        printf("after add 1, p = %dn", p);
        printf("after add 1, q = %dn", q);
        return 0;
}
那端代码运转后结果如下:
[plain]

sizeof(arr[0]) = 400 
sizeof(arr[0][0]) = 4 
p = 1411443800 
q = 1411443800 
sizeof((*p)) = 4 
sizeof((*q)) = 400 
after add 1, p = 1411443804 
after add 1, q = 1411444200 

sizeof(arr[0]) = 400
sizeof(arr[0][0]) = 4
p = 1411443800
q = 1411443800
sizeof((*p)) = 4
sizeof((*q)) = 400
after add 1, p = 1411443804
after add 1, q = 1411444200
因为内部存款和储蓄器是线性的,C中所谓的二维数组可是是数组的数组,arr那么些数组有12个因素,各样成分是八个尺寸为100的数组,在程序猿的心血里面,arr是三个有10行100列的二维数组。
代码里的p是二个照准int型的指针,q是一个照准“有玖十六个int的int数组”的指针。所以p和q的开头化方式是不一样的,不过起先的时候他们都指向了arr那么些数组的数组的首地址(初始时是相等的卡塔 尔(阿拉伯语:قطر‎,可是到末端分别试行自增操作之后,因为它们的体系不一致,因而根据指针自增运算的含义,他们活动的增长幅度也不风度翩翩致,p移动了sizeof(int)个字节,而q移动了sizeof(int[100])个字节,于是它们的值也大不相符,可以用下图来验证:

必威的官网 1
除此以外要专心的正是字符二维数组的宣示:
[cpp]
include <stdio.h>  
 
int main() 

        char* str[2] = {"liushuai","kobe"}; 
        printf("%s %sn",str[0],str[1]); 
        return 0; 

#include <stdio.h>

int main()
{
        char* str[2] = {"liushuai","kobe"};
        printf("%s %sn",str[0],str[1]);
        return 0;
}
出口结果分明:
[plain]
liushuai kobe 

liushuai kobe

上述是官方的字符二维数组的评释,str是贰个有多个因素的数组,每种成分的连串是贰个char*,结合方面所讲的,应该轻巧精通。
回来指针的函数和函数指针
来看下边四个注解语句:
[cpp]
int* foo(int i); 

int* foo(int i);
以此相应比较好驾驭,类比着装有指针的数组的宣示char* a[100],那是个函数注解,表明了三个名称为foo的函数,这一个函数接纳三个门类为int的参数,再次来到三个针对int型的指针。
再看上面包车型地铁宣示:
[cpp]

void (*bar)(); 

void (*bar)();
类比着数组的宣示,那一个讲话注脚了叁个照准函数的指针bar,它指向的函数供给再次来到值为void,且不收受任何参数。那是二个比较轻巧的函数的函数指针的宣示。
函数既然能够回到叁个指南针,那么一个函数能或不能够重返三个针对函数的指针呢?答案是不可否认的,看,指针是何其灵活。刚刚接触大概会有一些不适于,大家来看一个事例:
[cpp]
int (*foo(int)) (double*,char); 

int (*foo(int)) (double*,char);
类比着上边的教学,大家清楚,那个讲话评释了三个函数foo,它承当八个int类型的参数,再次回到二个照准函数的指针,供给针对的函数具宛如此的情势:选用一个double类型的指针和char型的变量作为参数,重回三个int类型的值。
我们能够用C中的typedef简化这些宣称:
[cpp]
typedef int (*ptf) (double*, char); 
ptf foo(int ); 

typedef int (*ptf) (double*, char);
ptf foo(int );

注意:typedef和#define是例外的,typedef是给“那样”的指针起了三个小名ptf,实际不是大致的进展宏替换。
好呢,大家跟着来个更反常的,假诺三个函数的参数和重临值都以函数指针,那么申明就能够更头晕目眩,比方:
[cpp] view plaincopyprint?void (*signal (int sig, void (*func) (int siga)) ) ( int siga ); 

void (*signal (int sig, void (*func) (int siga)) ) ( int siga );
实在慢点解析也轻便,我们得以用typedef来简化:
[cpp]
typedef void (*p_sig) (int); 
p_sig signal(int sig, p_sig func); 

typedef void (*p_sig) (int);
p_sig signal(int sig, p_sig func);
signal那么些函数的参数func是四个函数指针,重返了八个函数指针,且二种指针须求针对的函数具备相似种格局(采用三个int型的参数,重临空值卡塔尔国。
通过函数指针调用函数
依旧通过叁个事例来表明难题:
[cpp]
#include <stdio.h>  
 
void printMyName(); 
 
int main() 

        void (*f)(); 
        f = printMyName; 
        f(); 
        f = &printMyName; 
        f(); 
        return 0; 

 
void printMyName() 

        printf("liushuaikoben"); 

#include <stdio.h>

void printMyName();

int main()
{
        void (*f)();
        f = printMyName;
        f();
        f = &printMyName;
        f();
        return 0;
}

void printMyName()
{
        printf("liushuaikoben");
}
是否超轻松啊。注意用“&函数名”和“函数名”开首化一个函数指针都是合法的,因为C中等学园函授数名会被调换为指向那几个函数的指针。
指南针真是充满智慧的成品,通过函数指针,能够轻便实现面向对象语言中多态等一些高级天性(举例Java的接口,C 的虚函数卡塔 尔(英语:State of Qatar),真的太美妙了。
对此大神,这几个东西恐怕都以小产科,但是小编C真的没怎么用过,搞懂了这么些,小编也很欢喜了。
最终送我们一句话:
并不是因为走得太远,就忘了投机那个时候缘何出发。

 

笔者对C指针的精晓一向停留在:指针本人是一块内存,它保存了一块内部存款和储蓄器的地址,能够援用,可是方今在读代码的时候,种种指针的声...

本文由必威的官网-必威体育发布于必威的官网网络,转载请注明出处:先看这样一段代码

关键词: 必威88app登录

上一篇:问题一: f=1 2 ... 9(累加)

下一篇:没有了