《C和C++代码精粹》——2.6 const指针

2.6 const指针

C和C++代码精粹
注意memcpy函数第二个参数中的const关键字。这个关键字告诉编译器此函数将不会改变source指向的任何值(除了强制类型转换)。当把指针作为参数传递时,总是合适地使用const限定符是一个很好的习惯,它不仅可以防止你无意中错误的赋值,而且还可以防止在作为参数将指针传递给函数时可能会修改了本不想改变的指针所指向的对象的值。例如,如果在程序清单2.6中的声明是:

const int i=7,j=8;

有可能因为下面这条语句而得到警告:

swap(&i,&j);

因为swap的确改变了其参数所指的变量的值。

如果浏览一下你所使用的编译器提供的标准头文件,就会看到const。在一个声明中,当const出现在星号前面的任意位置时,表明所指向的内容不会被改变:

const char *p; //指向常字符的指针
char const *q; //同样是指向常字符的指针
char c;
c=*p;          //OK(假设p和q已经初始化了)
*q=c;          //错误,不能改变指针所指的内容

也可以通过把const放在星号的后面来声明指针本身不可改变:

char* const p;
*p='a';         //OK,只有指针是常量
++p;             //错误,不能改变指针

要禁止改变指针和它所引用的内容,就在星号前和后都使用const:

const char* const p;
char c;
c=*p;         //OK-能读出内容
*p='a';      //错误
++p;          //错误

程序清单 2.7中的函数inspect说明了如何打印出任何对象的不同字节。因为我并没有改变对象的内容,所以第一个参数是一个指向const的指针,而且,在使用它之前要小心地将它转换成一个指向常字符的指针。

程序清单2.7 检查任何对象的函数

// inspect.cpp: 检查对象的字节
#include <iostream>
#include <iomanip>
using namespace std;
void inspect(const void* ptr, size_t nbytes)
{
    const unsigned char* p = (const unsigned char*) ptr;  

    cout.setf(ios::hex, ios::basefield);
    for (int i = 0; i < nbytes; ++i)
        cout << "byte " << setw(2) << setfill(' ') << I
             << ":    " << setw(2) << setfill('0') << int(p[i])
             << endl;
}
main()
{
    char c = 'a';
    short i = 100;
    long n = 100000L;
    double pi = 3.141529;
    char s[] = "hello";
    inspect(&c, sizeof c);   cout << endl;
    inspect(&i, sizeof i);   cout << endl;
    inspect(&n, sizeof n);   cout << endl;
    inspect(&pi, sizeof pi); cout << endl;
    inspect(s, sizeof s);    cout << endl;
}
//输出:
byte  0:    61
byte  0:    64
byte  1:    00
byte  0:    a0
byte  1:    86
byte  2:    01
byte  3:    00
byte  0:    13
byte  1:    7c
byte  2:    d3
byte  3:    f4
byte  4:    d9
byte  5:    21
byte  6:    09
byte  7:    40
byte  0:    68
byte  1:    65
byte  2:    6c
byte  3:    6c
byte  4:    6f
byte  5:    00

本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。

时间: 2024-09-30 00:12:28

《C和C++代码精粹》——2.6 const指针的相关文章

《C和C++代码精粹》——2.5 普通指针

2.5 普通指针 C和C++代码精粹 通常编写能接收指向任意类型参数的函数是很方便的.这是很有必要的,例如,用标准的库函数memcpy,能够从一个地址向另一个地址拷贝一块内存.你也可能想调用memcpy来拷贝自己创建的结构: struct mystruct a,b; /.../ memcpy(&a,&b,sizeof(struct mystruct)); 为了操作任意类型的指针,memcpy把它头两个参数声明为void型指针.可以不需要强制类型转换将任何类型的指针赋予void类型.也可以在

《C和C++代码精粹》——1.2 循序渐进

1.2 循序渐进 C和C++代码精粹 在没有完全掌握C++的情况下也可以有效地使用它.事实上,面向对象技术承诺如果供应商为重用.可扩展性提供设计好的类库,那么建立应用程序的工作就很容易了.现有的开发环境,及其应用程序框架和可视化组件,正在兑现这一承诺. 如果觉得必须要掌握这种语言,可以一步步地去做,并且在这一过程中可以取得丰硕的成果.已出现的3个"顶峰"是: 1.更好的C: 2.数据抽象: 3.面向对象编程. 由于C++比C更安全.更富于表达,所以可以将它作为一个更好的C使用.这个顶峰

