关于C语言指针的一些新认识(2)
在使用C语言编程的过程中,遇到了很多关于指针使用的小问题,这里总结一下就当做是编程的小技巧啦
Q1. 如何用printf( )输出指针
这个问题相当于如何用printf( )输出地址,答案是:用"%p",请看下面的代码:
|
#include <stdio.h> int main() { freopen("ans.txt", "w", stdout); int msg = 10; int * ptr = &msg; printf("ptr ponits to: %p\n", ptr); printf("msg's addr is: %p\n", &msg); printf("ptr's addr is: %p\n", &ptr); return 0; } |
输出的结果为:

Q2. 宏定义NULL是什么?
这里我编写了如下测试程序:
|
#include <stdio.h> int main() { freopen("ans.txt", "w", stdout); int * ptr = NULL; printf("ptr ponits to: %p\n", ptr); return 0; } |
输出为:

从这里我们可以推测NULL很可能是0的宏定义。但是如果编写这样的代码:
|
#include <stdio.h> int main() { int num = NULL; //这里会提示警告!! printf("num is: %d\n", num); return 0; } |
结果会提示警告:

从警告来看,NULL应该是一个指针。实际上,在C语言中NULL是这样定义的:#define NULL ((void *)0),即通过强制类型转换将整数0定义成了通用指针类型:0x00000000(这是指针常量,即地址,不是指针变量,标识符是不能以数字开头的)。
Q3.二级指针
同样是一个占用4B的指针(32位系统中),只不过它指向的内容是一个一级指针。
Q4.动态的声明二维数组
|
#include <stdio.h> #include <stdlib.h> #define SIZE 100 int main() { int** td_arr = NULL; /* 动态分配SIZE个一级指针 */ td_arr = (int**)calloc(SIZE, sizeof(int*)); /* 为每个一级指针动态分配SIZE个int型变量的内存空间 */ for(int i = 0; i < SIZE; i++) { td_arr[i] = (int*)calloc(SIZE, sizeof(int)); } return 0; } |
这里动态声明的数组并不像真正的数组那样——分配的是一块儿连续的内存地址,而是一些块儿装的内存,如下图:

