指针的一些问题

1、c++/c语言中不少地方,数组和指针可以相互替换使用,容易让人产生一种错觉,指针和数组是等价的。

数组要么在静态存储区域创建,如全局数组;要么在栈上创建如函数内的数组。数组的名称对应着(而不是指向)一块内存,它的地址和容量在其生命周期内保持不变,数组的内容可变。

指针可以指向任意类型的内存块,它的特征是可变的,所以常常用指针来操作动态内存,指针比数组灵活,当时容易出错。

char a[] = "hello";
a[0] = 'x';
cout<<a<<endl;
char *p = "world";  //这里的p指向的是常量字符串
p[0] = 'x';  //编译器不能发现该错误
cout<<p;

如上边一段代码,a是容量为6的字符数组,a中的内容是可以改变的,如a[0]='x'。指针p指向的是一个常量字符串“world”(位于静态存储区),常量字符串的内容是不能够被修改的。但是从语法的角度看,编译器并不知道p[0]='x'有什么问题,但是该语句在企图执行时,就会出错。

char a[] = "hello";
char *p = "world"; 
cout<<sizeof(a)<<endl;             //6
cout<<sizeof(p)<<endl;             //4
cout<<sizeof(char *)<<endl;     // 4
cout<<sizeof(void *)<<endl;      //4
cout<<sizeof(int *)<<endl;        //4  
cout<<sizeof(short *)<<endl;    //4

 

另外指针和数组的容量计算也是有区别的。以上一段代码为例,sizeof(a)的值为6,但是sizeof(p)的值为4,这是因为sizeof(a)可以计算出数组的字节数,但是sizeof(p)得到的是一个指针变量的字节数,相当于sizeof(char *),而不是p所指向的内存容量。c++、c语言是没有办法知道指针所指向的内存容量,除非在申请内存时记住。

 

void test(char p[100])
{cout<<sizeof(p)<<endl;//4
}

 

注意:当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。如上边的代码,sizeof(p)的大小为4。

2、指针参数传递内存

void GetMemory(char *p)
{p = (char *)malloc(100);
}int main()
{char *str = NULL;GetMemory(str);strcpy(str,"hello");printf("%s",str);   //运行出错free(str);
}

这段代码运行出错,原因出自函数Getmemory中。编译器总是要为函数的每个参数制作临时副本,指针参数p的副本是_p,编译器使_p=p。如果函数体内的程序修改了_p的内容,就导致了参数p的内容作相应的修改。这就是指针可以用作输出参数的原因。但是在本例中,_p申请了新的内存,只是把_p所指向的内存地址改变了,但是p丝毫未变。所以函数GetMemory并不能输出任何东西,每次执行一次GetMemory就会泄露一块内存。因为没有执行free释放内存。

void GetMemory2(char **p,int num)
{*p = (char *)malloc(num);
}

如果一定要使用指针参数去申请内存,那么可以使用指向指针的指针,如上边的代码。当然也可以使用函数返回值来传递动态内存,如:

char *GetMemory3(int num)
{char *p = (char *)malloc(num);return p;  
}

但是值得注意的是,我们这里使用返回值返回的是动态分配的堆内存,不是栈内存,如果不小心返回的是栈内存,就会出错,因为在函数结束时,栈内存自动消亡了。

char *GetMemory4()
{char p[] ="hello world!"return p;   //编译器会发出警告  
}

对上边的程序稍作修改

char *GetMemory5()
{char *p ="hello world!"return p;   
}

这时候p指向的是字符串常量,位于静态存储区,生命周期恒定不变,那么此时返回的是一个只读的内存块。

 

3、结构体的存储分配

struct Align1
{int a;char b;char c;
};
struct Align2
{char b;int a;char c;
};

如上边所示两个结构体的数据元素一样,但是位置顺序不同,那么他们占用的内存大小不同。在32位机器中整型4个字节,并且他的起始存储位置必须能够被4整除。所以以上两个结构体在内存中分配如图所示

