指针和引用

引用:

引用是某个对象(即变量)的别名。

形式如下:

类型 &引用名 = 变量名;

注意:

1.在定义引用时,引用符&在类型与引用名之间的位置是灵活的。

int& ir = i;

int & ir = i;

int &ir = i;

以上几种定义完全相同。

2.在变量声明时出现的&才是引用运算符,其他地方出现的&都是地址操作符。

int& fun( int &i1, int &i2);    //引用参数,函数返回引用。

3.引用代表一个变量的别名,必须在定义时初始化,不能在定义完成后再给它赋值。

float f;

float &fr;

fr = f;

以上语句是错误的。

可为一个变量指定多个引用。为引用提供初始值的,可以是一个变量,也可以是另一个引用名。

4.一个引用名只能是一个变量的别名,不能再次将它指定为其他变量的别名。

5.引用实际是一种隐式指针,但它与指针的用法存在区别。

6.当用&运算符获取一个引用的地址时,实际取出的是引用对应的变量的地址。

int i = 9;

int &ir = i;

int *pi = &ir;

pi实际指向的是i。

7.建立引用时有一些限制

不能建立引用的引用;不能建立引用数组;不能建立数组的引用;可以建立指针的引用,但不能创建指向引用的指针。

int a[10];

int &aa = a;                    //错误,不能建立数组的引用。

int &ia[5];                            //错误,不能建立引用数组。

 

指针:

指针功能最强但又最危险。

指针变量的定义语句:

数据类型 * 变量名;

int * iPtr;

int iCount = 28;

iPtr = &iCount;

(*iPtr的类型是整型,指针iPtr指向该整数,所以iPtr的类型是整型指针,而iPtr的地址(即&iPtr)的类型是整型指针的地址,即指向整型指针的指针。三者都不相同。)

(在32位机器中,整数和指针都占4个字节。但指针和整数表示的是不同的类型。)

指针的初始化:

指针在使用前要进行初始化。指针忘了赋值比整型变量忘了赋值危险得多

 

指针类型与实际存储的匹配:

指针是有类型的,给指针赋值,不但必须是一个地址,而且应该是一个该指针类型相符的变量或常量的地址。

int i=0;

int * iPtr = &i;      // *iPtr的内容是起始点为i的地址的一个整型数。

指针具有一定类型,它是值为地址的变量,该地址是内存中另一个该类型变量的存储位置。

指针运算:

数组名本身,没有方括号和下标,它实际上是地址。表示数组的起始地址。 

int iArray[10];

int * iPtr = iArray;                //用数组名对指针初始化。

或   iPtr = &iArray[0];                  //同样表示数组的第一个元素的地址。

由于指针是具有某个数据类型的地址,所以指针运算都是以数据类型为单位展开的。即 iPtr是个整型指针,iPtr++使指针指向下一个整数。若在32位系统中,iPtr的地址值实际是增加4,因为在32位系统中int型占4个字节。

只有加法和减法可用于指针运算。

sum += *iPtr;

iPtr++;

以上两条语句可压缩为以下一条语句:

sum += *iPtr++;     或 sum += *(iPtr++);

指针和数组:

数组名可以拿来初始化指针,数组名就是数组第一个元素地址。

数组名是指针常量,区别于指针变量。给数组名赋值是错误的。

int iArray[100];

int sum = 0;

……

for(int i = 0; i < 100; i++)

{

  sum += *iArray;

  iArray++;                          //Error。数组名不是左值。

}

数组名表示内存中分配了数组的固定位置,修改了这个数组名,就会丢失数组空间。

 

const指针:

指向常量的指针(常量指针)

在指针定义语句的类型前加const,表示指向的对象是常量。

const int a = 78;

const int b = 28;

const int * pi = &a;

* pi = 58;    //Error。

pi = &b;      //OK.

int * pj = &b; //error。b为常量。不能把它的地址赋给非常量指针。

常量指针定义const int * pi = &a;告诉编译器,*pi是常量,不能将*pi作为左值进行操作。

指针常量

