数组做函数参数的退回问题
当数组做函数形参时,数组会退回为一个指针变量
下面用一个例子给出一个简单的证明
void sortArray(int a[], int num)
{
int i, j, tmp;
int num2 = 0;
num2 = sizeof(a)/sizeof(a[0]);
printf("num2:%d \n", num2);
/*这里的num2输出结果为1,因为将a当成指针处理
32为编译器下指针为4个字节,int也为4个字节,结果为1
实参的a 和 形参的a 的数据类型本质不一样
形参中的数组 ,编译器会把它当成指针处理 这是C语言的特色*/
for(i=0; i<num; i++)
{
for (j=i+1; j<num; j++)
{
if (a[i] > a[j])
{
tmp = a[i];
a[i]= a[j];
a[j] = tmp;
}
}
}
}
void main()
{
int i = 0,j = 0;
int tmp = 0;
int num = 0;
int a[] = {33,654,4,455,6,33,4,3333};
num = sizeof(a)/sizeof(a[0]);
printf("num:%d \n", num); //输出结果为8,说明此时实参a为数组结构
sortArray(a, num);
}
数据类型本质分析
数据类型的本质是固定内存大小的别名
1、数据类型的大小
使用sizeof求解数据类型的大小(sizeof不是函数,是操作符)
例:有关数组的数据类型大小
int a; //告诉c编译器分配4个字节的内存
int b[10] ; //告诉c编译器分配40个自己内存
printf("b:%d, b+1:%d, &b:%d, &b+1:%d \n", b, b+1, &b, &b+1);
//输出结果为b:6618656 b+1:6618660 &b:6618656 &b+1:6618696
//b+1 &b+1 结果不一样
//b &b所代表的数据类型不一样
//b 代表的数组首元素的地址
//&b代表的是整个数组的地址
//因此b+1移动了4个字节,&b+1移动了40个字节
printf("sizeof(b):%d \n", sizeof(b)); //输出40
printf("sizeof(a):%d \n ", sizeof(a)); //输出4
2、数据类型的命名
所有数据类型都可以通过typedef进行重命名
typedef struct Teacher
{
char name[64];
int age;
}Teacher;
//可以使用Teacher代替struct Teacher
//c++中已经做了优化,无需重定义
3、数据类型的封装
在实际开发中,通常使用void* 来对数据类型进行封装
void * 可以指向任何类型的数据,经常用于数据类型的封装,如典型的memset函数原型为
void * memcpy(void *dest, const void *src, size_t len)C语言规定只有相同类型的指针才可以相互赋值
void* 指针作为左值用于“接收”任意类型的指针void* 指针作为右值赋值给其它指针时需要强制类型转换(malloc函数返回为void* )这就解释了为什么使用
malloc函数时要进行强制类型转换,如
char * p2 = (char *)malloc(sizoeof(char)*20)