指针运算
指针±整数
指针关系运算是与指针类型息息相关,如果是char* 类型,指针变量+1,那么地址增加一个字节。
int main() { int arr1[]={0,1,2,3,4,5,6,7,8,9}; int* p=arr1; int sz=sizeof(arr1)/sizeof(arr1[0]); for(int i=0;i<sz;i++) { printf("%d ",*(p+i));//此时就是指针+整数,地址每次增加4个字节,从而打印下一个数字,最后屏幕输出数组中所有数字 } return 0; }
指针-指针
指针-指针结果为两指针之间元素个数
int my_strlen(char *s) { char *p = s; while(*p != '\0' ) p++; return p-s; } int main() { printf("%d\n", my_strlen("abc"));//故此打印值为3 return 0; }
关系运算(比较大小)
int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int* p = &arr[0]; int i = 0; int sz = sizeof(arr) / sizeof(arr[0]); while (p < arr + sz) //指针的⼤⼩⽐较 { printf("%d ", *p); p++; } return 0; }
野指针
野指针成因
1.指针未初始化
int main() { int *p;//局部变量指针未初始化,默认为随机值 *p = 20; return 0; }
2.指针越界
int main() { int arr[10] = {0}; int *p = &arr[0]; int i = 0; for(i=0; i<=11; i++) { //当指针指向的范围超出数组arr的范围时,p就是野指针 *p=i; p++; } return 0; }
3.指向已释放的空间
int* test() { int n = 100;//创建的是临时变量,出函数就会被程序释放 return &n; } int main() { int*p = test(); printf("%d\n", *p); return 0; }
如何规避野指针
1.指针初始化,就算不知道暂时赋值多少,可以把指针赋值为NULL
2.注意指针越界,申请多少就使用多少,不要越界使用
3.避免使用函数内部创建的局部变量
传值调用 传址调用
传值调用
void Swap1(int x, int y) { int tmp = x; x = y; y = tmp; } int main() { int a = 0; int b = 0; scanf("%d %d", &a, &b); printf("交换前:a=%d b=%d\n", a, b); Swap1(a, b);//只传变量,无法完成交换是传值 printf("交换后:a=%d b=%d\n", a, b); return 0; }
传址调用
void Swap2(int*px, int*py) { int tmp = 0; tmp = *px; *px = *py; *py = tmp; } int main() { int a = 0; int b = 0; scanf("%d %d", &a, &b); printf("交换前:a=%d b=%d\n", a, b); Swap1(&a, &b);//传地址,函数中地址改变就可以完成数字交换 printf("交换后:a=%d b=%d\n", a, b); return 0; }