1.指针的定义
标准定义:在计算机科学中,指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向(points to)存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,将地址形象化的称为“指针”。意思是通过它能找到以它为地址的内存单元。
- 指针就是个变量,用来存放地址,地址唯一标识一块内存空间。
- 指针的大小是固定的4/8个字节(32位平台/64位平台)。
- 指针是有类型,指针的类型决定了指针的±整数的步长,指针解引用操作的时候的权限。
也可以说指针是就是地址,在不同的情况下有不同的叫法“左右值”
在表达式左边时就是指针变量,例如:
int a=10;
int *pc=NULL;//指针变量pc
pc=&a;//指针变量pc
在表达式右边时又可叫指针 , 例如:
int a=10;
int *pc=NULL;//指针变量pc
int *pt=NULL;
pc=&a;//指针变量pc
Pt=PC;//指针pc
指针有什么用?
指针就像房间号一样,就是给内存上给的“房间号”,为了快速方便的访问内存中的内容;
2.指针的使用
1.字符指针
一般使用:
int main()
{
char ch = 'w';
char *pc = &ch;
*pc = 'w';
return 0;
}
char* pstr = “hello world.”; 该表达式的本质是将"hello world."的首字符地址放到了pstr中
面试题:
#include <stdio.h>
int main()
{
char str1[] = "hello world.";
char str2[] = "hello world.";
char *str3 = "hello world.";
char *str4 = "hello world.";
if(str1 ==str2)
printf("str1 and str2 are same\n");
else
printf("str1 and str2 are not same\n");
if(str3 ==str4)
printf("str3 and str4 are same\n");
else
printf("str3 and str4 are not same\n");
return 0;
}
程序的运行结果是:
str1 and str2 are not same
str3 and str4 are same
原因:
str1 和str2 的字符串存放在数组中,数组名代表的是存放字符串
的首 元素的地址,而不同的数组的时候就会开辟出不同的内存块,所
以str1和str2不一样
而str3和str4指向的是一个同一个常量字符串。C/C++会把常量字符
串存储到单独的一个内存区域,当几个指针。指向同一个字符串的时候,
他们实际会指向同一块内存。但是用相同的常量字符串去初始化
2.数组指针(是指针)
指针数组是用来存放数组的指针的
#include <stdio.h>
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,0};
int (*p)[10] = &arr;
return 0;
}
这样可以使用,但是通常我们不这样使用数组指针
通常我们是用数组指针来传参的(数组传参时一定会发生降维问题,降维成指向其内部元素的指针,而二维数组的内部元素是一维数组,所以二维数组传参的时候会降维成指向一维数组的指针,即可使用数组指针来传参)
#include <stdio.h>
#include<windows.h>
void print_arr2(int(*arr)[5], int row, int col)
{
int i = 0 ,j=0;
for (i = 0; i<row; i++)
{
for (j = 0; j<col; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
int main()
{
int arr[3][5] = {1,2,3,4,5,6,7,8,9,10};
print_arr2(arr, 3, 5);
return 0;
}
数组名arr,表示首元素的地址,但是二维数组的首元素是二维数组的第一行,所以这里传递的arr,其实相当于第一行的地址,是一维数组的地址可以用数组指针来接收
############################################################################################################################################################
arr vs &arr
int arr[10];
arr表示的是数组中首元素的地址,而&arr表示的是数组的地址,两者在数值层面上是相同的,但是在进行操作是两者是不同的,例如arr+1与&arr+1的值就是不同的 ,arr+1指的是数组中第二个元素的地址,即加大小时数组中元素的大小,而arr数组的类型为int所以加的就是4,而&arr+1指的是下一个数组的地址,即加的是整个数组的大小,即40。
数组的传参问题
一维数组:
#include <stdio.h>
void test(int arr[])//ok
{}
void test(int arr[10])//ok
{}
void test(int *arr)//ok
{}
int main()
{
int arr[10] = {0};
test(arr);
}
#include <stdio.h>
void test2(int *arr[20])//ok
{}
void test2(int **arr)//ok
{}
int main()
{
int *arr2[20] = {0};
test2(arr2);
}
二维数组
void test(int arr[3][5])//ok
{}
void test(int arr[][5])//ok
{}
void test(int (*arr)[5])//ok
{}
int main()
{
int arr[3][5] = {0};
test(arr);
}
函数指针
函数其实也是用地址的,那么应该怎样查看函数的地址呢?
#include <stdio.h>
void test()
{
printf("hehe\n");
}
int main()
{
printf("%p\n", test);
printf("%p\n", &test);
return 0;
}
只需使用函数名即可查看函数的地址不需要加();
那么函数也有地址,是不是也可以将它的地址用一个变量来保存呢?
是的,那么就存在了函数指针的概念,函数指针就是用来保存函数地址的指针。
void (*pfun1)();
这就是函数指针
指针的概念就回顾完了 ,还有一些笔试题目附链接。
C指针笔试题