C语言之数组专题:数组指针、指针数组、数组做函数参数退化、数组名、数组类型
2014-09-01 23:26
537 查看
数组首元素地址与数组地址:数组名a代表元素首地址,&a代表数组地址。
数组首元素地址=数组地址即:a=&a
&a+1代表的是加一个数组长度sizeof(a),a+1代表的是加一个数组元素长度sizeof(a[0])
一维数组名是一个指针常量
二维数组名是一个数组指针,多维数组名也是一个数组指针,是指向一个低维数组的指针
6、多维数组在物理内存中是线性存储的,只是编译器帮我们优化了
数组指针:数组是一个指针,该指针是指向一个数组的指针(数组类型和数组指针的关系)
指针数组:指针是数组元素,也就是数组元素中存储的都是指针
1、定义一个数组类型:用数组定义变量
2、定义一个数组类型,用数组顶一个数组类型的指针
2、指针数组做函数参数退化
指针数组的两种用途
菜单
命令行
指针数组自我结束的三种方法
第一种做法
//C风格字符串是以零结尾的字符串
//操作数组的方法:下标法和指针法
1、数组初始化:
数组元素的个数可以显示或隐式指定int main() { int a[10] = {1,2};//其他没初始化元素,编译器默认帮你初始化为0 int b[] = {1, 2};//编译器隐式指定长度为两个元素 int c[20] = {0}; for (i=0; i<10; i++) { printf("%d ", a[i]); } memset(a, 0, sizeof(a)); getchar(); } |
2、数组名理解难点
int a[10]={1,2}; printf("&a:%d,a:%d\n",&a,a); printf("&a+1:%d,a+1:%d\n", &a+1, a+1); |
数组首元素地址=数组地址即:a=&a
&a+1代表的是加一个数组长度sizeof(a),a+1代表的是加一个数组元素长度sizeof(a[0])
一维数组名是一个指针常量
二维数组名是一个数组指针,多维数组名也是一个数组指针,是指向一个低维数组的指针
char array[10][30]; (array+i) //相当于第i行的首地址 //二级指针 (*(array+i)) //一维数组的首地址 //一级指针 *(array+i)+j //相当于第i行第j列的地址 &array[i][j] *(*(array+i)+j) //相当于第i行第j列的地址 array[i][j] |
2、初学者数组类型三大难题
数组类型数组指针:数组是一个指针,该指针是指向一个数组的指针(数组类型和数组指针的关系)
指针数组:指针是数组元素,也就是数组元素中存储的都是指针
1、 数组类型
C语言中的数组有自己特定的类型,数组的类型由元素类型和数组大小共同决定1、定义一个数组类型:用数组定义变量
void main12() { int i = 0; //定义一个数组类型 typedef int MyArrayType[5]; //int MyArrayType myArray; //int myArray[5]; for (i=0; i<5; i++) { myArray[i] = i +1; } for (i=0; i<5; i++) { printf("%d \n", myArray[i]); } system("pause"); } |
void main13() { int i = 0; typedef int MyArrayType[5]; //定义一个数组类型 MyArrayType *pArray = NULL; //定义了一个数组类型的指针 Int a[5]={0}; pArray = &a; for (i=0; i<5; i++) //我通过数组指针的方式来操作a[5]这块内存 { (*pArray)[i] = i+1; //a[i] = i+1; } for (i=0; i<5; i++) { printf("%d \n", (*pArray)[i]); } system("pause"); } |
2、 数组指针
定义数组指针int i = 0; //这个是定义了一个类型,这个类型是数组类型 typedef int MyArrayType[5]; //int //这个是定义了一个类型,定义了一个指针类型,定义了一个指向数组的指针类型。。。。 typedef int (*MyPArrType)[5] ; //数组指针 MyPArrType myPoint; // int b[5]; myPoint = &b; //变量取地址给指针赋值 for (i=0; i<5; i++) { (*myPoint)[i] = i+1; } for (i=0; i<5; i++) { printf("%d ", (*myPoint)[i]); } system("pause"); } |
1):typedef int MyArrayType[5]; //定义一个数组类型 MyArrayType *pArray = NULL; //定义了一个数组类型的指针 //这个是定义了一个类型,定义了一个指针类型,定义了一个指向数组的指针类型 2):typedef int (*MyPArrType)[5] ; //数组指针 MyPArrType myPoint; //int b[5]; 3):int (*myArrayPoint)[5] ; //告诉编译给我开辟四个字节内存 |
5、指针数组
1、指针数组与数组指针容易混淆Char *p1[] = {“123”,”456”,”789”}; []优先级高,先与p结合成为一个数组,再由char*说明这是一个字符型指针数组 //这是一个指针数组、数组3*4、三个一维数组的首地址存放在以指针作为元素的数组中 Char (*p2)[] = {“123”,”456”,”789”}; //编译器只分配4个字节,是一个指针,编译不通过、错误的方式 |
int printfArray(char *buf [30]); int printfArray(char *buf[]); int printfArray(char **buf); |
菜单
命令行
指针数组自我结束的三种方法
char* c_keyword[] = { "while", "case","static","do",'\0'}; char* c_keyword[] = {"while", "case","static","do",0}; char* c_keyword[] = {"while", "case","static","do",NULL}; |
6、当多维数组当做函数参数的话的时候会退化为指针
退化原因的本质是因为程序员眼中的二维内存,在物理内存上是线性存储 //总结:函数调用的时候,把数组首地址和有效数据长度传给被调用函数才是最正确的做法 |
一维数组做函数参数退化过程 //int a[10] -=-->int a[] ---->int *a //数组做函数形参的时候,如果在形参中定义int a[10]语句, //c/c++编译器会做优化,技术推演如下 //int a[10] -=-->int a[] ---->int *a |
一维数组做函数参数退化过程 char buf[10][30])—》char buf[][30])----》char (*buf)[30]) |
int printfArray(char buf[10][30]); int printfArray(char buf[][30]); int printfArray(char (*buf)[30]); 这三者效果是一样的,也就验证了数组做函数参数退化为指针 |
int printfArray(int a[]) { int i = 0; printf("排序之前\n "); for (i=0; i<10; i++) { printf("%d ", a[i]); } return 0; } |
第二种写法 |
int printfArray04(int *a, int num) { int i = 0; printf("排序之前\n "); for (i=0; i<num; i++) { printf("%d ", a[i]); } return 0; } |
1、 C语言中只会以机械式的值拷贝的方式传递参数(实参把值传给形参) |
int fun(char a[20], size_t b) { printf("%d\t%d",b,sizeof(a)); } |
原因1:高效 |
原因2: C语言处理a 的时候,它没有办法知道n是几,它只知道&a[0]是多少,它的值作为参数传递进去了 虽然c语言可以做到直接int fun(char a[20]),然后函数能得到20这个数字,但是,C没有这么做。 |
2、二维数组参数同样存在退化的问题 |
二维数组可以看做是一维数组 二维数组中的每个元素是一维数组 二维数组参数中第一维的参数可以省略 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]); |
3、等价关系 |
数组参数 等效的指针参数 一维数组 char a[30] 指针 char* 指针数组 char *a[30] 指针的指针 char **a 二维数组 char a[10][30] 数组的指针 char(*a)[30] |
7、数组操作基础以及中括号本质
//c语言里面没有字符串这种类型。通过字符数组来模拟字符串//C风格字符串是以零结尾的字符串
//操作数组的方法:下标法和指针法
void main() { int i = 0; char *p = NULL; //通过字符串初始化字符数组并且追加\0 char buf4[] = "abcd"; for (i=0; i<strlen(buf4); i++) { printf("%c", buf4[i]); //p[] } //[] *的本质到底是什么? //*p 是我们程序员手工的(显示)去利用间接赋值 //[] 只不过是,c/c++编译器帮我们做了一个*p的操作。。。。。。 // buf4[i]======> buf4[0+i] ====> *(buf4+i) //===*(buf4+i) --> bu4[i]; printf("\n"); p = buf4; for (i=0; i<strlen(buf4); i++) { printf("%c", *(p+i)); //*p } system("pause"); } |
void main12() { //字符数组初始化 //指定长度如果定义的长度剩余部分补充0 char buf1[100] = {'a', 'b', 'c'}; //不指定长度 char buf2[] = {'a', 'b', 'c'}; char buf3[] = {'a', 'b', 'c','\0'}; //通过字符串初始化字符数组并且追加\0 char buf4[] = "abcd"; printf("%s\n", buf4 ); printf("sizeof(buf4): %d\n ", sizeof(buf4)); //注意sizeof是对数据类型进行大小测量也就是数组类型包括了\0 printf("strlen(buf4): %d \n", strlen(buf4));//strlen是求字符串的长度不包括\0 system("pause"); } |
相关文章推荐
- C语言之数组专题:数组指针、指针数组、数组做函数参数退化、数组名、数组类型
- C语言中,数组名作为参数传递给函数时,退化为指针
- C语言中,数组名作为参数传递给函数时,退化为指针
- C语言中,数组名作为参数传递给函数时,退化为指针
- C语言 数组做函数参数退化为指针的技术推演
- C语言中,数组名作为参数传递给函数时,退化为指针
- C++基础8【难】 回顾:数组指针,函数指针,函数指针做函数参数 C语言多态
- C语言 数组名作为参数传递 数组名发生退化成指针
- 《IOS_作业C语言》高级指针(结构体指针、结构体数组指针、结构体数组指针,作为函数的参数使用、预编译指令)
- 当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针!
- C语言提高-第23/24/25讲: 指针的运算/数组名作为函数参数/指针作函数参数(一维数组Vs指针)
- 《IOS_C语言》高级指针(结构体指针、结构体数组指针、结构体数组指针,作为函数的参数使用、预编译指令)
- 数组排序及数组做函数参数将会退化为指针
- 数组名作为函数参数时,退化为指针
- C语言--- 高级指针2(结构体指针,数组作为函数参数)
- 数组做函数参数退化为指针
- 数组名作为函数参数,进入函数时退化成指针
- 数组作为函数参数传递时退化为指针(腾讯)
- 排序热身及数组做函数参数退化为指针引申
- C语言学习6 :指针的定义,指针类型要合法,指针要初始化,指针做函数参数,数组和指针的通用性,指针+1所代表的空间,void * 指针,交换函数中的指针,数组和字符型指针区别,字符型指针的应用,使用指针完成字符操作函数