如果仔细观察图中内存块儿之间的地址编号就会发现一个很有意思的现象:一级指针块和数组#1块之间并不是紧密相连的,而是相差12B(=0x00521918 - 0x0052190C)的长度。同样的,数组块之间也相隔同样的长度,可能这是为减轻数组越界带来的问题而故意保留的。
Q6. 如何实现对指针的引用传递?
假设你需要一个数组来存储输入的数据,但是你又不知道数据量的大小,这时你就需要一个动态数组。如果你想在一个子函数里完成这个输入工作,同时又不想这个数组是一个全局变量,那么你就需要用到对指针的引用来完成任务。好吧,着实挺复杂的…
这个例子是对一个做参数的整型指针的引用:
|
void function(int* &arg); |
这是一个要求输入一定量整数的程序,用如上的方法实现:
|
#include <stdio.h> #define CHUNK 5 int SIZE = 100; int inputNum(int* &, int); int main() { int* arr = (int*)malloc(SIZE*sizeof(int)); int lng = 0; lng = inputNum(arr, lng); return 0; } int inputNum(int* &arr, int i) { int cur = 0; while(scanf("%d", &cur == 1) { if(lng + CHUNK > SIZE) { arr = (int*)relloc(arr, lng + CHUNK); } arr[lng] = cur; lng++; } return lng; } |
Q7. 回调函数(指针变量指向函数)
回调函数就是一个通过函数指针调用的函数(感觉就像汇编里的标号,用一个指针标记一段代码,在需要的时候调用这段代码)。这种函数需要这样声明:
|
type (*func)([arg1, arg2, ...]); |
下面就通过一段程序展示一下它的威力:(以下代码摘自:深入理解指针函数)
|
#include<stdio.h> #include <assert.h> double GetMin(double *dbData, int iSize) // 求最小值 { double dbMin; int i; assert(iSize>0); dbMin=dbData[0]; for (i=1; i<iSize; i++){ if (dbMin>dbData[i]) { dbMin=dbData[i]; } } return dbMin; } double GetMax(double *dbData, int iSize) // 求最大值 { double dbMax; int i; assert(iSize>0); dbMax=dbData[0]; for (i=1; i<iSize; i++){ if (dbMax< dbData[i]) { dbMax=dbData[i]; } } return dbMax; } double GetAverage(double *dbData, int iSize) // 求平均值 { double dbSum=0; int i; assert(iSize>0); for (i=0; i<iSize; i++) { dbSum+=dbData[i]; } return dbSum/iSize; } double UnKnown(double *dbData, int iSize) // 未知算法 { return 0; } typedef double (*PF)(double *dbData, int iSize); // 定义函数指针类型 PF GetOperation(char c) // 根据字符得到操作类型,返回函数指针 { switch (c) { case 'd': return GetMax; case 'x': return GetMin; case 'p': return GetAverage; default: return UnKnown; } } int main(void) { double dbData[]={3.1415926, 1.4142, -0.5,999, -313, 365}; int iSize=sizeof(dbData)/sizeof(dbData[0]); char c; printf("Please input the Operation :\n"); c=getchar(); printf("result is %lf\n", GetOperation(c)(dbData,iSize)); // 通过函数指针调用函数 } |
说到这来,我对指针的总结也算告一段落了,之后如果遇到新的问题还会继续补充…
完。
关于C语言指针的一些新认识(2)的更多相关文章
- 关于C语言指针的一些新认识(1)
Technorati 标签: 指针,数组,汇编,C语言 前言 指针是C语言的精华,但我对它一直有种敬而远之的感觉,因为一个不小心就可能让你的程序陷入莫名其妙的麻烦之中.所以,在处理字符串时,我总是能用 ...
- C语言指针学习
C语言学过好久了,对于其中的指针却没有非常明确的认识,趁着有机会来好好学习一下,总结一下学过的知识,知识来自C语言指针详解一文 一:指针的概念 指针是一个特殊的变量,里面存储的数值是内存里的一个地址. ...
- C语言指针总结
C语言中的精华是什么,答曰指针,这也是C语言中唯一的难点. C是对底层操作非常方便的语言,而底层操作中用到最多的就是指针,以后从事嵌入式开发的朋友们,指针将陪伴我们终身. 本文将从八个常见的方面来透视 ...
- C语言指针操作
欢迎访问我的新博客:http://www.milkcu.com/blog/ 原文地址:http://www.milkcu.com/blog/archives/pointer-manipulation. ...
- C语言指针的陷阱
C语言指针的陷阱 分类: C/Cpp 转自:http://blog.csdn.net/porscheyin/article/details/3461670 “C语言诡异离奇,陷阱重重,却获得了巨大 ...
- 2-Linux C语言指针与内存-学习笔记
Linux C语言指针与内存 前面我们对于: c语言的基本用法 makeFile文件的使用 main函数的详解 标准输入输出流以及错误流管道 工具与原理 指针与内存都是c语言中的要点与难点 指针 数组 ...
- C语言指针与数组
C语言指针与数组 数组的下标应该从0还是1开始? 我提议的妥协方案是0.5,可惜他们未予认真考虑便一口回绝 -- Stan Kelly-Bootle 1. 数组并非指针 为什么很多人会认为指 ...
- C语言指针学习总结
上学的时候学习C语言,最烦的就是里面指针,可是指针也恰恰是C语言的灵魂. 最近在重温数据结构的内容,因为大多数据结构的教材都是用C语言描述的,而数据结构中也大量的用到了指针的内容,所以我就在这篇笔记中 ...
- 深入理解C语言 - 指针使用的常见错误
在C语言中,指针的重要性不言而喻,但在很多时候指针又被认为是一把双刃剑.一方面,指针是构建数据结构和操作内存的精确而高效的工具.另一方面,它们又很容易误用,从而产生不可预知的软件bug.下面总结一下指 ...
随机推荐
- 【译】x86程序员手册29-第8章 输入输出
Chapter 8 Input/Output 输入/输出 This chapter presents the I/O features of the 80386 from the following ...
- JavaScriptav数据类型和变量
数据类型 计算机顾名思义就是可以做数学计算的机器,因此,计算机程序理所当然地可以处理各种数值.但是,计算机能处理的远不止数值,还可以处理文本.图形.音频.视频.网页等各种各样的数据,不同的数据,需要定 ...
- Masonry基础API
Masonry基础API mas_makeConstraints() 添加约束 mas_remakeConstraints() 移除之前的约束,重新添加新的约束 mas_updateConst ...
- NGS数据格式介绍
一般情况下,从Illumina平台上得到的测序,其数据格式是Fastq格式,可以称之为原始数据(Raw data).事实上直接的下机数据是显微拍摄得到的图像信息.但是一般都会用Bcl2Fastq软件将 ...
- 微信小程序支付全问题解决
这几天在做小程序的支付,没有用官方的SDK,这里就纯用官方的文档搞一发. * 注作者使用的PHP,不过支付流程都是这样 开发前必读 主要流程 小程序前端发送求参请求 接受请求封装 "统一下单 ...
- python3.3+selenium
1.查看C:\Python33\Scripts下已经有了easy_install.exe; 2.从这里下载pip tar.gz,并解压到C盘,https://pypi.python.org/pypi/ ...
- 用Python实现阿里钉钉机器人读取数据库内容自动发群通知
最近想把一些预警数据信息按照一定的要求自动发送到移动端APP,最终把目标放在了腾讯的微信和阿里的钉钉软件上,由于刚开始学习python,于是编程工具想用python来实现.微信使用群体最广,通过一天的 ...
- 洛谷月赛2018.8 T1题解(U28036 Nagisa loves Tomoya)
[题解] 我们设原来的数组为a1,a2,a3..., 那么一次操作之后的数组变为a1+a2,a2+a3,a3+a4..., 两次操作之后数组变为a1+2a2+a3,a2+2a3+a4,a3+2a4+a ...
- Billboard (HDU 2795)
Billboard (HDU 2795) Hdu 2795 注意到每个广告的长度是1,因此可以将每这一张广告牌当成一个数列表示,每个初始值为w.使用线段树维护这个数列,每次查询为找到这个数列第一个大于 ...
- Python基础之生成器、迭代器
一.字符串格式化进阶 Python的字符串格式化有两种方式: 百分号方式.format方式,由于百分号的方式相对来说比较老,在社区里讨论format方式有望取代百分号方式,下面我们分别介绍一下这两种方 ...