C++之指针与数组区别
C++/C程序中,数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。数组名对应着(而不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变。指针可以随时指向任意类型的内存块,它的特征是“可变”,所以我们常用指针来操作动态内存。指针远比数组灵活,但也更危险。
下面以字符串为例比较指针与数组的特性。
一、修改内容
char a[] = “hello”; //“hello”位于常量存储区,a在全局(静态)初始化区
a[] = ‘X’;
cout << a << endl;
char *p = “world”; // 注意p指向常量字符串 p位于全局(静态)初始化区
p[] = ‘X’; // 编译器不能发现该错误 常量字符串的内容是不能被修改的
cout << p << endl;
二、内容复制与比较
// 数组…
char a[] = "hello"; //a在全局(静态)初始化存储区 “hello”在常量存储区
char b[]; //b在全局(静态)未初始化存储区
strcpy(b, a); // 不能用 b = a;
if(strcmp(b, a) == ) // 不能用 if (b == a)
…
// 指针…
int len = strlen(a);
char *p = (char *)malloc(sizeof(char)*(len+)); //一定要给p申请一个容量一块内存
strcpy(p,a); // 不要用 p = a; //赋值
if(strcmp(p, a) == ) // 不要用 if (p == a) //如果是后者则比较的是地址
…
不能对数组名进行直接复制与比较。若想把数组a的内容复制给数组b,不能用语句 b = a
,否则将产生编译错误。应该用标准库函数strcpy
进行复制。同理,比较b和a的内容是否相同,不能用if(b==a)
来判断,应该用标准库函数strcmp
进行比较。
语句 p = a
并不能把a的内容复制指针p,而是把a的地址赋给了p。要想复制a的内容,可以先用库函数malloc
为p申请一块容量为strlen(a)+1
个字符的内存,再用strcpy
进行字符串复制。同理,语句if(p==a)
比较的不是内容而是地址,应该用库函数strcmp
来比较。
三、计算内存容量
用运算符sizeof
可以计算出数组的容量(字节数)。如下示例中,sizeof(a)
的值是12(注意别忘了’’)。指针p指向a,但是sizeof(p)
的值却是4。这是因为sizeof(p)
得到的是一个指针变量的字节数,相当于sizeof(char*)
,而不是p所指的内存容量。C++/C语言没有办法知道指针所指的内存容量,除非在申请内存时记住它。
char a[] = "hello world";
char *p = a;
cout<< sizeof(a) << endl; // 12字节
cout<< sizeof(p) << endl; // 4字节
注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。如下示例中,不论数组a的容量是多少,sizeof(a)
始终等于sizeof(char *)
。
void Func(char a[]){
cout<< sizeof(a) << endl; // 4字节而不是100字节
}
四、指针参数是如何传递的
如果函数的参数是一个指针,不要指望用该指针去申请动态内存。如下示例中,Test函数的语句GetMemory(str, 200)
并没有使str
获得期望的内存,str
依旧是NULL
,为什么?
void GetMemory(char *p, int num){
p = (char *)malloc(sizeof(char) * num); //首先会在栈中分配一个p_作为p的临时副本,p_是指向p的,当p = (char*)malloc(size(char)*num)时,实际是修改了p_所指向的内存,
//即现在p_指向由malloc在堆上新分配的内存。但是p丝毫未变。所以函数GetMemory并不输出任何东西,并且每执行一次GetMemory就会泄露一块内存,因为并没有free掉
//p_在堆上开辟的内存
}
void Test(void){
char *str = NULL;
GetMemory(str, ); // str 仍然为 NULL
strcpy(str, "hello"); // 运行错误
}
如果非得要用指针参数去申请内存,那么应该改用“指向指针的指针”,见示例:
void GetMemory2(char **p, int num){
*p = (char *)malloc(sizeof(char) * num); //当传入的是指向指针的指针时,即有一个内存区域,存储了一个值,这个值是个指针,它又指向了另一块内存区域。这是给p在堆上分配一个新的内存
}
void Test2(void){
char *str = NULL;
GetMemory2(&str, ); // 注意参数是 &str,而不是str str是个存放在栈上的指针,&str就是在栈上又分配一个指针,这个指针指向str。
strcpy(str, "hello");
cout<< str << endl; free(str);
}
C++之指针与数组区别的更多相关文章
- GDB调试字符数组时指针和数组区别的体现
测试ftell函数时发现报错,先贴源码 // File Name: ftell.c #include <stdio.h> #include <stdlib.h> int mai ...
- 指针与数组的区别 —— 《C语言深度剖析》读书心得
原书很多已经写的很清楚很精炼了,我也无谓做无意义的搬运,仅把一些基础和一些我自己以前容易搞混的地方写一下. 1. 意义: 指针: 指针也是一种类型,长度为4字节,其存放的内容只能是一个地址(4字节). ...
- 指针 与 数组 以及 a 与 &a的区别
指针 与数组 并没有什么关系, 指针就是指针,指针变量在32位系统下,永远占4个byte,其值为某一个内存的地址,指针可以指向任何地方,但是不是任何地方你都能通过这个指针变量访问到; 数组 ...
- c指针与数组,传参问题,指针数组与数组指针的区别,二维数组动态内存分配
一 数组的结构:顺序存储,看谭浩强中的图,牢记 1.数组名指代一种数据结构:数组 现在可以解释为什么第1个程序第6行的输出为10的问题,根据结论1,数组名str的内涵为一种数据结构,即一个长度为10的 ...
- C语言中指针和数组的区别
看<C专家编程>一书,看到数组与指针并不相同一章,遂做了一段测试: 代码: #include <stdio.h> #include <stdlib.h> int m ...
- C++指针和数组的区别(不能混用的情况)
通常情况下,C++中指针和数组是可以混用的,但是,在编写字符数组的全排列的时候,混用却出了问题,因此,今天特地mark一下,以备日后查找 这里整理的,不包括用new开辟的动态数组 1.数组一旦声明,我 ...
- 深入理解C语言中的指针与数组之指针篇
转载于http://blog.csdn.net/hinyunsin/article/details/6662851 前言 其实很早就想要写一篇关于指针和数组的文章,毕竟可以认为这是C语言的根本 ...
- 转: 浅谈C/C++中的指针和数组(二)
转自:http://www.cnblogs.com/dolphin0520/archive/2011/11/09/2242419.html 浅谈C/C++中的指针和数组(二) 前面已经讨论了指针和数组 ...
- 转:浅谈C/C++中的指针和数组(一)
再次读的时候实践了一下代码,结果和原文不一致 error C2372: 'p' : redefinition; different types of indirection 不同类型的间接寻址 /// ...
随机推荐
- 使用SpringMVC<mvc:view-controller/>标签时踩的一个坑
<mvc:view-controller>标签 如果我们有些请求只是想跳转页面,不需要来后台处理什么逻辑,我们无法在Action中写一个空方法来跳转,直接在中配置一个如下的视图跳转控制器即 ...
- 洛谷 P2652 同花顺(离散化)
洛谷 P2652 同花顺(题面) 手动模拟了一下,其实离散化排序可以起很大作用题目要求花色相同,数字连续,那么我们要做的就是找一种花色,并提取出其中一串数字留下那些舍弃的牌换成相应花色,并和之前留下的 ...
- 微信小程序开发简易计算器改进版
微信小程序开发计算器有多种方法,但是大部分代码比较复杂.不容易理解.本案例进行了改进,主要是组件bindtap属性绑定的自定义函数clickBtn(),采用了switch语句,使得代码结构更加清晰,学 ...
- JavaScript中的面向对象编程,详解原型对象及prototype,constructor,proto,内含面向对象编程详细案例(烟花案例)
面向对象编程: 面向:以什么为主,基于什么模式 对象:由键值对组成,可以用来描述事物,存储数据的一种数据格式 编程:使用代码解决需求 面向过程编程: 按照我们分析好的步骤,按步 ...
- ASP.NET 中 ContentType 类型
在ASP.NET中使用Response.ContentType="类型名";来确定输出格式 不同的ContentType 会影响客户端所看到的效果.默认的ContentType为 ...
- troff - groff 文档排版系统的 troff 处理器
总览 SYNOPSIS troff [ -abcivzCERU ] [ -d cs ] [ -f fam ] [ -F dir ] [ -m name ] [ -M dir ] [ -n num ] ...
- debian 下设置Ctrl+Alt+T快捷键打开终端
在设置->键盘->快捷键->自定义快捷键->添加 名称:Terminal 命令:gnome-terminal 再右上边点击后 按Ctrl +Alt +T
- 建站租用RAKsmart服务器的优势
RAKsmart算是近年来受国内用户关注度颇高的美国服务器提供商.位于美国西海岸加州地区的RAKsmart机房,拥有超过十年的机房管理经验,提供了快速.稳定的服务器租用服务.那么RAKsmart服务器 ...
- CSIC_716_20191203【 socket网络编程,以及沾包问题的高级解决方式】
AF_UNIX(本机通信) AF_INET(TCP/IP – IPv4) AF_INET6(TCP/IP – IPv6) SOCK_STREAM(TCP流) SOCK_DGRAM(UDP数据报) 远程 ...
- cin,cout优化
https://www.cnblogs.com/PrayG/p/5749832.html ios_base::sync_with_stdio(0); cin.tie(0); 涨知识了