指针其实就是一个变量, 和其他类型的变量一样。在32位计算机上, 指针占用四字节的变量。指针与其他变量的不同就在于它的值是一个内存地址,指向内存的另外一个地方, 指针能够直接访问内存和操作底层的数据,可以通过指针直接动态分配与释放内存

#include <stdio.h>

int main(void)
{
int i = 1;
int *p = &i;       //指针p指向了i的地址
*p += 1;          //*p将i的什增1
printf("i = %d\n", i);
return 0;
}

//下面是用typedef定义一个新结构最常用的定义形式,演示了指针的基本使用方式。

/*在声明指针的时候,最好将其初始化为NULL, 否则指针将随机指向某个区域,访问没有初始化的指针,会因为指针未定义而为程序带来预想不到的结果;指针释放后, 也应该将指针指向NULL, 以防止野指针。因为指针所指向的内存虽然释放了,但是指针依然指向某一内存区域。

指针的运算最容易出错。指针支持加减运算。 下面代码中ptmp += 1 运算结束之后, 指针指向的区域不是向前移动了一个字节, 而是向前移动了 sizeof(node)个字节, 也就是说“1” 代表了指针指向的数据结构(node)大小个字节。如果要让指针向前移动一个字节,那么需要先对指针进行类型转换:(char*)ptmp+1。

也就是说, 对于指针p, 指针的加法运算 p = p + n中, p向前移动的位置不是 n 个字节, 而是

n * (sizeof(*p) 个字节,指针的减法运算与此类似。

*/

typedef struct_node
{
int value;
struct_node * next;
}node, *link;

node * pnode = NULL; //声明变量都应该初始化,尤其是指针
pnode = (node *)malloc(sizeof(node)); //内存分配
//务必检测内存分配失败情况, 程序健壮性的考查
//不加这样的判断,如果分配失败,会造成程序访问NULL指针崩溃
if(pnode == NULL)
{
//出错处理,返回资源不足错误信息
}
memset(pnode, 0, sizeof(node)); //新分配的内存应该初始化, 否则内存中含有无用的垃圾信息
pnode->value = 100;
printf("pnode->value = %d\n", pnode->value);
node* ptmp = pnode;
ptmp += 1; //指针支持加减操作,但须格外小心
free(pnode); //使用完内存后, 务必释放,否则会泄漏,一般采取谁分配谁释放原则
pnode = NULL; //释放内存后,需要将指针置NULL, 防止野指针

1、下面总结些指针变量的各种声明形式:主要要明白[],*和()运算符的优先级:()>[]>*, 比如 int * a[10],由于[]的优先级别高于*,所以该表达示首先是一个数组。那么它是什么数组呢?由 int *确定它是个指针数组。又比如 int(*a)[], 由于()高于[], 所以它是一个指针。那么它是什么指针呢?由[]确定它是个数组指针,即指向数组的指针。

1) int *a[10];      //指针数组;

2) int (*a)[10];   //数组指针;

3) int (*a)(int);   //函数指针;

4) int (*a[10])(int);    //函数指针数组。注意用*与[]的优先级来判断这组定义的区别;

5) int *a, **a;     //指针和指向指针的指针;

6) char str[];       //字符串数组;

7) char *str, **str; //字符指针和指向字符串的指针;

2、用sizeof()计算指针长度:主要要明白指针长度(在32位系统中)为4,字符串数组的长度必须包含字符串的结束标志符'\0',数组的长度为元素个数乘以单个元素大小。

char *p1 = "Hello World!";  //p1为字符串指针,所以sizeof(p1) = 4;

char p2[] = "Hello World!"; //p2为字符数组并初始化为"Hello, world"。由于字符串的存储特点,总是以'\0'作为结束标志,因此上面的字符串等价于下面的数组:char p2[] = {'H','e', 'l', 'l','o',',', ','w','o','r','l','d','\0'};必须包含字符串的结束标志符'\0',所以sizeof(p2) = 13。

char p3[] = {'H','e', 'l', 'l','o','W','o','r','l','d'}; //p3为字符数组,并由12个字符初始化,所以sizeof(p3) = 12。

注意:strlen(p)计算的是字符串中有郊的字符数(不含'\0')。所以 strlen(p)的值为12。

如下面字符串拷贝:strlen(str)+1这个要是没有加1来存储字符串结束'\0',则strcpy(strbak,str)将报错。

char * str = "Hello, how are you!";

char * strbak = (char*)malloc(strlen(str)+1);

if(NULL == strbak)

{

//内存分配失败,返回错误

}

strcpy(strbak,str);

有关sizeof用法及总结如下:

(1)参数可以为数据类型或者为一般变量。

如sizeof(int), sizeof(double)等,这种情况要注意的是,不同系统或者不同编译器得到的结果可能是不同的。例如int类型在16位系统中占2个字节,在32位系统中占4个字节。

(2)参数可以为数组或指针。

int a[50];//sizeof(a) = 4*50 = 200; 数组所占的空间大小为200字节。

注意数组作函数参数时,在函数体内计算该数组参数等同于计算指针的长度

int *a = new int[50]; //sizeof(a) = 4; a 为一个指针,sizeof(a)是求指针的大小,在32位系统中,当然是占4 个字节。

(3)参数可以为结构或类。

sizeof应用在类和结构中的处理情况是相同的。有两点需要注意,第一,结构或者类中的静态成员不对结构或者类的大小产生影响,因为静态变量的存储位置与结构或者类的实例地址无关。第二,没有成员变量的结构或类的大小为1,因为必须保证结构或类的每一个实例在内存中都有唯一的地址。

3,常用指针含义:

