【重生之我要苦学C语言】深入理解指针3
深入理解指针3
数组
数组名是数组首元素的地址,但有两个例外:
- sizeof(数组名)//sizeof的括号中单独放一个数组名的时候,数组名表示整个数组,计算出但是整个数组的大小,单位是字节
- &数组名 //这里的数组名也表示整个数组,取出的是这个数组的地址
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("&arr[0] =%p\n", &arr[0]);//首元素的地址
printf("&arr[0]+1 =%p\n", &arr[0]+1);//首元素的地址+1
printf("arr =%p\n", arr);//首元素的地址
printf("arr+1 =%p\n", arr+1);//首元素的地址+1
printf("&arr =%p\n", &arr);//数组的地址
printf("&arr+1 =%p\n", &arr+1);//数组的地址+1
return 0;
}
&arr+1比&arr大了40,即跳过了整个arr数组
&arr[0]——>int*
arr ——>int*
&arr ——>类型不是int*(数组指针)
使用指针访问数组
按顺序输出数组元素:
方法一:p不变
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int* p = arr;
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
for (i = 0;i < sz;i++) {
printf("%d ", *(p + i));
}
return 0;
}
方法二:p改变
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int* p = arr;
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
for (i = 0;i < sz;i++) {
printf("%d ", *p);
p++;
}
return 0;
}
输入数组的内容
方法一:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
int arr[10] = { 0 };
int* p = arr;
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
for (i = 0;i < sz;i++) {
scanf("%d", p + i);
}
for (i = 0;i < sz;i++) {
printf("%d ", *p);
p++;
}
return 0;
}
方法二:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
int arr[10] = { 0};
int* p = arr;
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
for (i = 0;i < sz;i++) {
scanf("%d", p);
p++;
}
p = arr;//p回归首元素地址
for (i = 0;i < sz;i++) {
printf("%d ", *p);
p++;
}
return 0;
}
int* p = arr;
arr-数组名,是数组首元素的地址,类型是:int*
p里面存放的也是首元素的地址,类型也是int*
arr等价于p
当不用指针输出的时候,应写为:
for (i = 0;i < sz;i++) {
printf("%d ", arr[i]);
p++;
}
那么因为arr等价于p,可以写成p[i]:
for (i = 0;i < sz;i++) {
printf("%d ", p[i]);
p++;
}
又因为可以写成
for (i = 0;i < sz;i++) {
printf("%d ", *(p + i));
}
可以得出:
p[i] =* (p+i) =*(i+p)
那么是否可以写成 i[p] 或 i[arr] 呢?
答案是可以的
arr[i] ——> *(arr+i)
[]就是一个操作符
数组传参的本质
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void print_arr(int arr[], int sz) {
int i = 0;
for (i = 0;i < sz;i++) {
printf("%d ", arr[i]);
}
}
int main() {
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int sz = sizeof(arr) / sizeof(arr[0]);
print_arr(arr, sz);
return 0;
}
如果改为:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void print_arr(int arr[]){
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
for (i = 0;i < sz;i++) {
printf("%d ", arr[i]);
}
}
int main() {
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
print_arr(arr);
return 0;
}
X86环境下:
X64环境下:
是因为:
数组在传参的时候,不会将整个数组传递过去
print_arr(arr);//arr数组名表示数组首元素的地址
所以传过去的是数组首元素的地址,在函数内没办法计算数组的元素个数,
void print_arr(int arr[]){//实际上为int* arr
所以可以写为:
void print_arr(int* arr, int sz) {
形参的数组和实参的数组是同一个数组
函数的形参可以写成数组,也可以写成指针
冒泡排序
复习一下冒泡排序
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void bubble_sort(int arr[], int sz) {
int i = 0;
int j = 0;
for (i = 0;i < sz - 1;i++) {
int flag = 0;//假设已经有序
for (j = 0;j < sz - 1 - i;j++) {
if (arr[j] > arr[j + 1]) {
flag = 1;
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
if (flag == 0) {
break;
}
}
}
void print_arr(int arr[], int sz) {
int i = 0;
for (i = 0;i < sz;i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
int main() {
//排成升序
int arr[10] = {9,8,7,6,5,4,3,2,1,0};
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr,sz);
print_arr(arr, sz);
return 0;
}
二级指针
int a = 10;
int* p = &a;
int** pp=&p;//pp就叫二级指针
理解:int* *pp: * pp是说pp是指针变量,int * 是说pp指向的p是 int *类型的
二级指针变量是用来存放一级指针的地址
printf("%d\n", **pp);
等同于
printf("%d\n", *p);
const修饰:
const int** p;//const限制**p
int* const * p;//const限制*p
int** const p;//const限制p
指针数组
存放指针(地址)的数组
int* arr[3] = { &a,&b,&c };
例:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
int a=10, b=20, c=30;
int* arr[3] = { &a,&b,&c };
int i = 0;
for (i = 0;i < 3;i++) {
printf("%d ", *(arr[i]));
}
return 0;
}
指针数组模拟二维数组
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
int arr1[] = { 1,2,3,4,5 };
int arr2[] = { 2,3,4,5,6 };
int arr3[] = { 3,4,5,6,7 };
int* arr[3] = { arr1,arr2,arr3 };//arr指针数组
int i = 0;
for (i = 0;i < 3;i++) {
int j = 0;
for (j = 0;j < 5;j++) {
printf("%d ", arr[i][j]);
}
printf("\n");
}
return 0;
}
结果为:
arr[i]=*(arr+i)
arr[j]=x[j]
x[j]= *(x+j) = *(*(arr+i)+j)
END……
做一个积极向上的人,读温柔的句子,见阳光的人,眼里全是温柔与笑意~🌻