数组、指针数组与数组指针
来源:互联网 发布:什么是淘宝客单价 编辑:程序博客网 时间:2024/06/04 20:07
一、数组类型
注意:
(1)数组首元素的地址与数组地址是完全两个不同的概念
int a[10];printf("a : %d, a + 1 : %d\n", a, a + 1);printf("&a : %d, &a + 1 : %d\n", &a, &a + 1);
输出结果:
(2)数组元素的首地址是常量,不能修改,这是为了释放内存空间所必需的,否则找不到释放内存空间的首地址了
(3)定义一个数组类型
定义数组类型的格式如下:
typedef int(ARRAY)[5];
其中ARRAY便是这个数组类型的名字。
举个例子:
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>#include<string.h>int main(){ typedef int(ARRAY)[5]; ARRAY a; //相当于 int a[5]; for (int i = 0; i < 5; i++) a[i] = i + 1; for (int i = 0; i < 5; i++) printf("a[%d] : %d\n", i, a[i]); system("pause"); return 0;}
输出结果:
二、指针数组
1、指针数组的定义
int *a[5];
a就是一个指针数组
2、指针数组的应用
(1)菜单
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>#include<string.h>//获取菜单中标题的位置下标int getpos(char** mymenu, const char* key, int* pos) { int ret = 0; if (mymenu == NULL || key == NULL || pos == NULL) { ret = 1; printf("func getpos mymenu == NULL || key == NULL || pos == NULL err : %d\n", ret); return ret; } *pos = 0; for (int i = 0; mymenu[i] != NULL; i++) { if (strcmp(key, mymenu[i]) == 0) { *pos = i; return ret; } } return ret;}int main() { int pos = 0; char* mymenu[] = { "while", "for", "do", "switch", "case", 0 }; char key[64] = "do"; getpos(mymenu, key, &pos); printf("pos : %d\n", pos); for (int i = 0; mymenu[i] != NULL; i++) { printf("%s\n", mymenu[i]); } system("pause"); return 0;}
输出结果:
mymenu是个指针数组,传给行参时,可以是char** mymenu,也可以是char* mymenu[],指针数组传参时会退化成指针,这是C语言的强大,不需要知道这个数组里面究竟放了几个元素,可以根据最后一个元素为空,这就需要用到指针数组的自我结束能力,或者传给一个数组大小的参数。
这里牵扯到指针数组的自我结束能力,也就是说程序员在定义指针数组的元素时,把最后一个设为空,那么编译器就能知道到这里就结束了。
比如:
char* mymenu1[] = { "while", "for", "do", "switch", "case", '\0' };char* mymenu2[] = { "while", "for", "do", "switch", "case", 0 };char* mymenu3[] = { "while", "for", "do", "switch", "case", NULL };
这里的三种结束方式都是可以的。
(2)命令行
int main(int argc, char* argv[], char** env) { printf("\n-----------------begin argv-------------------\n"); for (int i = 1; i < argc; i++) { printf("%s\n", argv[i]); } printf("\n-----------------end argv-------------------\n"); printf("\n-----------------begin env-------------------\n"); for (int i = 0; env[i] != NULL; i++) { printf("%s\n", env[i]); } printf("\n-----------------end env-------------------\n"); system("pause"); return 0;}
输出结果(这里是用cmd执行的):
可以看到main函数的参数argv和env实际都是二级指针,argv写成了指针数组的形式而已。
再扩展一下main函数的内存分配,都知道main函数是程序的入口,那么exe程序跑起来,也就是操作系统调用了main函数,那么就有操作系统为main函数分配内存空间,调起来之后再把内存空间的首地址扔给main函数,让main函数继续执行内存的分配释放等各种操作。比如上面菜单的那个例子main函数调用了getpos函数,则由main函数为getpos分配内存空间,也就是说谁调用的谁就去分配内存空间。
所以说在企业的项目开发过程中,不管是使用的MFC框架,QT框架,还是linux内核,程序员只是使用各种api,往里面填参数而已,实际都是框架里把内存分配好了。
三、数组指针
1、数组指针的定义方式
(1)数组类型定义
typedef int(arrayType) [5];int a[3][5];arrayType* myarray = &a;
(2)数组指针类型
typedef int(*pArrayType) [5];int a[3][5];pArrayType pArray = &a;
(3)直接定义
int a[3][5];int (*pArray)[5] = a;
2、多维数组的本质
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>#include<string.h>int print_array(int* array, int n, int m) { int ret = 0; if (array == NULL) { ret = 1; printf("func print_array err : %d\n", ret); return ret; } for (int i = 0; i < n * m; i++) { printf("%d ", array[i]); } printf("\n"); return ret;}int main(){ int a[3][5]; printf("a : %d, a + 1 : %d\n", a, a + 1); printf("&a : %d, &a + 1 : %d\n", &a, &a + 1); int(*pArray)[5] = a; int temp = 1; printf("pArray : %d, pArray + 1 : %d\n", pArray, pArray + 1); for (int i = 0; i < 3; i++) { for (int j = 0; j < 5; j++) { *(*(pArray + i) + j) = temp++; } } print_array((int*)a, 3, 5); system("pause"); return 0;}
输出结果:
可以看到a是二维数组的首元素地址,a + 1跳了一个一位数组的距离,也就是5 * 4 = 20个单位,跟数组指针加1跳的步长是一样的。&a是整个二维数组的首地址,&a + 1跳了5 * 4 * 3 = 60个单位。
二维数组赋给数组指针后,可以通过数组指针改变二维数组的值,先看以前写的一位数组转指针的过程:
a[i] ===》 a[0 + i] ===》 *(a + i)
那么二维数组转数组指针是一个道理
a[i][j] ===》 a[0 + i][j] ===》 *(a + i)[j] ===》 *(a + i)[0 + j] ===》 *(*(a + i) + j)
3、多维数组在内存中的存储
虽然是多维数组,但实际多维数组在内存中还是按照线性存储的,从上面的代码中看出,在print_array函数中的第一个形参是一级指针,利用这个一级指针仍然把二维数组的值给打印出来了。
- 指针数组与数组指针
- 指针数组与数组指针
- 指针数组与数组指针
- 指针数组与数组指针
- 指针数组与数组指针
- 指针数组与数组指针
- 指针数组与数组指针
- 数组指针与指针数组
- 指针数组与数组指针
- 指针数组与数组指针
- 指针数组与数组指针
- 指针数组 与数组指针
- 指针数组与数组指针
- 数组指针与指针数组
- 指针数组与数组指针
- 指针数组与数组指针
- 指针数组与数组指针
- 数组指针与指针数组
- leetcode--011 Container With Most Water
- Handler new Handler()和new Handler(Looper.getMainLooper())的区别
- Python __init__模块
- java9*9乘法
- Linux命令之dos2unix - 将DOS格式文本文件转换成UNIX格式
- 数组、指针数组与数组指针
- 设计模式——状态模式
- js中的delete运算符
- 布局出问题?边框大法好!
- IOS 客户端 socket IPV4兼容IPV6
- hdu 1548 A strange lift
- Spring入门
- OSGI中ServiceTracker的应用
- 红与黑HNCU1103