一.变量存储

 #include <stdio.h>
int main(void)
{
int i = ;
printf(“%d\n”, i);
printf(“%d\n”, &i); //十进制打印i的地址
printf(“%x\n”, &i); //十六进制打印i的地址
return();
}
/*得到结果:
ray@ray-Lenovo:~/Documents/Exec_important/Daily$ ./0128-2
39
23300652
1638a2c
ray@ray-Lenovo:~/Documents/Exec_important/Daily$ ./0128-2
39
1367552540
5183321c
ray@ray-Lenovo:~/Documents/Exec_important/Daily$ ./0128-2
39
1684339276
6464fa4c
每次得到的地址都不同*/

二. 什么是指针

#include <stdio.h>
int main(void)
{
char a, *pa;
a = ;
pa = &a; /* pa指向变量a的地址 */
*pa = ; /* 给变量a的地址的内容赋值为20, 即a=20*/
printf("%d\n", a);
}
/* 得到结果: 20 */

三. 指针与数组名

#include <stdio.h>
int main(void)
{
int i, *pa, a[] = {, , , , , , , , , };
//int * const pa = a; //不行, pa被定义为常量指针了
pa = a; printf("array mode:\n");
for(i = ; i < ; i++)
printf("%d ", a[i]);
printf("\npointer mode:\n");
for(i = ; i < ; i++)
printf("%d ", *(a+i));
printf("\n\n");
for(i = ; i < ; i++)
printf("%d ", pa[i]);
printf("\n");
for(i = ; i < ; i++)
printf("%d ", *(pa+i));
printf("\n");
for(i = ; i < ; i++)
{
printf("%d ", *pa);
pa++;
}
printf("\n");
return ;
}
/*执行后显示:
array mode:
0 1 2 3 4 5 6 7 8 9
pointer mode:
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
*/

四. const int *pi与int *const pi的区别

#include <stdio.h>
int main(void)
{
int i1 = , i2 = ;
const int *pi = &i1;
pi = &i2; /* 注意这里, pi 可以在任意时候重新赋值一个新内存地址*/
i2 = ; /* 这里能用*pi = 80 来代替吗?当然不能! */
printf("%d\n", *pi); /* 输出是 80 */
return ;
}
/*pi 的值是可以被修改的。即它可以重新指向另一个地址的,但是,不能通过*pi 来修改 i2 的值*/
#include <stdio.h>
int main(void)
{
int i1 = , i2 = ;
int *const pi = &i1;
/* pi = &i2; 注意这里, pi 不能再这样重新赋值了,即不能再指向另一个新地址 */
i1 = ; /* 这里能用 *pi = 80; 来代替吗?可以,这里可以通过*pi 修改 i1 的 */
printf("%d\n", *pi); /* 输出是 80 */
return ;
}
/*pi 的值是可以被修改的。即它可以重新指向另一个地址的,但是,不能通过*pi 来修改 i2 的值*/

总结:

1) 如果 const 修饰在*pi 前,则不能改的是*pi(即不能类似这样: *pi=50;赋值)而不是指 pi。
2) 如果 const 是直接写在 pi 前,则 pi 不能改(即不能类似这样:pi=&i; 赋值)。

五. 函数参数的传递

Q1. 值传递

#include <stdio.h>
void Exchg1(int x, int y)
{
int tmp;
tmp = x;
x = y;
y = tmp;
printf("x = %d, y = %d\n", x, y);
} int main(void)
{
int a = , b = ;
Exchg1(a, b);
printf("a = %d, b = %d\n", a, b);
return ;
}
/*编译执行,输出:
x = 6, y = 4
a = 4, b = 6
*/

Q2. 地址传递

#include <stdio.h>
void Exchg2(int *px, int *py)
{
int tmp = *px;
*px = *py;
*py = tmp;
printf("*px = %d, *py = %d\n", *px, *py);
} int main(void)
{
int a = , b = ;
Exchg2(&a, &b);
printf("a = %d, b = %d.\n", a, b);
return ;
}
/*编译执行,输出:
*px = 6, *py = 4
a = 6, b = 4
*/

Q3. 引用传递

#include <stdio.h>
void Exchg3(int &x, int &y) /* 注意定义处的形式参数的格式与
值传递不同 */
{
int tmp = x;
x = y;
y = tmp;
printf("x = %d, y = %d.\n", x, y);
} main()
{
int a = ;
int b = ;
Exchg3(a, b); /*注意:这里调用方式与值传递一样*/
printf("a = %d, b = %d.\n", a, b);
}
/*编译报错,因为C没有引用的用法,C++才*/

六. 指向另一指针的指针

