在使用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)的更多相关文章

  1. 关于C语言指针的一些新认识(1)

    Technorati 标签: 指针,数组,汇编,C语言 前言 指针是C语言的精华,但我对它一直有种敬而远之的感觉,因为一个不小心就可能让你的程序陷入莫名其妙的麻烦之中.所以,在处理字符串时,我总是能用 ...

  2. C语言指针学习

    C语言学过好久了,对于其中的指针却没有非常明确的认识,趁着有机会来好好学习一下,总结一下学过的知识,知识来自C语言指针详解一文 一:指针的概念 指针是一个特殊的变量,里面存储的数值是内存里的一个地址. ...

  3. C语言指针总结

    C语言中的精华是什么,答曰指针,这也是C语言中唯一的难点. C是对底层操作非常方便的语言,而底层操作中用到最多的就是指针,以后从事嵌入式开发的朋友们,指针将陪伴我们终身. 本文将从八个常见的方面来透视 ...

  4. C语言指针操作

    欢迎访问我的新博客:http://www.milkcu.com/blog/ 原文地址:http://www.milkcu.com/blog/archives/pointer-manipulation. ...

  5. C语言指针的陷阱

    C语言指针的陷阱   分类: C/Cpp 转自:http://blog.csdn.net/porscheyin/article/details/3461670 “C语言诡异离奇,陷阱重重,却获得了巨大 ...

  6. 2-Linux C语言指针与内存-学习笔记

    Linux C语言指针与内存 前面我们对于: c语言的基本用法 makeFile文件的使用 main函数的详解 标准输入输出流以及错误流管道 工具与原理 指针与内存都是c语言中的要点与难点 指针 数组 ...

  7. C语言指针与数组

    C语言指针与数组 数组的下标应该从0还是1开始? 我提议的妥协方案是0.5,可惜他们未予认真考虑便一口回绝    -- Stan Kelly-Bootle   1. 数组并非指针 为什么很多人会认为指 ...

  8. C语言指针学习总结

    上学的时候学习C语言,最烦的就是里面指针,可是指针也恰恰是C语言的灵魂. 最近在重温数据结构的内容,因为大多数据结构的教材都是用C语言描述的,而数据结构中也大量的用到了指针的内容,所以我就在这篇笔记中 ...

  9. 深入理解C语言 - 指针使用的常见错误

    在C语言中,指针的重要性不言而喻,但在很多时候指针又被认为是一把双刃剑.一方面,指针是构建数据结构和操作内存的精确而高效的工具.另一方面,它们又很容易误用,从而产生不可预知的软件bug.下面总结一下指 ...

随机推荐

  1. Git——github基本操作

    基本概念 上一篇文章写到git共享仓库,但是有个局限性,就是这个仓库存在于本地,其他人无法从我们这个仓库拿到共享的内容 但是我们可以将这个共享仓库放入一个远程的服务器上,然后设置一些登录权限就能完美的 ...

  2. MyBatis 之一 简介

    什么是 MyBatis ? MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis ...

  3. Win7 下 PB (PowerBuilder) Insert Control 崩溃的解决办法

    环境: WIN7 x86  PB8.0, x64系统目录不同,不过也可以试试 Insert -> OLE... -> Insert Control  - 崩溃 如果网上提供的办法解决不了你 ...

  4. js延时加载的方法

    js的延迟加载有助与提高页面的加载速度,以下是延迟加载的几种方法: 1.使用setTimeout延迟方法的加载时间 延迟加载js代码,给网页加载留出更多时间 <script type=" ...

  5. 安全,轻松的Axios与Nuxt.js集成

    modules: [ // Doc: https://github.com/nuxt-community/axios-module#usage '@nuxtjs/axios' ], /* ** Axi ...

  6. CLISTCTRL2

    回顾: 刚刚写完,因为是分期写的,所以最初想好好做一下的文章格式半途而废了~说的也许会有点啰嗦,但是所有的基础用到的技术细节应该都用到了. 如果还有什么疑问,请回复留言,我会尽力解答. 如果有错误,请 ...

  7. JSON字符串的生成

    public class Corporation { public string remark { get; set; } public string version { get; set; } pu ...

  8. [转载] kprobe原理解析(一)

    From: https://www.cnblogs.com/honpey/p/4575928.html kprobe原理解析(一) kprobe是linux内核的一个重要特性,是一个轻量级的内核调试工 ...

  9. idea安装及使用

    使用:https://blog.csdn.net/qq_42303709/article/details/81983208 安装教程:https://blog.csdn.net/yl171272518 ...

  10. 【最短路】Dijkstra+ 链式前向星+ 堆优化(优先队列)

    Dijkstra+ 链式前向星+ 优先队列   Dijkstra算法 Dijkstra最短路算法,个人理解其本质就是一种广度优先搜索.先将所有点的最短距离Dis[ ]都刷新成∞(涂成黑色),然后从起点 ...