c语言指针和数组
c语言中,指针和数组很相似,但是也有些不一样。
1. 声明
int a[10]
:表示声明一个数组。而int *a
则是声明一个指向int类型的指针变量a。
2. 字符数组与字符串常量
char *message = "hello world\n"
声明了一个字符串常量hello world\n
,并用指针message指向字符串的首个字符。
char message[] = "hello world\n"
则声明了一个字符数组。
其中字符数组和字符串常量之间最明显的区别便是常量不可更改,而数组可以更改。
3. 指针和下标
对于数组,想要访问其中的元素,有2中方法:下标引用和指针引用。如对于int a[5] = {1, 2, 3, 4, 5};
访问元素2,a[1]
和*(a + 1)
效果是等价的。但是指针操作有时比下标引用效率更高,因为下标引用编译器需要做一定的计算。
下标还可以是负值。
int *pi = &a[2];
p[-1]
则代表是a[1]
。但是注意a[-1]
是非法的,访问数组头部元素的前一个位置的值是非法的,哪怕仅仅是指针的运算判断也是标准未定义的行为。如:
int a[5] = {1, 3, 5, 7, 9};
int *p = &a[4];
/* 当退出循环时,p = a - 1, 虽然未对p提领,但这种行为时c标准未定义的行为
* 尽量不要使用
*/
while (p >= a){
printf("%d ", *p--);
}
NOTE:1[a]
和a[1]
效果也是一样的,只是很少被使用。
4. 多维数组
多维数组即维数大于1的数组。如int matrix[10][10];
声明了一个10x10的矩阵。
多维数组在内存中的存储方式和一维数组没有区别,都是线性存储的。且多维数组存储是以行主序存储。以int a[4][3];
为例,它在内存中存储顺序是a[0][0], a[0][1], a[0][2], a[1][0], a[1][1], a[1][2]...
所以,可以通过一下方式遍历二维数组:
int a[4][3], *pa = *a;
for (pa = *a; pa < a + 4 * 3; pa++)
...;
一维数组的数组名是一个指针常量,它是指向元素的指针。而二维数组的数组名也差不多,但是指向的时一个数组的指针。如:
int vector[10];
int matrix[10][10];
int *vp = vector; // 声明int *的指针
int (*p)[10] = matrix; // 声明指向包含10个元素的数组的指针
/* 非法的。左值p是指向int *的指针,
* 但右值matrix是指向长度为10的数组的指针
*/
//int **p = matrix;
这种情况在数组名作为函数参数传递时尤其要注意!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端