C语言误区
数组
错误示范
int n=5;
int num[n]={1,2,3,4,5};
错误,非法,n是可变的变量,禁止数组在下标为变量 初始化的时候同时赋值。
const int n=5;
int a [n]={1,2,3,4,5};
同样错误,const对编译无影响,n同样是变量,const只影响编译前的检查。
static const int n=5;
int a [n]={1,2,3,4,5};
还是错误,就算是放堆上,他还是变量,
正确做法
int n=5;
int a[n];
for(i =0;i<5;i++)a[i]=i;
或者
int n=5;
int *a=(int *)malloc(sizeof(int)*5);
for(i =0;i<5;i++)a[i]=i;
需要一个一个赋值
指针
指针相关经典的问题:什么是数组的指针,什么是指针的数组,指针和数组是否是相同的?
单指针
int main()
{
volatile int b [5]={0,1,2,3,4};
volatile int *a=b;
printf("%d %d %d %d\n",a,*a++,a,*a);
printf("%d %d %d %d\n",a,++*a,a,*a);
printf("%d %d %d %d\n",a,*++a,a,*a);
printf("%d %d %d %d\n",a,*(a++),a,*a);
printf("%d %d %d %d\n",a,(*a)++,a,*a);
}
运行结果编译器不同,结果不同。
大概说一下:++和*是同一优先级,所以是从右到左
*a++,a先取值a再指向下一个指针。
++*a,a先取值,a指向的值+1
*++a,a先指向下一个指针,再取值
*(a++),同*a++
(*a)++,括号最高优先级,先取值,a指向的值再+1。
一维数组与指针
char (*p)[5];数组指针,指向一个长度为5的char数组
char *n;指针
int b[5]={0,1,2,3,4}; b是数组首元素的指针,&b是指向数组的所在地址
int main()
{
int (*p)[5];
int b[5]={0,1,2,3,4};
p=b;
int *a=b;
printf("%d %d %d %d",sizeof(a),sizeof(b),sizeof(p),sizeof(*p));
}
a的长度是8,存储一个int的变量的地址,类型为指针,指针的为机器字长。
b的长度是20,虽然b的值是数组首元素的地址,但是b的类型是含有五个int的数组。
p的长度是8,因为他是指向具有五个变量的数组的指针,类型是指针。
*p的长度是8,p指向了具有五个变量数组的地址,取值后就是五个变量数组首元素的地址,类型是具有五个变量数组。
有点绕,sizeof()不是函数,而是宏定义,根据参数类型返回值,int就是4,char就是1。指针的移动,比如a++,a–,就是根据指针所指向的类型进行移动。
int *a=(int *)malloc(sizeof(int));
a++;a的值增加了4,因为a指向的值的int型的。
int (*p)[5];
int b[5]={0,1,2,3,4};
p=b;
P++;p的值增加了20,因为p指向的是含有5个int型的数组。
二维数组和一维数组和指针
一维数组的名的值是数组首元素地址的值。
那么二维数组呢?
举例:
char buf[2][2]={{1,2},{3,4}};
buf的值是首元素的指针,buf的元素类型是 char *[2],buf的值就是这个
2*2的数组中第一个含有2个char数组的地址。
buf[0]的值是首元素的指针,buf[0]的元素类型是char,因此buf[0]的值就是
含有2个char数组中第一个元素char的地址。
在内存分配中:
二维数组初始化:
int **a=(int **)malloc(sizeof(int *[2])*2)
for(int i=0;i<2;i++) a[i]=(int *)malloc(sizeof(int)*2);