错误分析和纠正

本文聚焦C语言,分析了多个常见错误点。包括二级指针、宏定义替换、野指针、指针与地址混淆等问题,还指出用fscanf给结构体变量赋值时%c抓取空格导致的错误,此外介绍了printf输出字符串时可加修饰的用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

①二级指针错误点

#include <stdio.h>
int main()
{
    int **k,*a,b=100;
    a=&b;
    k=&a;
    printf("%d\n",**k);

    return 0;
}

        分析:此时的**k输出的并不是地址,而是b的值;a取了b的地址,k取了a的地址,那么*k才是b的地址,**k是b的值。 

②宏定义替换

#include<stdio.h>
#include SUB(X,Y)(X+1)*Y
main()
{ 
    int a=3,b=4;
    printf(‘’%d\n‘’,SUB(a++,b++));
}

           分析:(a++ +1)*b++  ,a++和b++都是先参与运算,再自增,所以应该是(3+1)*4=16;

③ 野指针

#include<stdio.h>
fun(int *a,int *b)
{
    int *w;
    *a=*a+*a;
    *w=*a;
    *a=*b;
    *b=*w;
}

int main()
{
    int x=9,y=5,*px=&x,*py=&y;
    fun(px,py);
    printf("%d,%d\n",x,y);

}

       分析:带进去算,你可能会算出5和18,但是!这个*w一开始并没有指向空指针NULL,所以这个*w是个野指针,会出错。

④int *ptr,int k,ptr=k;这种表达是错误的,k是变量,ptr是地址,不能赋值。

⑤指针和地址混淆

void fun(int *p,int *q)
{
	p=p+1;
	*q=*q+1;
}

int main()
{
	int m=1,n=2,*r=&m;
	fun(r,&n);
	printf("%d,%d\n",m,n);
	
	return 0;
 } 

        这里的p=p+1,是指针向后移动了,而不是值加了1,这是易错点。*q=*q+1, *的优先级高,先取*q的值,再加1,所以m=1,n=3;

关于*p++,先取*p的内容,然后是指针p后移,而不是取指针后移的值。

⑦*p=&a[ 0 ] [ 0 ]; ++p,这里*p取的不是数组首地址,所以++p不是行移动,而是第一行元素移动。

错误点:

         用fscanf将文本中的数据赋值给结构体中的变量。其中第三行的fscanf(pf,"%c",&oldn[i].gend)读取不了文本中的字符' m ',这是为什么呢。

        

         使用%c时,出现了错误,这里考虑到是不是%c抓取了一个空格,但我又想到fscanf的功能是从一个流中执行格式化输入,遇到空格和换行时结束,抓取字符' m '的时候,前面的空格应该是不会抓取的,但是这里显示空格确实是被抓取了,要不然字符' m '是不会出现在住址那里的。

         先看一下%c,%c读入一个字符。无法读入空值。空格可以被读入。

        所以情况实际上是这样的。如图:

         在这里%c抓取到了缓冲区的空格,空格后面的字符' m '被后面的%s拿走了。

        另外我发现了printf的一些用法,以前竟然没用到:

        字符串的输出格式符为%s,具体输出的时候,可以加上一些修饰
        例如,如果输出形式为%ms,则按照给定的宽度m输出,若字符串长度小于m,则在左侧用空格补足(右对齐输出);若大于m,则输出全部字符串。除了可以加上整数m进行修饰之外,还可以加上负号(-),或者小数点进行修饰。fprintf也可以用;

    printf("%-10s\t%-10s\t%-10s\t%-10s\t%-10s\n","姓名","电话","性别","住址","年龄");
		for(i=0;i<ps->size;i++)
		{
			printf("%-10s\t%-10s\t%-10s\t%-10s\t%-10s\n",
				ps->data[i].name,
				ps->data[i].tele,
				ps->data[i].gender,
				ps->data[i].addr,
				ps->data[i].age				
			);
		}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值