#include <stdio.h>
void find1(char array[], char search, char **ppa)
{
int i;
for(i = ; *(array + i) != ; i++)
{
if(*(array + i) == search)
{
*ppa = array + i;
break;
}
else if(*(array + i) == )
{
*ppa = ;
break;
}
}
} int main(void)
{
char str[] = {"afsdfsdfdf\0"};
char a = 'd';
char *p = ;
find1(str, a, &p);
if( == p)
printf("没找到!\n");
else
printf("找到了,p = %x\n", p);
return ;
}
/*编译执行,输出:
找到了,p = 6393eb53
*/

七. 函数名与函数指针

 1.

#include <stdio.h>
void MyFun(int x); //也可写成void MyFun(int)
void (*FunP)(int); //也可写成void (*FunP)(int x)
int main(int argc, char* argv[])
{
MyFun();
FunP = &MyFun;
(*FunP)();
} void MyFun(int x)
{
printf("%d\n", x);
}
/*编译执行,输出:
10
20
*/

2.

#include <stdio.h>
void MyFun(int x); //也可写成void MyFun(int)
void (*FunP)(int); //也可写成void (*FunP)(int x)
int main(int argc, char* argv[])
{
MyFun();
FunP = MyFun;
FunP();
return ;
} void MyFun(int x)
{
printf("%d\n", x);
}
/*编译执行,输出:
10
20
*/

3.

#include <stdio.h>
void MyFun(int x); //也可写成void MyFun(int)
void (*FunP)(int); //也可写成void (*FunP)(int x)
int main(int argc, char* argv[])
{
MyFun();
FunP = &MyFun;
FunP();
} void MyFun(int x)
{
printf("%d\n", x);
}
/*编译执行,输出:
10
20
*/

4.

#include <stdio.h>
void MyFun(int x); //也可写成void MyFun(int)
void (*FunP)(int); //也可写成void (*FunP)(int x)
int main(int argc, char* argv[])
{
MyFun();
FunP = MyFun;
(*FunP)();
} void MyFun(int x)
{
printf("%d\n", x);
}
/*编译执行,输出
10
20
*/

5.

#include <stdio.h>
void MyFun(int x); //也可写成void MyFun(int)
void (*FunP)(int); //也可写成void (*FunP)(int x)
int main(int argc, char* argv[])
{
(*MyFun)();
FunP = &MyFun;
(*FunP)();
} void MyFun(int x)
{
printf("%d\n", x);
}
/*编译执行,输出:
10
20
*/

总结上面: 1)  其实, MyFun 的函数名与 FunP 函数指针都是一样的, 即都是函数指针。 MyFun 函数名是一个函数指针常量,而 FunP 是一个函数数指针变量,这是它们的关系。
2)  但函数名调用如果都得如(*MyFun)(10)这样,那书写与读起来都是不方便和不习惯的。所以 C 语言的设计者们才会设计成又可允许 MyFun(10)这种形式地调用(这样方便多了并与数学中的函数形式一样,不是吗?)。
3)  为统一起见, FunP 函数指针变量也可以 FunP(10)的形式来调用。
4)  赋值时,即可 FunP = &MyFun 形式,也可 FunP = MyFun。

6.

#include <stdio.h>
void MyFun(int x); //也可写成void MyFun(int)
typedef void (*FunType)(int);
FunType FunP;
int main(int argc, char* argv[])
{
//FuncType FunP;/*函数指针变量也可以是局部的*/
MyFun();
FunP = &MyFun;
FunP();
return ;
} void MyFun(int x)
{
printf("%d\n", x);
}
/*编译执行,输出:
10
20
*/

7.

#include <stdio.h>
void MyFun1(int x);
void MyFun2(int x);
void MyFun3(int x);
typedef void (*FunType)(int);
void CallMyFun(FunType fp, int x);
int main(int argc, char* argv[])
{
CallMyFun(MyFun1, );
CallMyFun(MyFun2, );
CallMyFun(MyFun3, );
} void CallMyFun(FunType fp, int x)
{
fp(x);
} void MyFun1(int x)
{
printf("函数MyFun1中输出:%d\n", x);
} void MyFun2(int x)
{
printf("函数MyFun2中输出:%d\n", x);
} void MyFun3(int x)
{
printf("函数MyFun3中输出:%d\n", x);
}
/*
函数MyFun1中输出:10
函数MyFun2中输出:20
函数MyFun3中输出:30
*/

