#include <iostream.h>
#include <string.h>
void main()
{
/* test 1
const int c_ival = 0;
int *pi;
pi = c_ival;//指针变量可以通过一个常量赋值
int ival = 2;//指针变量不可以通过一个变量赋值
//pi = 2; //任何字面量,除0外,都不可以给指针变量赋值
pi = 0; //指针只能通过字面值0或者const量0,以及NULL预定义变量赋值
pi = NULL;//NULL是一个预处理变量,也可以为指针变量赋值。
*/
/* test 2
double dval;
double *pd = &dval;//可通过变量的地址(指针)给指针变量赋值
double *pd2 = pd; //同类型的指针变量可以赋值
// int *pi = pd; //不同类型的当然不能复制了
// int *pi = &dval; //类型不同的变量的指针不能互相赋值
*/
/* test 3
double obj = 3.14;
double *pd = &obj;//OK,不多说
void *pv = &obj;
pv = pd;
int *pi;
//pi = &2;//不能对常量取地址。
int iv = 11;
pi = &iv;
pv = pi;//类型相同的变量才可以赋值,而且void*型指针可以保持任何对象的地址
//void*指针只能用于比较,传参,不可以操作其指向的对象
*/
/**
友情提供:
指针和引用的比较:
虽然引用(reference)和指针都可以间接访问另一个值,但它们之间有两个主要的区别。
第一个区别在于引用总是指向某个对象:定义引用时没有初始化是错误的。第二个重要
的区别则是赋值行为的差异:给引用赋值修改的是该引用所关联的对象的值,而并不是
使引用与另一个对象关联。应用一经初始化,就始终指向同一个特定的对象。
*/
/* test 4
int ival = 1024, ival2 = 2048;
int *pi = &ival, *pi2 = &ival2;
pi = pi2;
//正确
int &ri = ival, &ri2 = ival2;
ri = ri2;
cout<<"ri = "<<ri<<", ri2 = "<<ri2<<endl;
//output :ri = 2048, ri2 = 2048
//注意这里并没有改变ri与ri2的指向,而是改变他们所各自关联的对象的值。
*/
/* test 5
int ival = 1024;
int *pi = &ival;
int **ppi = π //C++使用**操作符指派一个指针指向另一个指针。**也是指向符。
//下面相同的值,相同的对象
cout<<ival<<" "<<*pi<<" "<<**ppi<<endl;
*/
//忍不住了,讨论下,const引用
//正解:const引用是指向const对象的引用。
//const int ival = 1024; //引用必须初始化
//const int &refVal = ival;
//int &ref2 = ival;//非常量对象的引用不可以指向常量对象的引用
// const int &refVal2 = 2;//const引用可以以字面量初始化
// int vali = 1111;
// const int &refVal3 = vali;//const引用可以以变量初始化,但是通过该引用访问该变量,就只能当做常量使用。
// refVal3 = 100; 不可修改,表明这里是该引用指向了一个常量对象。
//l-value左值,左值是变量,可左可右。 r-value右值,右值是常量(包括字面量),只能右
/*
在指针上加上(或减去)一个整形数值n等效于获得一个新指针,该新指针指向指针原来指向的元素之后
(或之前)的第n个元素。
两个指针减法操作的结果是标准库类型ptrdiff_t的数据。这是一个signed整形,它表示两个指针之间
的差距。
*/
/* test 6
const size_t arr_sz = 5;
int int_arr[arr_sz] = {0, 1, 2, 3, 4};
for(int *pbegin = int_arr, *pend = int_arr + arr_sz;
pbegin != pend; ++pbegin)
{
// cout<<int_arr[5]; 为什么会输出5,诡异啊。
cout<<*pbegin<<' ';
}
*/
//指向const对象的指针和const指针
//指向const对象的指针这样声明 const double *cptr;
//1. 不能修改所指对象的值,因为是const对象嘛。
//*cptr = 42; //这是错误的。
//2. 不能使用void*指针保持const对象的地址,而必须使用const void*。
// const int universe = 42;
// const void *cpv = &universe;
// void *pv = &universe; //错误的,必须使用const void*
//3. 对于非const对象的处理和const引用是一样的。
//但是我们可以修改指针变量的值,使我们的指针指向新的对象。只是这个对象无论是否为const
//只要我们通过这个指针访问,那么系统都认为其为const。(自以为指向const的指针)
//const指针是这样 double *const cptr;
//指针变量的本身的值无法修改,也就是指针无法执行初始指定的对象的值,
//这样和const引用则比较像了,但是我们可以修改我们所执行的对象。
/*
double dval = 33.33;
double *const cptr = &dval;
*cptr = 332.02;
cout<<dval<<" "<<*cptr;
//下面最变态的:指向const对象的const指针
const double pi = 3.14159;
const double *const pi_ptr = π
//从右向左读,关于指针都一般都这么读,既不可以修改指针所指向的对象的值,也不可以修改该指针的指向。
*/
/*
//typedef和指针 不多说反正记得typedef不是简单的文本扩展,其实只要注意const应该写在类型后面就可以了
//所以:
//下面
typedef string *pstring;
const pstring cstr;
//等价于
string *const cstr;//也就是const指针。
*/
}
再加一点,天亮了要睡觉了啊!
#include <stdio.h>
#include <iostream.h>
#include <string.h>
#include <string>
using namespace std;
void main()
{
const char *cp1 = "A string example";
const char *cp2 = "A different string";
// int i = strcmp(cp1, cp2);
// printf("%d\n", i);
// i = strcmp(cp2, cp1);
// printf("%d\n", i);
// i = strcmp(cp1, cp1);
// printf("%d\n", i);
// char largeStr[16 + 18 + 2];
// strcpy(largeStr, cp1);
// printf("%s\n", largeStr);
// strcat(largeStr, " ");
// strcat(largeStr, cp2);
// printf("%s\n", largeStr);
// char ca[] = {'C', '+', '+', '\0'};
// cout<<strlen(ca)<<endl; 空格并不是null
int ia[3][4] = {
{0, 1, 2, 3},
{4, 5, 6, 7},
{8, 9, 10, 11},
};
typedef int int_array[4];
int_array *ip = ia;
for(int_array *p = ia; p != ia + 3; ++p)
for(int *q = *p; q != *p + 4; ++q)
cout<< *q <<endl;
//可使用数组长度后面的一对圆括号,对数组元素做值初始化:
int *pia2 = new int[10]();
// 这里初始化为0
// 允许定义类类型的const数组,但该类型必须提供默认的构造函数
// const string *pcs = new const string[100];//似乎不支持, 而且没有必要,
//因为string早已做好了相关的支持。
//这里就会使用默认构造函数来初始化数组元素
//使用delete [] 数组名 来释放数组空间。
//delete [] pcs;
delete [] pia2;
}