数组与指针
1. 数组与指针
1.1 一维数组与指针
例子: int a[] = { 1,2,3,4,5,6,7,8,9 ,0 }; for (int *p = a; p < a + 10; p++) { std::cout << p << ',' << *p << std::endl; }
|
指针格式:int a[10] 退化为指针是指向一个元素的指针,故int *p = a; |
访问数组的方式:p[i], *(p + i); |
1.1 二维数组与指针
例子1: char *s[] = { "cacul","paint","notepad" }; for (char**p = s; p < s + 3; p++) { std::cout << *p << std::endl; }
|
||||||||||||
上述内存模型可解释如下:
数组s中实际存的是每个字符串的地址,所以可以使用二级指针去访问。实际解释如下:
|
||||||||||||
例子2: char *s2[3][10] = { "cacul","paint","notepad" }; for (char**p = s2; p < s2 + 3; p++) { std::cout << *p << std::endl; }
这个例子将无法编译通过,报错如下: a value of type "char *(*)[10]" cannot be used to initialize an entity of type "char **" 说明二级指针和二维数组的指针的类型不同。 |
||||||||||||
结论: 地址相同不等价于类型相同,这里需要一个数组类型的指针 |
||||||||||||
例子3: char s2[3][10] = { "cacul","paint","notepad" }; printf("%p,%d,%d\n%p,%d,%d\n%p,%d\n", s2, sizeof(s2), sizeof(*(&s2)), &s2, sizeof(&s2), sizeof(*(*s2)), *s2, sizeof(*s2));
运行结果: 004AFB84,30,30 004AFB84,4,1 004AFB84,10 |
||||||||||||
结论:地址一样,但类型不一样,&s2整个数组的首地址,s2第一行的首地址,*s2第一个字符的地址。 |
||||||||||||
|
二维数组的遍历:
例子3: int b[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 }; //二维数组的遍历,因为在内存中是线性存储的 for (int *p = &b[0][0]; p < &b[0][0] + 12; p++) { std::cout << *p << std::endl; } |
扩展: 指针的运算 int *p = &b[0][0]; *(p+4); //等于5,实际移动的长度是4*sinzof(type) |
数组作为会退化为指针,即实际穿首地址。 例子: int getSize(int a[3][4]) { printf("%d", sizeof(a)); } int main() { int b[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 }; getSize(b); system("pause"); return 0; }
运行结果:4 |
例子: int getMax(int (*a)[4]) { int tmp = *(*(a + 0) + 0); for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { if (a[i][j] > tmp) { tmp = a[i][j]; //tmp = *(*(a + i) + j); } } } return tmp; } 调用: std::cout << getMax(b) << std::endl; |
工具:
API介绍: HWND *win = FindWindowA("ClassName", "WindowName");//寻找桌面窗口 SetWindowPos(win,坐标,大小)用于设置窗口坐标和大小。 |
1.2 三维数组
例子: int c[3][4][5] = { 0 }; for (int *p = &c[0][0][0], i = 0; p < &c[0][0][0] + 60; p++, i++) { *p = i; } int(*d)[4][5] = c; for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { for (int k = 0; k < 5; k++) { //std::cout << c[i][j][k] << "\t";//这三种都可以 //std::cout << d[i][j][k] << "\t"; std::cout << *(*(*(d+i)+j)+k) << "\t"; } std::cout << std::endl; } std::cout << std::endl << std::endl; }
|
由二维数组一样可以扩展到三维数组,所需指针即为指向一个二维数组的数组指针。 |
|
1.3 总结
N级指针不可用于数组。(会报类型不同的错误) |
定义 指针 访问 int a[10]; int *p = a; p[i]; *p; int b[3][4]; int (*b)[4] = b; b[i][j]; *(*(b + i) + j); int c[3][4][5]; int(*d)[4][5] = c; d[i][j][k]; *(*(*(d+i)+j)+k); |
GCC和VCC编译器的区别: GCC编译: int num = 100; int a[num]; 上述代码可以编译通过。 VCC编译: int num = 100; int a[num]; 不能编译通过,必须为常量,即int a[100]。 这种定义的变量都在栈里面,当定义int a[1024*1024]时会发生栈溢出。 |