编译器按照成员列表的顺序一个接着一个的给每个成员分配内存。只有当成员之间满足正确的对齐要求时,成员之间才会出现用于填充的额外内存空间。有些时候,我们有充分的理由决定不对数据结构成员进行重排,减少因边界对齐带来的空间损失。例如,我们可能想把相关的结构成员存储到一起,提高程序的可维护性和可读性。但是,如果不存在这样的理由,结构成员应该根据他们的边界进行重排,减少因为边界对齐而造成的内存损失。当程序创建几百个甚至上千个结构时,减少内存浪费的要求就比程序的可读性更为紧迫了。在这种情况下,在声明中增加注释可以弥补可读性方面的损失。

运行结果:

 

 

 

转载于:https://www.cnblogs.com/newpanderking/p/3825417.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/432473.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

tankwar的java坦克子弹撞墙_tankwar

tankwar 是使用java开发的一个单机版的小游戏 (未使用任何游戏引擎).和90经典版的坦克大战有些不同, 这里是纯坦克之间的战争, 英雄坦克并不用保护它的家.特色:1. 游戏共设6个关卡. (支持无限关卡)关卡设置中包括敌人坦克数量, 移动速度, 子弹速度, 以及子弹的杀伤力, 炸弹数量…

【翻译】使用Ext JS设计响应式应用程序

原文&#xff1a;Designing Responsive Applications with Ext JS在当今这个时代&#xff0c;用户都希望Web应用程序无论在形状还是大小上&#xff0c;既能在桌面电脑&#xff0c;也能在移动设备上使用。使应用程序能适应不同的需求渐成趋势。幸运的是&#xff0c;Ext JS 5提供…

java各种的不好_译文《最常见的10种Java异常问题》

封面&#xff1a;洛小汐译者&#xff1a;潘潘知彼知己&#xff0c;方能百战不殆。前言本文总结了有关Java异常的十大常见问题。目录检查型异常(checked) vs. 非检查型异常(Unchecked)异常管理的最佳实践箴言为什么在try代码块中声明的变量不能在catch或者finally中被引用&#…

Hadoop 开源调度系统zeus(二)

紧跟之前Hadoop 开源调度系统zeus(一) 本节主要介绍一下zeus的架构&#xff1a; 先给一个zeus的架构图 无论Master还是Worker都有一套WEB UI&#xff0c;无论从哪个上面去看&#xff0c;看到的结果都是一样的&#xff0c;实际上一般仅仅看主 Master&#xff1a;调度内核&#x…

python十条建议_十条建议帮你提高Python编程效率

程序员的时间很宝贵&#xff0c;Python这门语言虽然足够简单、优雅&#xff0c;但并不是说你使用Python编程&#xff0c;效率就一定会高。要想节省时间、提高效率&#xff0c;还是需要注意很多地方的。今天就与大家分享资深Python程序员总结的10点建议&#xff0c;帮助大家大幅…

Django:快速搭建简单的Blog

一&#xff0c;创建项目 1, 为blog创建名为mysite的工程项目&#xff1a; django-admin.py startproject mysite2, 项目结构如下&#xff1a; mysite├── manage.py└── mysite├── __init__.py├── settings.py├── urls.py└── wsgi.pymanage.py ----- Django项目…

java se好用吗_利用 Java SE 7 更好地管理资源

2011 年 5 月发布作者&#xff1a;Julien Ponge本文介绍 Java 7 针对自动资源管理问题给出的解决办法&#xff0c;即 Coin 项目中提出的新语言结构 try-with-resources 语句。&#xff1a;示例源文件 (zip) 简介典型的 Java 应用程序可以处理多种类型的资源&#xff0c;如文件、…

法线贴图Nomal mapping 原理

法线贴图多用在CG动画的渲染以及游戏画面的制作上&#xff0c;将具有高细节的模型通过映射烘焙出法线贴图&#xff0c;贴在低端模型的法线贴图通道上&#xff0c;使之拥有法线贴图的渲染效果&#xff0c;却可以大大降低渲染时需要的面数和计算内容&#xff0c;从而达到优化动画…

