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是用于创建可从一个平台移植到另一平台的超文 ...
随机推荐
- HDU2048
http://acm.hdu.edu.cn/showproblem.php?pid=2048 这道题是错位排序的思想 我们先来考虑第n个数,假设把他放在第k的位置,有n-1种放的方法,那么对于第k位置 ...
- java.lang.NoClassDefFoundError: org/apache/ibatis/session/SqlSession
在配置一个springmvc+mybatis的项目时,总是有报一个错误: org.springframework.beans.factory.BeanCreationException: Error ...
- Android test---JUnit
JUnit 单元测试 Android的单元测试基础也是比较简单,同样还是测试相加方法是否正确,测试用例还是用1+1?=2来个简单的Android单元测试: 1..打开eclipse,新建一个proje ...
- 利用nodejs的cheerio抓取网站数据
/*引入模块*/ var http = require('http') var url = 'http://www.cnblogs.com/txxt' var cheerio = require('c ...
- HEX文件格式和其校验算法
这次我将在原来的基础上(http://www.cnblogs.com/libra13179/p/5787084.html)继续讲解HEX文件的格式 打开app_valid_setting_apply. ...
- 线程操作UI界面的方法
以前一般都是用BeginInvoke来刷新UI界面,现在采用 SynchronizationContext 来刷新,写起来清楚多了. SynchronizationContext synchroniz ...
- MarkDown初体验
初体验 写在前面 一周前第一次听说了MarkDown这个编辑器,通过它知道了LaTex,正好满足了我多年对网上博客里的公式简陋的表达的需求.起初,只是用到了LaTex公式这一个功能 , 对于主要文字的 ...
- Bloom Filter学习
参考文献: Bloom Filters - the math http://pages.cs.wisc.edu/~cao/papers/summary-cache/node8.html B ...
- Unity5 AssetBundle 打包以及加载
using UnityEngine; using System.Collections; using System.Collections.Generic; using UnityEditor; us ...
- 使用FreePic2Pdf导出书签至Word建立层级目录——快速初始化Word笔记本目录
使用FreePic2Pdf导出书签至Word建立层级目录 --快速初始化Word笔记本目录 文:安徽师范大学2014级计算机科学与技术 王昊 (Get Contact:441301158@qq.com ...