1) const int *a; //指针常量,指针指向的变量不参改变值

2) int const * a; //指针常量,与const int *a等价

3) int * const a; //常量指针,指针本身不能改变值

4,计算数组的长度:

在计算数组长度的时候,需要注意数组作为函数的参数,将退化为指针,所以, 其长度为指针的长度。

int a[10];        //sizeof(a) = 10 * sizeof(int) = 40;

int a[10];

void func(int a[], int n)

{

print("%d", sizeof(a));        //此时数组退化为指针,所以sizeof(a) = 4;

}

需要指出的是,数组也是指针,但它是常量指针,即 int a[10]中的 a 可以看作是 int * const a。所以一但声明,a不能再被改变。

C/C++入门基础----指针(1)的更多相关文章

  1. C/C++入门基础---指针(2)

    5,数组指针的不同含义 int a[5][10]; printf(%d, %d, %d\n", a, a+1, &a+1);  //1310392,1310432,1310592 a ...

  2. JavaScript入门基础

    JavaScript基本语法 1.运算符 运算符就是完成操作的一系列符号,它有七类: 赋值运算符(=,+=,-=,*=,/=,%=,<<=,>>=,|=,&=).算术运 ...

  3. C++ STL编程轻松入门基础

    C++ STL编程轻松入门基础 1 初识STL:解答一些疑问 1.1 一个最关心的问题:什么是STL 1.2 追根溯源:STL的历史 1.3 千丝万缕的联系 1.4 STL的不同实现版本 2 牛刀小试 ...

  4. C语言入门基础整理

    学习计算机技术,C语言可以说是必备的,他已经成为现在计算机行业人学习必备的,而且应用也是十分的广泛,今天就来看看拥有几年c语言工作经验的大神整理的C语言入门基础知识,没有学不会,只有不肯学. 结构化程 ...

  5. Java入门基础知识点总结(详细篇)

    Java入门基础知识点总结(详细篇)~~~~~目录 1.1 图解 1.1.1 Java基础知识点 1.1.2 Java基础语法的相关内容 1.2 关键字 1.3 标识符 1.3.1 标识符概念 1.3 ...

  6. mybatis入门基础(二)----原始dao的开发和mapper代理开发

    承接上一篇 mybatis入门基础(一) 看过上一篇的朋友,肯定可以看出,里面的MybatisService中存在大量的重复代码,看起来不是很清楚,但第一次那样写,是为了解mybatis的执行步骤,先 ...

  7. 01shell入门基础

    01shell入门基础 为什么学习和使用shell编程 shell是一种脚本语言,脚本语言是相对于编译语言而言的.脚本语言不需要编译,由解释器读取程序并且执行其中的语句,而编译语言需要编译成可执行代码 ...

  8. Markdown入门基础

    // Markdown入门基础 最近准备开始强迫自己写博文,以治疗严重的拖延症,再不治疗就“病入骨髓,司命之所属,无奈何”了啊.正所谓“工欲善其事,必先利其器”,于是乎在写博文前,博主特地研究了下博文 ...

  9. HTML入门基础教程相关知识

    HTML入门基础教程 html是什么,什么是html通俗解答: html是hypertext markup language的缩写,即超文本标记语言.html是用于创建可从一个平台移植到另一平台的超文 ...

随机推荐

  1. Oracle11g的安装方法

    一.win7 64位 只能装64位的服务端 装 32位的客户端 最后装PLSQL二.PLSQL 数据库没有值:(1)配置 C:\oracl\product\11.2.0\client_1\Networ ...

  2. c# 获取某日期所在周的第一天和最后一天

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace WyfC ...

  3. Eclipse+MinGW+Boost环境搭建

    一.编译 运行 .bat 生成bjam.exe 运行:bjam --build-type=complete toolset=gcc stage 二.配置 配置eclipse -L Path加入链接库位 ...

  4. webpack使用笔记

    webpack简介 CommonJS和AMD是用于JavaScript模块管理的两大规范,前者定义的是模块的同步加载,主要用于NodeJS:而后者则是异步加载,通过requirejs等适用于前端.np ...

  5. PVANET----Deep but Lightweight Neural Networks for Real-time Object Detection论文记录

    arxiv上放出的物体检测的文章,在Pascal voc数据集上排第二.源码也已放出(https://github.com/sanghoon/pva-faster-rcnn),又可以慢慢把玩了.这篇文 ...

  6. 一个解决adb5037端口被绑定问题的小程序-以管理员身份运行

    @echo start adb... @rem 获取绑定的进程id输出到一个临时文件 @call netstat -ano |findstr " |findstr "LISTENI ...

  7. 快速卸载VS2015的办法

    1.以管理员身份运行CMD: 2.在CMD里输入F:\>vs_enterprise.exe /uninstall /force

  8. asp.net 新项目遇到的坑

    1.新拿来的项目,能正常跑,但是想熟悉,运用断点调试,f11却发现出了这个问题 此提示:应该是缺失dll文件  2.于是重新生成项目出现,发现Log4Net,有文件,但是出现这个提示 思考:一版本不对 ...

  9. androidstudio 配置git和github

    git是版本控制工具 github是一个网站,git可以把项目上传至这个网站 1:先下载git,并且安装,一般默认即可,安装成功可以点击电脑右键出现 2:生成id_rsa.pub, 配置账号和邮箱 点 ...

  10. 解决phalcon读取mysql乱码

    原先的项目用的是phalcon,迁移到新服务器上面后中文字符变为'?',即便连接参数设置了charset => 'utf8'也无效,一开始怀疑是版本问题,后来直接拷过去完全一样的库也没用:最后还 ...