数组名的理解
一维数组名就是数组首元素的地址,二维数组的数组名就是首行元素的地址,以下两种情况除外:
- 当数组名单独放入sizeof()中时,数组名代表整个数组;
- “&数组名”,这时是取整个数组的地址。(输出时仍然打印首地址,但是指针运算时能看出)
数组传参
- 一维数组传参时,传递的是数组首元素的地址;
- 二维函数传参时,传递的是数组首行元素的地址。
数组和指针的关系
- 一维数组:arr[i] == *(arr + i);两种表达是等价的
- 二维数组:arr[i][j] == *(*(arr+i)+j)
指针访问数组
一维数组传参的本质:实参传给形参的时数组中的首元素地址。用指针访问数组以及实现冒泡排序的代码如下:
- 用指针访问数组:
int main() { int arr[7] = { 0 }; int* p = arr; int i = 0; for (i = 0;i < 7;i++) { *(p+i) = i + 1; } for (i = 0;i < 7;i++) { printf("%d ", *(p + i)); } return 0; }- 冒泡排序(已优化)
void print(int arr[], int a) { int i = 0; for (i = 0;i < a;i++) { printf("%d ", arr[i]); } printf("\n"); } int main() { int arr[7] = { 7,1,2,3,4,5,6 }; int* p = arr; int sz = sizeof(arr) / sizeof(arr[0]); int i = 0; int j = 0; print(arr, sz);//打印乱序的数组 for (i = 0;i <sz-1 ;i++) { int cout = 0; for (j = 0;j < sz - i-1;j++) { if (*(arr + j) > *(arr + j + 1)) { int tmp = *(arr + j); *(arr + j) = *(arr + j + 1); *(arr + j + 1) = tmp; cout = 1; } } if (cout == 0) { break; } } print(arr, sz);//打印排序完成后的数组 return 0; }二级指针
将指针作为所指向内容的指针是二级指针,在代码中的使用如下:
int main() { int a = 0; int* p = &a; int** pp = &p;//int*代表指针pp所指向的内容p的类型 **pp = 100; printf("%d ", **pp); return 0; }指针数组
用于存放指针的数组被称为指针数组。可用于模拟二维数组(这里模拟出来的二维数组时断开的,真正的二维数组时连续的)
int main()//模拟二维数组并打印 { int arr1[] = { 1,2,3 }; int arr2[] = { 4,5,6 }; int arr3[] = { 7,8,9 }; int* arr[] = { arr1,arr2,arr3 };//这里的int*代表的是数组中的元素的类型为指针 int i = 0; int j = 0; for (i = 0;i < 3;i++) { for (j = 0;j < 3;j++) { printf("%d ", arr[i][j]); } printf("\n"); } return 0; }字符指针变量
指向的内容为字符或字符串的指针变量,该指针存放的是字符串中首个字符的地址,打印字符串时需要提供字符串守字符的地址:“printf("%s ",首地址)”,在代码中的应用如下:
int main() { const char* p = "abcdef";//最好加上“const”,这里的字符串时常字符串,不能改变。 printf("%s ", p); return 0; }数组指针变量
数组指针变量是指针变量所指的内容为:数组的指针变量,主体还是指针,形如:“int (*p)[10]=&arr”,在代码中的使用如下:
int main() { int arr[7] = { 0 }; int(*p)[7] = &arr;//若要进行指针运算,“[]”中必须要放数字 printf("%p \n", arr);//两次打印的结果相同 printf("%p \n", p); printf("%p \n", p + 1); return 0; }