《彻底搞定C指针》文档整理的更多相关文章

  1. 五分钟轻松搞定产品需求文档!这可能史上最全PRD文档模板

    本文由  @JustWu 原创发布于社区 为什么写这篇文章? 第一:写PMCAFF的PRD文档,大家都是用户,比较好参考与理解,方便大家来找我写的不好的地方. 第二:我在自学PRD文档的编写过程中,总 ...

  2. 将Html文档整理为规范XML文档

    有多种方式可以在.NET 平台进行HTML文件解析.数据提取,其中最简单.稳妥的办法是先使用工具将Html文档整理成XML文档,再通过XML Dom模型或XPath灵活地进行数据处理.SGML便是一个 ...

  3. NodeJS-001-Nodejs学习文档整理(转-出自http://www.cnblogs.com/xucheng)

    Nodejs学习文档整理 http://www.cnblogs.com/xucheng/p/3988835.html 1.nodejs是什么: nodejs是一个是javascript能在后台运行的平 ...

  4. Ionic2文档整理

    来自:Rainey's Blog 原文地址:http://rainey.space/2016/04/06/Ionic2_Chinese_Document/ Github:https://github. ...

  5. dotNET跨平台相关文档整理

    一直在从事C#开发的相关技术工作,从C# 1.0一路用到现在的C# 6.0, 通常情况下被局限于Windows平台,Mono项目把我们C#程序带到了Windows之外的平台,在工作之余花了很多时间在M ...

  6. 彻底搞定c指针

    第一篇 变量的内存实质 一.先来理解C语言中变量的实质 要理解C指针,我认为一定要理解C中“变量”的存储实质,所以我就从“变量”这个东西开始讲起吧! 先来理解理解内存空间吧!请看下图: 内存地址→   ...

  7. appium python andiroid自动化文档整理笔记。

    利用一天时间去整理appium for android文档.传送门 利用业余时间自己翻阅资料,google.百度等去查找,费劲一番功夫,最后终于成行了这篇文档. 也是作者对最近自己的学习的一个总结吧, ...

  8. redis module 学习—官网文档整理

    前言 redis在4.0版本中,推出了一个非常吸引的特性,可以通过编写插件的模式,来动态扩展redis的能力.在4.0之前,如果用户想拥有一个带TTL的INCRBY 命令,那么用户只能自己去改代码,重 ...

  9. Linux文档整理之【Jenkins+Docker自动化部署.Net Core】

    这次整理的文档是Jenkins+Docker实现自动化部署,很早之前就写的,今天有时间就搬到博客园做个记录. Jenkins是基于Java开发的一种持续集成工具,主要用于持续.自动的构建/测试软件等相 ...

  10. Linux文档整理之【Nginx安装Docker】

    这次整理的文档是Docker安装 先说明下我用的系统是Linux Centos,不同的Linux版本差别不大. 1.安装依赖包 sudo yum install -y yum-utils device ...

随机推荐

  1. 小项目--反eclass

    前言—— 最近会把前一段时间闲的无聊写的一些很小的项目写一些博客,用来练练手. 引子—— 最近班里有个很讨厌的软件,,,,教育局规定每个学校要上传多媒体使用记录,所以学校就给班里每台电脑上装了一个比较 ...

  2. mybatis常用jdbcType数据类型

    MyBatis 通过包含的jdbcType类型 BIT         FLOAT      CHAR           TIMESTAMP       OTHER       UNDEFINED ...

  3. HTML5的结构学习(1) --- 新增的主体结构元素

      1.article 元素 解释:代表文档.页面和应用程序中独立的.完整的.可以被独自引用的内容. 主要用途:博客中的文章.评论,贴吧中的帖子,或者独立的插件等. article中可以包含多种元素例 ...

  4. 解决eclipse无法解析shared_ptr

    今天心血来潮更新了一下机器上的ubuntu,装了14.04版本,原来是32位的,换成64的之后感觉是快了不少(加了内存).因为不少软件没做备份,包括eclipse,所以只得重装,重装之后的麻烦事儿就是 ...

  5. Wcf实现IServiceBehavior拓展机制

    IServiceBehavior接口 描述:提供一种在整个服务内修改或插入自定义拓展机制: 命名空间:  System.ServiceModel.Description程序集:  System.Ser ...

  6. Linux命令(持续更新ing)

    *.命令语法:  a.在进行参数设定时,通常为“-”号,若为完整参数名称,则输入“--”符号;  b.指令太长的时候,可以使用“\”符号使指令连续到下一行;  c.各种符号的意义:    ''     ...

  7. Filter与Servlet的区别和联系

    Filter Servlet 接口 实现Filter接口 实现Servlet接口 使用步骤 1.创建类,继承接口 2.实现方法 init() doFilter() destroy() 3.配置WEB- ...

  8. logstash Codec

    Logstash 使用一个名叫FileWatch的Ruby Gem库来监听文件变化,这个库支持glob扩展文件路径, 而且会记录一个叫.sincedb的数据库文件来跟踪被监听日志文件的当前读取位置,所 ...

  9. VC实现图片拖拽及动画

    基础知识 1.PictureBox控件的使用 2.加载位图文件 1.通过文件路径获得位图句柄 //获得位图句柄  void CMovePictureDlg::GetHandleFromPath(CSt ...

  10. pycares cffi

    pypy 5.0.1 由于 cpyext 有 bug,用不了异步 DNS 解析库 pycares .花了一周时间,对照着 pycares 的 C 代码自己重写了个 cffi 的实现.在 windows ...