赞
踩
本文基本为深入理解指针的笔记
不要混淆二维数组
和指针数组
,它们类似但是行为会有差异
int vector[5] = { 1,2,3,4,5 };
printf("%d", sizeof(vector) / sizeof(int));
我们可以将二维数组当作数组的数组,如果只用一个下标访问数组,得到的就是对应行的指针
int matrix[2][3] = { {1,2,3},{4,5,6} };
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
printf("%d ", matrix[i][j]);
}
}
1 2 3 4 5 6
单独使用数组名会返回数组地址,我们可以把数组地址赋给指针
int vector[5] = { 1,2,3,4,5 };
int* pv = vector;
注意:pv变量是指向数组的第一个元素而不是指向数组本身的指针
我们也可以使用&
取数组的地址,不同于上面的表示法,这么做返回的是整个数组的指针
printf("%p\n", vector);
printf("%p\n", &vector);
0000000EB10FF628
0000000EB10FF628
我们可以验证一下,两个指针的区别,指向数组的第一个元素和指向整个数组的指针是不一样的
int* pv = vector;
int* pv = &vector;//报错:类型不一致 int (*) = int (*)[5]
正确做法
int(*pv)[5] = &vector;
我们可以把数组下标用在指针上,pv[i]
等价于*(pv+i)
for (int i = 0; i < 5; i++) {
printf("%d ", *(pv + i));
}
1 2 3 4 5
注意区分下面两种的指针表示法,第二种指针的值改变,不再指向数组的首元素
//第一种
for (int i = 0; i < 5; i++) {
printf("%d ", *(pv + i));
}
printf("&vector = %p", vector);
printf(" pv = %p\n", pv);
//第二种
for (int i = 0; i < 5; i++) {
printf("%d ", *pv);
pv++;
}
printf("&vector = %p", vector);
printf(" pv = %p\n", pv);
1 2 3 4 5 &vector = 000000B18CF0F5A8 pv = 000000B18CF0F5A8
1 2 3 4 5 &vector = 000000B18CF0F5A8 pv = 000000B18CF0F5BC
vector[i]
表示法生成的机器码从位置vector
开始,移动i
个位置,取出内容。而*(vector+i
)表示法生成的机器码从位置vector
开始,在地址上增加i
,然后取出这个地址中的内容,尽管结果是一样的,生成的机器码却不一样。
用sizeof操作符对数组和同一个数组的指针操作也是不同的
printf("sizeof(int *ptr) = %d\n", sizeof(int *));
printf("sizeof(pv) = %d\n", sizeof(pv));
printf("sizeof(vector) = %d\n", sizeof(vector));
sizeof(int *ptr) = 8
sizeof(pv) = 8
sizeof(vector) = 20
int* pv = (int*)malloc(5 * sizeof(int));
for (int i = 0; i < 5; i++) {
*(pv + i) = i+1;
}
实现getline函数
char* (getLine)(void) { const size_t sizeIncrement = 10;//缓冲区创建时的带线啊哦 char* buffer = (char *)malloc(sizeIncrement); char* currentPosition = buffer;//指向缓冲区下一个空白位置的指针 size_t maximumLength = sizeIncrement;//可以安全存入缓冲区的最大字符数 size_t length = 0;//读入的字符数 int character;//上次读入的字符数 if (currentPosition == NULL) { return NULL; }//如果malloc函数分配失败,返回NULL while (1) { character = fgetc(stdin);//读字符 if (character == '\n') break;//回车符 退出 if (++length >= maximumLength) {//读入的字符数字超过安全存入的数 char* newBuffer = (char *)realloc(buffer, maximumLength += sizeIncrement);//重新分配内存并返回指针,分配成功会释放原来的指针 if (newBuffer == NULL) {//如果重新分配失败 返回NULL free(buffer);//释放之前buffer return NULL; } currentPosition = newBuffer + (currentPosition - buffer);//指向下一个字符位置的指针相应的去新的空间按之前的顺序指向 buffer = newBuffer; } *currentPosition++ = character;//字符指针偏移并被赋值 } *currentPosition = '\0';//跳出,赋值'\0' return buffer;//返回指向分配好的空间的指针 }
I am a student and I am a boy!
I am a student and I am a boy!
将一维数组作为参数传递给函数实际时通过值类传递数组的地址。这样子传递更高效,因为不用拷贝传递整个数组而只是传递地址,不需在栈上分配内存。一般还要传递数组的长度,避免超出索引。
void displayArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
int vector[5] = { 1,2,3,4,5 };
displayArray(vector, 5);
void displayArray(int *arr, int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);//数组表示法
printf("%d ", *(arr+i));//指针表示法
}
printf("\n");
}
int* arr[5];//每个元素都是指针
for (int i = 0; i < 5; i++) {
arr[i] = (int*)malloc(5 * sizeof(int));//为每个元素分配空间
*arr[i] = i;
}
arr[i]
返回的是一个地址,通过*
解引用得到的,*arr[i]
才是一个整数
使用指针表示法
*(arr + i) = (int*)malloc(5 * sizeof(int));
**(arr + i) = i;
(arr+i)
表示第i
个元素的地址
*(arr+i)
为修改元素中的内容,我们使用了*
,于是修改了指针的值,完成了动态的内存分配
**(arr+i)
是再对指针进行解引用,得到储存的int数据
如何解释arr[0][0] = 0
我们假设arr的每个元素都指向一个有5个元素的指针,则arr[0][0]
代表arr
第一个元素指向的第一个元素
int matrix[2][5] = { {1,2,3,4,5},{6,7,8,9,10} };
int(*pmatrix)[5] = matrix;//声明了一个数组指针
(*pmatrix)
声明了一个数组指针
,整条声明语句将pmatrix
定义为一个指向二维数组的指针,每列5
个元素
如果把括号删去就表示声明了5
个元素的数组,数组类型是整数指针
int(*pmatrix)[5] = matrix;
printf("the address: %p\n", pmatrix[0]);
printf("the address: %p\n", pmatrix[1]);
the address: 0000002A6FD4F698
the address: 0000002A6FD4F6AC
可以看到,地址差20,符合差一行元素的状况
正确方式
void display2DArray(int arr[][5], int rows);
void display2DArray(int(*arr)[5], int rows);
错误错误:计算机会认为传入一维数组数组,里面都是整数指针
void display2DArray(int *arr[5], int rows);
int rows = 2, columns = 5;
int** matrix = (int**)malloc(rows * sizeof(int*));
for (int i = 0; i < rows; i++) {
matrix[i] = (int*)malloc(columns * sizeof(int);
}
int rows = 2, columns = 5;
int** matrix = (int**)malloc(rows * sizeof(int*));
matrix[0] = (int*)malloc(rows * columns * sizeof(int));
for (int i = 1; i < rows; i++) {
matrix[i] = matrix[0] + i * columns;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。