现在的位置: 首页 > 综合 > 正文

c++ 指针和字符串

2013年08月18日 ⁄ 综合 ⁄ 共 2390字 ⁄ 字号 评论关闭
  

      指针相信都比较熟悉了,这里稍微总结一下。 

1、传递参数给函数

      在c++,中,有三种方式可以将参数传递给函数,前面已经讨论过了两个:传值调用和按引用调用,还有一种情况就是使用“指针参数按引用调用”,听起来比较拗口,下面来举一下例子

#include <iostream>
using std::cout;
using std::endl;

int cubeByValue(int);
void cubeByReference(int &);
void cubeByPointer(int *);

int main()
{
    
int n1 = 1, n2 = 1, n3 =1;

    n1 
= cubeByValue(n1);
    cubeByReference(n2);
    cubeByPointer(
&n3);
    cout 
<< n1 << ' '<< n2 << ' ' << n3 << endl;
}

int cubeByValue( int i)//传值调用
{
    
return i*2;
}

void cubeByReference(int & i)//引用调用
{
    i 
*= 2;
}

void cubeByPointer(int* i)//使用指针参数按引用调用
{
    
*= ( *i) * 2;
}

/*输出结果
2 2 2
*/

2、用const限定访问权限

      使用const,我们可以有4种方法将指针传递给函数,当然,这代表了4种不同的访问权限:

      a) 非常量数据的非常量指针。拥有最高权限,数据可以通过复引用指针来修改,同时指针也可以修改为指向其他数据。次指针的声明中不包含const限定符。

      b)常量数据的非常量指针。指针可以被修改为指向其他数据,但是被指向的数据不能通过复引用指针来修改。这种指针通常作为打印数组的函数的数组参数。

void printArray(const char * sPtr)
{
    
for(;*sPtr != '/0';sPtr++)
           cout << *sPtr;
}

      c)非常量数据的常量指针。指针总是指向相同的内存地址,但可以修改这个地址里的数据内容。例如数组名就是非常量数据的常量指针。

      d)常量数据的常量指针。这里有最低权限,当数组被传递到函数,并且函数不能修改数组内容时,就是这种情况。

int main()
{
    
int x = 5;
    
const int * const ptr = & x;
    
//*ptr = 7 //错!
    
// ptr ++ //错!
}

3、数组的sizeof结果

      当sizeof用在一个数组身上,那么返回的是这个数组所占用的总字节数,当数组被转换为指针参数时,sizeof将返回指针的长度(通常为4),而不是数组长度。

size_t getSize(double *ptr)
{
    
return sizeof(ptr);
}

int main()
{
    
double array[20];
    cout 
<< sizeof(array)<<endl<<getSize(array)<<endl;
    cout 
<< sizeof(array) / sizeof(double);//当知道数组里面的数据类型时,可以用此方法得到数组长度
}

/*输出
80
4
20
*/

      (注:sizeof是一个操作符,而不是一个函数,使用sizeof不会对程序性能产生不良影响。sizeof返回类型是size_t 通常被定义为unsigned int类型。)

4、指针表达式和指针算法

      指针可以自增、自减、加减一个整数、减一个指针。

      a)指针加减一个整数 i 是把它所指向的位置加上 i * (它所指向的数据类型),即如果一个指向int类型的指针变量ptr所指向的内存位置是100,那么 prt++ 后,它所指向的内存地址是100 + 1*sizeof( int ) = 104;

      b)不是任意两个指针都可以进行相互的减操作,只有两个指针都指向一个数组里面的数据时才能进行减操作。得到的结果是两个指针之间的元素个数。

      c)将一个指针赋值给另一个指针时,语句左右两边的类型必须一致,不一致也必须用强制转换来换成一致。这里有一个例外,就是void *类型,它是一个通用指针,任何指针都可以不通过强制转换赋值给void *类型的指针,相反,void *类型的指针必须经过强制转换后才能赋值给其他类型的指针。并且void *类型的指针不能被复引用,因为编译器不知道指针指向的数据类型。综合例子:

int main()
{
    
int array[4];

    
double *dbPtr;
    
void *vd;

    
int *ptr1 = array;
    
int *ptr2 = &array[0];

    ptr1
++;//此时ptr1指向元素array[1]
    ptr2 += 3;//此时ptr2指向元素array[3]

    cout 
<< ptr2 - ptr1<<endl;//相减得到两个指针之间元素的个数


    dbPtr 
= (double *)ptr1;//必须经过强制类型转换
    vd = dbPtr;//不需要强制类型转换
    ptr2 = (int *) vd;//必须经过强制类型转换

    
return 1;
}

/*输出
2
*/

5、函数指针

      函数指针指向函数在内存中的地址。函数名其实就是执行这个函数任务的代码在内存中的开始地址。函数指针能够传递给函数、能够从函数返回、能够放在数组中以及能够赋值给其他函数指针。

抱歉!评论已关闭.