【c语言】带你真正走进指针的世界——那些一不小心就会出现的BUG

                                    Let's              go ~

                                                                                    代码如下

#include <stdio.h>

int main()
{
    int a = 3,b = 3;
   
       (a = 0) && (b = 5);
       printf("a = %d,b = %d\n",a,b);

       (a = 1) || (b = 5);
	    printf("a = %d,b = %d\n",a,b);

    return 0;
}

    注:(1) 逻辑运算符 “&&” 代表的是两边同时为 “ 1 ” 时才输出 “ 真 ” ,任意一边为 “ 0 ” 输出都为 " 假 "。而在编译器里,代码是按照从左到右的顺序编译的,所以当程序编译到“ (a = 0)” 时,即左边结果为 “ 0 ”,所以直接输出 “ 假 ”,不再编译右边的 “(b = 5)”,所以最终结果为: a=0,b=3.

   (2) 逻辑运算符 “||” 代表的是只要两边任意一边的结果为“ 1 ”时,即输出结果“ 真 ”。而在编译器里,代码是按照从左到右的顺序编译的,所以当程序编译到“ (a = 1)” 时,即左边结果为 “ 1 ”,所以直接输出 “ 真 ”,不再编译右边的 “(b = 5)”,所以最终结果为: a=1,b=3.

                                                                                    代码如下

#include <stdio.h>
#include <string.h>
	
int main()
{
     char* str = "I Love You";
	int length = strlen(str);

	for(int i=0;i<length;i++)
	{
		printf("%c",str[i]);
	}

	if(i == length)
		printf("\n");

    return 0;
}

       ???给一个指针赋值一串字符???

       ???打印指针还可以用数组的方式打印出来???

       ???这究竟是神马???

        注:指针和数组有很多相似的地方,其中之一就是:数组的变量名代表的是数组第一个变量的地址(数组的首地址),所以数组名其实也算是一个指针,指向的是第一个数组的地址,而我们平常使用的是数组的常规用法,而例如上面代码所写的用指针来创建一个字符数组是正规用法。

                                                                               代码 如下

#include <stdio.h>
#include <string.h>

int main()
{
	char* x = "china";

	char y[] = "china";

	*(x+1) = 'A';

	y[1] = 'A';
	return 0;
}

       程序虽然没有报错,但是运行就会奔溃,单步调试可以发现,是因为擅自修改不可修改的内存导致的

        在回答问题前我们先了解下内存的结构分区

       由图可知,在内存的分布中,存放常量的区域是 可读不可写  的,意思是“可以读取出去,但是不能写入进来

       然后我们再来看看例子代码的内存分布

       由图上可知,给类型为char* 的变量赋值时,是从变量区直接赋值过来的,而给类型为char 数组赋值时,是从变量区中复制过来的!!!

       注:简单来说,如果把 ‘ A ’ 赋值给char* 和char 类型的话

      *(x + 1) 是直接修改了常量区的数据,结合 图上 “变量区可读不可写” 的原则,将会导致内存擅自读写而程序奔溃。

       y[ 1 ] 是从常量区中把数据复制过来后再进行修改,所以可以正常运行!

猜你喜欢

转载自blog.csdn.net/qq_41884002/article/details/84480687