C语言常见误区——个人总结

本文探讨了C语言中数组和指针的常见误区,包括使用变量作为数组大小的非法性,const关键字对数组初始化的影响,以及指针操作如++和*的优先级问题。还解释了一维数组、指针和二维数组之间的区别,以及sizeof运算符在不同类型变量上的应用。通过示例代码展示了指针移动和内存分配的方式,特别是涉及动态内存分配的二维数组初始化方法。
摘要由CSDN通过智能技术生成

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];数组指针,指向一个长度为5char数组
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指向的是含有5int型的数组。

二维数组和一维数组和指针

一维数组的名的值是数组首元素地址的值。
那么二维数组呢?
举例:

char buf[2][2]={{1,2},{3,4}};
buf的值是首元素的指针,buf的元素类型是 char *[2],buf的值就是这个
2*2的数组中第一个含有2char数组的地址。
buf[0]的值是首元素的指针,buf[0]的元素类型是char,因此buf[0]的值就是
含有2char数组中第一个元素char的地址。

在内存分配中:

二维数组初始化:
int **a=(int **)malloc(sizeof(int *[2])*2)
for(int i=0;i<2;i++) a[i]=(int *)malloc(sizeof(int)*2);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值