C语言之数组专题:数组指针、指针数组、数组做函数参数退化、数组名、数组类型
来源:互联网 发布:科盟网络 编辑:程序博客网 时间:2024/05/16 07:33
转自:http://blog.csdn.net/wu5215080/article/details/38989381
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=&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]
6、多维数组在物理内存中是线性存储的,只是编译器帮我们优化了
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");
}
2、定义一个数组类型,用数组顶一个数组类型的指针
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个字节,是一个指针,编译不通过、错误的方式
2、指针数组做函数参数退化
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]的时候,它没有办法知道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/CPP点滴积累—数组做函数参数退化为指针
- 指针数组做参数
- 数组名降级 数组退化为指针 问题
- C语言中,数组名作为参数传递给函数时,退化为指针
- sizeof进行字符串、结构体大小的判断
- 开发应用的一般流程(个人)
- UI优化技巧:使用ViewStub
- 在制作水晶报表时遇到此错误未处理System.IO.FileNotFoundException HResult=-2147024894
- CAP理论十二年回顾:"规则"变了
- C语言之数组专题:数组指针、指针数组、数组做函数参数退化、数组名、数组类型
- Java学习笔记---设计模式之抽象工厂模式
- 字符流的文件读取
- 【Node.js基础篇】(十)使用net模块和Readline模块实现Socket通信
- Ubuntu 基础操作
- iOS之OC随笔-九宫格的算法简单实现
- 当模板函数遇上数组参数
- ASP.NET运行时报 对象名 'users' 无效 错误信息
- 收获