一、 经典的指针程序:互换两数
#include<stdio.h>
void exc(int* a, int* b);
int main(void){
int a = 3 ;
int b = 5 ;
exc(&a, &b );
printf("%d, %d \n",a,b);
return 0;
}
void exc(int* p, int* q){
int t;
t = *p;
*p = *q;
*q = t;
}
问题:
能不能这样写
void exc(int* p, int* q){
int* t;
*t = *p;
*p = *q;
*q = t;
}
答:不能。
p
是int*
,*p
是int
。
如果要互换*p
和*q
的值,则 t
必须定义成int
,不能定义成int*
,否则语法错误
* 的含义
1.乘法
2.定义指针变量
如:int*p;
3.指针运算符
该运算放在已经定义好的指针变量的前面
如果p是一个已经定义好的指针变量
则*p表示以p的内容为地址的变量
二 、数组和指针
指针和一维数组:
#include<stdio.h>
int main(void) {
int a[5];
int b[5];
printf("% x \n", &a[0]);
printf("% x", a);
}
结论:一维数组名是一个指针常量
;
它存放的是一维数组第一个单元的地址。
数组下标和指针
#include<stdio.h>
int main(void) {
char *p = "abcdef";
printf("% d ,%d" , p[1],*(p+1));
}
结论:如果p为指针变量,则 p [ i ] = *(p+i)
。
确定一个数组需要两个参数
#include<stdio.h>
void f(int * pArr, int len);
int main(){
int a[5] = {1, 2, 3, 4, 5 };
int b[6] = {5, 6, 7, 8, 9 };
int c[10] = {9, 10, 11, };
f(a, 5);
f(b, 5);
f(c, 10);
return 0 ;
}
void f(int * pArr, int len){
int i;
for(i = 0; i < len; i++){ //遍历
printf("%d ", *(pArr+i)) ;
}
printf("\n");
}
结论:需要地址和长度
修改数组元素的值
#include<stdio.h>
void f(int* pArr, int len);
int main(){
int a[3] = {1, 2, 3};
printf("%d \n", a[2] );
f(a,6);//1
printf("%d \n", a[2] );
return 0 ;
}
void f(int* pArr, int len ){
pArr[2] = 33;//2
}
结论:
1、a = pArr = 数组第一个下标的地址
2、a [ i ] = pArr [ i ] = *( a + i ) = *( pArr + i )
他们是同一个变量
3、数组通过传入首元素的地址
、数组的长度
,可以对整个数组
元素进行修改
网友提示: 数组的定义是a [ 3 ], a可以表示数组里第一个数的地址;
* pArr直接读取来获取 a 来获得他们的地址;
他们虽然是同一个变量、有同样的作用但他们不是相等的
。
三 、 指针变量运算
指针变量不能相加
不能相乘
也不能相除
。
如果两个指针变量指向的是同一块连续空间中的不同存储单元
,则这两个指针变量才可以相减
四、一个指针变量占几个字节?
- 一个变量的地址使用该变量
首字节的地址
来表示 - 指针变量类型确定了所指变量占几个字节
- 首字节的地址编号需要字节来保存
- 地址是32/64位的数据,一个字节只能保存8位数,所以需要4/8个字节来保存
- 总结:一个指针变量,无论它指向的变量占几个字节该指针变量本身只占
4
(32位)/8
(64位)个字节