int a = 3, b = 5;
int p1 = &a, p2 = &b; // 不能从int*转换为int
因为&a也是个整数,所以int p=&a在早期有的编译器下可能行(我没有那种编译器,试不了),但大多数编译器应该是不行的,因类型不配而不能通过编译。即使行,在你这里由于只是一个整数的指针,所以没有影响,但若a是数组呢?因为int p=&a中的p是整型,p+1就指不到第二个元素a[1]了;而声明int *p=&a后,p是int *型的,p+1就指到第二个元素a[1]了,p+1使地址加了4,而前者只加了1。
1、如果你坚持不想声明指针类型变量的话,用unsigned int来存储指针的值可能会更好一些。
unsigned int p1=(unsigned int)&a,p2=(unsigned int)&b;
2、用int或unsigned int来存储指针,只有你自己清楚这个整型或无符号整型变量里面存放的值是一个指针(地址)值,但编译器不知道。用作实参调用其他函数似乎没有问题,如果指针类型只有赋值运算,那没有太大的区别,但指针至少还有解引用运算和加减运算等!
例如你的程序要在main()里面输出a和b的值:
printf("a=%d,b=%d\n",a,b);
// 如果声明了int *p1,*p2并且已经将它们分别指向了a和b,还可以这样写,看上去简单明了:
printf("a=%d,b=%d\n",*p1,*p2);
// 但如果你将p1和p2声明为unsigned int
// 要取出它们当前所指向变量的值
// 必须进行恶心的繁杂的显式类型转换
// 括号不少,祈祷我没有漏写掉
printf("a=%d,b=%d\n",*((int *)p1),*((int *)p2));
你必须自己实现*p运算,这要你查明p此时实际指向的变量的类型是什么。
不只如此,编译器还会根据声明的指针类型,让p++和p--移动正确的长度,但p如果声明成了int 或 unsigned int,那你必须亲自查明p现在正在指向一个什么类型的变量,然后对那个变量的类型取sizeof。
p+=sizeof(int);// int *p;...;p++;
p+=sizeof(struct student);// struct student * p;...;p++;
p+=sizeof(char);// char * p;...;p++;
//如果你想用指针给4个单元之后的位置赋值,假设p被声明为char *:
*(p+4)='\0';
//不然的话,恐怕要写成这样:
*((char *)(p+4*sizeof(char)))='\0';
//如果p指向了结构体或者链表之类的会更恶心。
而且很难利用编译器进行指针类型的检查(譬如你不小心将一个二级指针类型的指针值赋给了一个一级指针类型的指针变量,或者反过来),一大堆的强制类型转换挤在那里够你拆上半天的。
总之,这样的程序,可读性会变得非常差,排错也会很不方便,读你的程序的人很难一眼看明白你的指针正在干什么。
区别可不小……
如果是写成int *p1=&a,*p2=&b的话,那么p1, p2的类型为指向int类型变量指针,本质是指针,它存的东西被认为是地址。
而如果写成int p1=&a,p2=&b的话,那么p1, p2的类型为int类型变量, 本质是int类型的变量,而里面存的东西被认为是地址,其实是地址用int类型方式表示出来而已,但本质是int变量;
你替换试试就知道了,如果用int p1=&a,p2=&b的话那么你的swap函数是不起作用的。
前面那位朋友的swap_by_reference(int&, int &)其实不是你说的那种,这里用到的是引用,是另一种安全的指针,这个就涉及到C++了,跟这个问题没有关系。