《C和C++代码精粹》——2.12 指向函数的指针

2.12 指向函数的指针 C和C++代码精粹 一个指针可以指向函数也可以指向存储的对象.下面的语句声明fp是一个指向返回值为整型(int)的函数的指针: int(*fp)( ); *ftp的圆括号是必需的,没有它的语句 int *fp( ); 将fp声明为一个返回指向整型(int)指针的函数.这就是将星号与类型声明紧密相连的方式成为逐渐受人们欢迎的方式的原因之一. int fp(); //方式说明fp()返回一个指向整型的指针(int ) 当然,这种方式建议你通常应该每条语句只声明一个实体,否则

《C和C++代码精粹》导读

前言 C和C++代码精粹 本书适合于那些C和C++的职业程序员.假如你已熟悉这两种语言的语法和基本结构,这本书能够为你创建有效的.实用的程序提供实践性的指导.每一个代码范例或程序范例均标明行之有效的用法和技术,这些用法和技术对C/C++这两种重要编程语言的性能发挥起着重要的作用. 对于那些希望在工作中加强自身技术和提高效率的人来说,本书可以算是一本经验之谈.尽管目前人们对面向对象模式的推崇到了白热状态(本书也包括这方面的丰富内容),可是我没有理由不对C++的基础-C表示尊崇.我发现太多的程序开发

《C和C++代码精粹》——2.8 数组作为参数

2.8 数组作为参数 C和C++代码精粹当你把数组作为参数传递给一个函数,正如所预期的那样,是传递了指向数组第一个元素的指针.因此,可以在调用的函数中永久地改变数组元素的值.在程序清单2.12的函数f中,地址&a[0]按值传递给指针b,因此表达式b[i]就和表达式a[i]完全是一样的了.不可能按值传一个完整的内置数组. 即使用数组符号定义了参数b,即: int b[] 它同下面这种写法是完全一样的. int *b 程序清单2.12 说明作为参数的数组实际上是指针 // array5.cpp: 数

《C和C++代码精粹》——1.12 运算符重载

1.12 运算符重载 C和C++代码精粹在C++中你可以重载运算符,例如,定义一个复数的数据类型如下: struct complex { double real, imag; }; 假如能使用中缀符号用于复数加法,那将会相当方便.如: complex c1,c2; - complex c3=c1+c2; 当编译器遇到如c1+c2这样的表达式时,将查找下边两个函数中的一个(只须其中的一个存在): operator+(const complex&,const complex &); //全局函

《C和C++代码精粹》——1.8 标准流

1.8 标准流 C和C++代码精粹C++中有4个预定义的流:cin(标准输入),cout(标准输出),cerr(标准错误),clog(标准错误).除了cerr外其余都是全缓冲流.就像stderr一样,cerr的行为好象是非缓冲的,但事实上它是单元缓冲的,也就是说它在处理完每一个对象而不是每一个字节后会自动清除缓冲.例如,带有单元缓冲的语句: cerr<<"hello":缓冲处理5个字符,然后清除缓冲区.一个非缓冲处理的流会立即发送每个字符到它的最终目的地. 程序清单1.5

《C和C++代码精粹》——1.18 C的兼容性

1.18 C的兼容性 C和C++代码精粹为了提供强类型检查和面向对象, C++不得不在一些语言方面与C不同.如果要把C++作为更好的C使用,就必须留意两种语言间的不同特性. 程序清单1.18 说明复数模板 #include <iostream> #include <complex> using namespace std; main() { complex<double> x(1.0, 2.0), y(3.0, 4.0); cout << "x +

《C和C++代码精粹》——2.15 小结

2.15 小结 C和C++代码精粹C和C++仅仅与那些使用它们的人一样危险.指针是地址.可以将任何一个指针赋值成void*.注意区分一个const指针和一个指向const的指针.p±n = =(char)p±n sizeof (*p).p-q = = ±n .*(a+i) = = a [i].除非在sizeof和&的上下文中,否则一个数组名即是指向它第一个元素的指针.没有多维数组,只有数组的数组.仅是指针的存在并不要求它所引用的类型的实现的有效性(这是一个不完全类型).如果理解了这些概念,你就正