c语言指针
彻底搞懂c语言的指针,数组指针、指针数组、二数组、指针参数传递等
int num = 10; int* p = # *p = 20;
&表示取地址,int*
表示生成一个野指针,*p表示解引用;以上的代码执行之后,num
的值变为20。printf("%p",&num)
表示的是打印num
的指针。
int arr[10] = {0};
int *p = arr;
for (int i = 0;i < 10;i++){
*(p + i) = 1;
}
*(p+i)表示解引用,对数组进行处理。
- 野指针:
int *p; *p = 20;
p表示的为野指针,p的位置是随机的,所以会造成p越界。 当数组地址越界也会出现野指针。 返回函数的局部变量指针时也会出现野指针。 - 野指针解决方法:
- 指针初始化
int* p = NULL;
- 小心地址越界。
- 指针使用之前检查有效性。
if (p != NULL)
- 指针初始化
-
求字符串的长度:
//计数器法 int my_strlen (char *str){ int length = 0; while (*str != '/0'){ //最后一个指针表示为'/0' length ++; str ++; } return length; } //指针-指针 int my_strlen (char *str){ char *start = str; while (*str != '/0'){ str ++; } return str - start; } int main(){ int len = my_strlen("abc"); //传入的时“abc”的a的地址 printf ("%d",len); return 0; }
-
二级指针:
int a = 10;int* p = &a;int* *pa = &p;
p为指针,表示整型变量a的地址,而pa表示二级指针,表示指针p的地址。 -
char* p = 'hello world'
,其中的p
表示的是h
的地址,printf("%d",*p)
可以打印出h,*p
表示对p
进行解引用。 -
指针数组:
int a[] = {1,2,3,4,5}; int b[] = {2,3,5,8,9}; int c[] = {4,5,6,9,7}; int* arr[3] = {a,b,c}; for (int i = 0;i < 3;i++){ for (int j = 0;j < 5;j++){ printf ("%d ",*(arr[i] + j)); //等同于:printf ("%d ",arr[i][j]); } printf ("/n"); }
-
数组指针:
int (*p)[5];
表示的是p为一个int类型的指针,且p的数值有5个。所以p的大小为 4*5;int arr[10] = {0};int (*parr)[10] = &arr
取出数组的指针,parr是指向数组的指针----存放的是数组的地址void printf1(int arr[3][5],int c,int k){ for (int i = 0;i < c;i++){ for (int j= 0;j < k;j++){ printf ("%d" ,arr[i][j]); } printf ("\n"); } } void printf2 (int (*arr)[5],int c,int k){ //传入的是二维数组第一行的首地址 for (int i = 0;i < c;i++){ for (int j = 0;j < k;j++){ printf ("%d ",(*(arr + i) + j)); //*(arr + i)表示为第i行的地址解引用= 第i行的函数名,所以要继续解引 用才能得到数据。 } printf ("/n"); } } int main (){ int arr[3][5] = {{1,2,3,4,5},{2,3,4,5,6},{7,8,9,6,4}}; printf1(arr,3,5); //把arr看成数组。 printf2(arr,3,5); //把arr看成指针;二位数字的首元素表示的是第一行的地址(一维数组的地址) return 0; }
-
一维数组传参数:
void text (int a[10]) void text (int a[]) void text (int *a) void text1 (int *a[10]) void text1 (int* *a) int main (){ int arr1[10] = {0}; int* arr2[10] = {0}; text (arr1); text (arr2); return 0; }
-
二维数组传参数
void text (int arr[3][5]) void text (int arr[][]) //不可以,最多只能省略行,列是坚决不能省略的 void text (int arr[][5]) void text (int *arr) //不可以,二维数组的arr表示为第一行的含有5个参数的地址 void text (int (*arr)[5]) void text (int* *arr) //不可以 int main (){ inr arr[3][5] = {0}; text (arr); }
-
一级指针传参数
void text(char* p) int main (){ char ch = 'w'; text (&ch); //取ch的地址 char* p = &ch; text (p); }
-
二级指针传参数
void text (int** p) int main (){ int a = 10; int *p = &a; int **pp = &p; text (pp); text (&p); int *arr[10] = {0}; text (arr); //存放一级指针的数组 }
-
函数的地址。注意区分 数组名 != &数组名;(&数组名:表示整个数组的地址相当于(*arr)[10]);函数名 == &函数名。
int add (int x,int y){ } void text (char * str){ } int (*pf)(int ,int) = &add; void (*pt)(char) = &text; int ret = (*p)(3,5); //调用add,*p表示对函数解引用。 int ret = pf(3,5); int ret = add(3,5); //以上三种调用方式完全一样。