C/C++入门基础----指针(1)
指针其实就是一个变量, 和其他类型的变量一样。在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)的更多相关文章
- C/C++入门基础---指针(2)
5,数组指针的不同含义 int a[5][10]; printf(%d, %d, %d\n", a, a+1, &a+1); //1310392,1310432,1310592 a ...
- JavaScript入门基础
JavaScript基本语法 1.运算符 运算符就是完成操作的一系列符号,它有七类: 赋值运算符(=,+=,-=,*=,/=,%=,<<=,>>=,|=,&=).算术运 ...
- C++ STL编程轻松入门基础
C++ STL编程轻松入门基础 1 初识STL:解答一些疑问 1.1 一个最关心的问题:什么是STL 1.2 追根溯源:STL的历史 1.3 千丝万缕的联系 1.4 STL的不同实现版本 2 牛刀小试 ...
- C语言入门基础整理
学习计算机技术,C语言可以说是必备的,他已经成为现在计算机行业人学习必备的,而且应用也是十分的广泛,今天就来看看拥有几年c语言工作经验的大神整理的C语言入门基础知识,没有学不会,只有不肯学. 结构化程 ...
- Java入门基础知识点总结(详细篇)
Java入门基础知识点总结(详细篇)~~~~~目录 1.1 图解 1.1.1 Java基础知识点 1.1.2 Java基础语法的相关内容 1.2 关键字 1.3 标识符 1.3.1 标识符概念 1.3 ...
- mybatis入门基础(二)----原始dao的开发和mapper代理开发
承接上一篇 mybatis入门基础(一) 看过上一篇的朋友,肯定可以看出,里面的MybatisService中存在大量的重复代码,看起来不是很清楚,但第一次那样写,是为了解mybatis的执行步骤,先 ...
- 01shell入门基础
01shell入门基础 为什么学习和使用shell编程 shell是一种脚本语言,脚本语言是相对于编译语言而言的.脚本语言不需要编译,由解释器读取程序并且执行其中的语句,而编译语言需要编译成可执行代码 ...
- Markdown入门基础
// Markdown入门基础 最近准备开始强迫自己写博文,以治疗严重的拖延症,再不治疗就“病入骨髓,司命之所属,无奈何”了啊.正所谓“工欲善其事,必先利其器”,于是乎在写博文前,博主特地研究了下博文 ...
- HTML入门基础教程相关知识
HTML入门基础教程 html是什么,什么是html通俗解答: html是hypertext markup language的缩写,即超文本标记语言.html是用于创建可从一个平台移植到另一平台的超文 ...
随机推荐
- mysql load data 乱码的问题
新学mysql在用load data导入txt文档时发现导入的内容,select 之后是乱码,先后把表,数据库的字符集类型修改为utf8,但还是一样,最后在 http://bbs.chinaunix. ...
- tiny中文乱码问题,不过仅适用于windows,所以xml不可以出现中文
我是在SetAttribute() 函数之前使用的 SetAttribute(const char* name,const char * _value) 首先得到了一个CString 类型的变量 st ...
- Have Fun with Numbers及循环链表(约瑟夫问题)
1. 循环链表(约瑟夫问题) https://github.com/BodhiXing/Data_Structure 2. Have Fun with Numbers https://pta.pate ...
- oracle计算是否是同一周
函数已经解决跨年问题 select to_char(date'2016-12-31','iW') from dual; select to_char(date'2017-01-01','iW') fr ...
- EX的魔方
https://www.luogu.org/problem/show?pid=2007 题目背景 常神牛从来没接触过魔方,所以他要借助计算机来玩.即使是这样,他还是很菜. 题目描述 常神牛家的魔方都是 ...
- [转载:]C#与Fortran混合编程之本地调用Fortran动态链接库
前言 C#发展到现在,已是一门相当完善的语言,他基于C语言风格,演化于C++.并依靠强大的.NET底层框架.C#可以用来快速构建桌面及Web应用.然而在我们的实际工作中,尽管C#已经非常完善,但还是不 ...
- 【Python】pip国内安装源
豆瓣安装源 pip install packages -i http://pypi.doubanio.com/simple --upgrade --trusted-host pypi.doubanio ...
- Sublime Text 3 使用
Sublime Text3使用 下载安装 参考:http://www.downza.cn/soft/187996.html Sublime Text Build 3126 x64 Setup.exe下 ...
- c++程序设计之编程思想
代码块愈小,代码的功能就愈容易管理,代码的处理和移动就愈轻松. 任何一个傻瓜都能写出计算机可以理解的代码,唯有写出人类容易理解的代码,才是优秀的程序员. 绝大多数情况下,函数应该放在它所使用的数据的所 ...
- vs2013单元测试练习过程
1.打开VS2013 --> 新建一个项目.这里我们默认创建一个控制台项目.取名为UnitTestDemo 2.在解决方案里面新增一个单元测试项目.取名为UnitTestDemoTest 创建完 ...