Javascript引擎单线程机制及setTimeout执行原理说明

setTimeout用法在实际项目中还是会时常遇到。比如浏览器会聪明的等到一个函数堆栈结束后才改变DOM&#xff0c;如果再这个函数堆栈中把页面背景先从白色设为红色&#xff0c;再设回白色&#xff0c;那么浏览器会认为DOM没有发生任何改变而忽略这两句话&#xff0c;因此我们可以…

解决VS命令提示符 “Setting environment for using Microsoft Visual Studio. 此时不应有“系列错误

一、起因 最近在玩Boost库。当然首先是要进行Boost库的安装和配置。于是浅墨Google了一下boost库的安装配置攻略&#xff0c;下载了最新版1.55的boost库&#xff0c;就愉悦地开始进行配置了。 当进行到第五步&#xff0c;要在VS命令提示符中运行bootstrap.bat的时候&#xff0c…

yii2多语言设置

yii2的多语言切换功能 1.页面添加语言切换按钮&#xff0c;如下图&#xff1a; 代码如下&#xff1a; <ul> <li> <a href"javascript:;" οnclick"changeLanguage(en_US);"> <span><?php echo …

APP安全环节缺失,手游运营商怎样应对APP破解困境

2013年手游行业的规模与收入均实现了大幅增长&#xff0c;发展势头强劲。然而&#xff0c;在手游快速发展的同一时候&#xff0c;因为监管、审核等方面存在着漏洞&#xff0c;手机游戏软件被破解后注入恶意代码、盗取用户財产、窃取用户设备信息的现象屡见不鲜。手游被破解后黑…

linux php cpu,获取Linux服务器性能CPU、内存、硬盘等使用率 PHP

数据库配置文件&#xff1a; conn.phpdefine("MONITORED_IP", "172.16.0.191"); //被监控的服务器IP地址 也就是本机地址define("DB_SERVER", "172.16.7.2"); //存放数据的服务器IP地址define("DB_USER", "roo…

信息论与编码matlab实验报告,信息论与编码实验程序与结果图(matlab).doc

信息论与编码实验程序与结果图(matlab).doc 1信源熵实验程序&#xff1a;clc;closeall;clear;linwidd1fontt20p00;pd1;N20plinspace(p0,pd,N);I-log2(p);plot(p,I, k );title( I-log2(p)函数图 );xlabel( p );ylabel( I );clc;closeall;clear;linwidd1fontt20p00;pd1;N20plinsp…

OpenGL: 实现立体显示

立体显示原理&#xff1a;设没有立体显示的模型视图矩阵ModelView为Mv,投影矩阵为Mp&#xff0c;则、物体空间的任何一点为P&#xff0c;则变换到屏幕坐标P*MpMvP&#xff1b;注意前面已经说过opengl里面坐标列优先&#xff0c;所以矩阵都是右乘。 左眼和右眼的变换都是由中间的…

数学 之 hdu 4861

// [7/23/2014 Sjm] /* 对于此题&#xff0c;举出数据找规律&#xff0c;即可AC。。。 不过悲催的WA了好多次&#xff0c;后来发现竟把"YES"打印成"Yes"了。。。。 注释掉的代码是用来找规律的。。。 */ 1 #include <iostream>2 #include <cs…

centos 6 安装mysql,CentOS6.5安装MySQL教程(完整教程)

Step 1&#xff1a;检测系统是否安装MYSQL# yum list installed | grep mysql顺便提下如果yum有如下提示不能用的情况&#xff1a;yum在自动更新原因是yum在自动更新 只要关掉它就OK了解决方案&#xff1a;直接输入# rm -f /var/run/yum.pid或者&#xff1a;# /etc/init.d/y…

php通过条件来定义const,php用const出错是什么原因

大家都知道define是定义常量的,如果在类中定义常量呢&#xff1f;当然不能用define&#xff0c;而用const&#xff0c;如下例&#xff1a;<?php //在类外面通常这样定义常量define("PHP","phpernote.com");class MyClass{ //常量的值将始终保持不变。在…