在指针定义语句的指针名前加const,表示指针本身是常量。

char * const pc = "asdf";

pc = "dfgh";   //Error.指针常量不能改变其指针的值。

*pc = 'b';  //OK.

*pc++ = 'y';  //Error. 指针常量不能改变其指针的值。

在定义指针常量时必须进行初始化。

指针常量定义 int * const pc = &b;告诉编译器,pc为常量,不能作为左值进行操作,但是允许修改间接访问值,即*pc可以修改。

常量指针常量

可以定义一个指向常量的指针常量,它必须在定义时进行初始化。

const int ci = 7;

int ai;

const int * const cpc = &ci;

const int * const cpi = &ai;

*cpi = 39;   //Error

ai = 39;   //OK.

常量指针常量 const int * const cpc = &b;告诉编译器,cpc和*cpc都是常量,它们都不能作为左值进行操作。

总结:若const位于*号左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;若const位于*号右侧,const就是修饰指针本身,即指针本身是常量。

 

void 指针

它是空类型指针,不指向任何类型。仅仅只是一个地址。

不能进行指针运算,也不能进行间接引用。因为这两种操作都需要指针的类型信息。

将其他指针的值赋给空类型指针是合法的。但是 将空类型指针赋给其他指针则不被允许,除非进行显式转换。

int a = 20;

int * pr = &a;

void * p = pr;     //OK

pr = p;       //Error

pr = (int *)p;    //OK

 

指针函数

返回指针的函数称为指针函数。

它可以返回堆地址,可以返回全局或静态变量的地址。但不要返回局部变量的地址。

字符指针

字符串的类型是指向字符的指针(char*)。它与数组名同属一种类型。

字符串通常存放在内存data区的const区。由于字符串的地址属性,两个同样字符组成的字符串的地址是不相等的。

如:

if("join" == "join") //此判断语句得出的结论为假。

程序中两个字符串的比较实质上是两个地址的比较。

字符串、字符数组名、字符指针均属于同一种数据类型。

输出字符指针就是输出字符串。输出字符指针的间接引用就是输出单个字符。

字符串比较:

字符串比较应该是逐个字符一一比较。通常使用标准库函数。

strcmp(),它在string.h头文件中声明。

原型:int strcmp( const char * str1,const char * str2);

(1)当字符串str1等于串str2时,返回值0;

(2)当str1串大于str2串时,返回一个正值;

(3)当str1串小于str2串时,返回一个负值。

字符串赋值:

可以用字符串去初始化字符数组,但是不能对字符数组赋予一个字符串,因为数组名是常量指针,不是左值。

char buffer[10];

buffer = "hello";  //Error

 

char buffer[10] = "hello";    //OK

可以使用标准库函数对字符数组进行赋值。

C语言标准库函数strcpy,把从src地址开始且含有'\0'结束符的字符串复制到以dest开始的地址空间

原型声明:char *strcpy(char* dest, const char *src);
头文件:#include < string.h> 和 #include <stdio.h>
功能:把从src地址开始且含有NULL结束符的字符串复制到以dest开始的 地址空间
说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
返回指向dest的 指针
strcpy()仅能对以‘\0’做结束符的字符数组进行操作。
函数原型char *strncpy(char *dest,char *src,size_t n);
(c/c++)复制字符串src中的内容(字符,数字、汉字....)到字符串dest中,复制多少由size_tn的值决定。如果src的前n个字符不含NULL字符,则结果不会以NULL字符结束。如果n<src的长度,只是将src的前n个字符复制到dest的前n个字符,不自动添加'\0',也就是结果dest不包括'\0',需要再手动添加一个'\0'。如果src的长度小于n个字节,则以NULL填充dest直到复制完n个字节。src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符长度+'\0'。
 
NULL指针值
NULL是空指针值,它不指向任何地方。
NULL与void*是不同的概念。NULL是一个值,一个指针值,任何类型的指针都可赋予该值。而void*是一种类型,是一种无任何类型的指针。

 

 

 

转载于:https://www.cnblogs.com/summerdreamer/p/6665588.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值