指针和数组并非相等的,ios
当声明一个数组时,它同时也分配了一写内存空间,用于存储数组元素,c++
但当声明一个指针时,它只分配了用于容纳指针的空间(32位中4个字节的大小)。程序员
如:面试
站在c++编译器的角度, *p 至关于咱们程序员手工(显示)利用间接赋值,去操做内存编程
"[]"是c++编译器帮咱们程序员作了一个*p的操做数组
当一个数组名做为函数参数时,数组名的值就是指向数组第一个元素的指针,因此此时传递给函数的是指针的拷贝。函数
#include <iostream.h> int sum ( int ap[ ] , int n ) { int m = 0 ; for ( int i = 0 ; i < n ; i ++ ) { m += * ap ; ap ++ ; } return m; } void main() { int a [ 10 ] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } ; cout << "sum = " << sum ( a , 10 ) << endl ; }
int sum(int ap[], int n) 和int sum(int *ap, int n)效果同样的spa
二维数组名一样表明数组首元素的地址指针
//int b[2][5]===>b的类型为int(*)[5]不是char**code
多维数组名的本质:数组指针即
指向一个数组的指针
int a[3][5]
(a+i) 表明是整个第i行的地址
*(a+i)就表示
第i行首元素的地址
*(a+i) + j ===> & a[i][j]
*( *(a+i) + j) ===>a[i][j]元素的值
一级指针作函数参数:
二维数组能够看作是一维数组
二维数组中的每一个元素是一维数组
二维数组参数中第一维的参数能够省略
void f(int a[5]) ====》void f(int a[]); ===》 void f(int* a);
void g(int a[3][3])====》 void g(int a[][3]); ====》 void g(int (*a)[3]);
实参 ( 数组参数 ) | 所匹配的形参(等效指针参数) |
一维数组 char a[30] | 指针 char* (可直接char* p=a;下面的相似) |
指针数组 char *a[30] | 指针的指针 char **a 指针的指针([30]数组作函数参数退化为指针 , 何况又是个指针数组因此**) |
二维数组 char a[10][30] | 数组的指针 char(*a)[30](数组指针 |
数组指针(行指针)char(*c)[10] | char(*c)[10] 不改变 |
指针的指针 char**c(二重指针) | char**c 不改变 |
int printfArr23_1(char myArray[10][30], int iNum) { int i = 0; for (i=0; i<iNum; i++) { printf("%s \n", myArray[i]); } return 0; } int printf2Array_2(char myArray[][30], int iNum) { int i = 0; for (i=0; i<iNum; i++) { printf("%s \n", myArray[i]); } return 0; } int printf2Array_3(char (*myArray)[30],int iNum) { int i = 0; for (i=0; i<iNum; i++) { printf("%s \n", myArray[i]); } return 0; } void main() { int i = 0; char myArray[10][30] = {"ccccc", "aaaa", "bbbb","11111"}; // printf2Array_2(myArray, 4); printf2Array_3(myArray, 4); system("pause"); }
多维数组名本质就是一个数组指针
二重指针的用法
(1)二重指针指向一重指针的地址
(2)二重指针指向指针数组的
(3)实践编程中二重指针用的比较少,大部分时候就是和指针数组纠结起来用的。
(4)实践编程中有时在函数传参时为了经过函数内部改变外部的一个指针变量,会传这个指针变量的地址(也就是二重指针)进去。
int main() { char* str[] = {"abcde","aqw","ulk"}; char **str1 = str;// { "abcde", "aqw", "ulk" };不能够直接定义 **str1 = { "abcde", "aqw", "ulk" };指针数组指针 cout << "sizeof(str)" << sizeof(str) << endl; cout << "sizeof(str[1])" << sizeof(str[1]) << endl; cout << "sizeof(str[0])" << sizeof(str[0]) << endl; for (int i = 0; i < sizeof(str) / sizeof(str[0]);i++) { printf("%s\n", str1[i]); }system("pause"); return 0; }
华为的面试题:
如有函数声明voidf(char** p),则使得函数调用f(var)不正确的var定义是———?
A char var[10][10]; B char *var[10]
C void* var=NULL; D char* v=NULL,**var=&v;
解析:
1.char var[10][10];var的类型是 char (*)[10] 类型(不理解的话须要好好看看课本)
2.char *var[10]; var数组是存放char *类型的数组,数组名var是数组var元素的首地址,因此var的
类型是char**类型
3.void * 是定义没有指针类型的指针,void *能够指向任何类型的数据。在c99中举个例子int *p = malloc(sizeof(int)); 能够不写强制类型转换,由于malloc返回一个void *类型的指针,
char**p = malloc(100); 这样定义同样能够经过
4.v是char*类型的,那么取v的地址确定是char**类型的,因此var是char**类型的。
结构体变量做为函数形参的时候,实际上和普通变量(相似于int之类的)传参时表现同样的。因此说结构体变量其实也是普通变量。
用结构体变量做实参时,采起的是“值传递”的方式