【C语言】初阶知识点

EOF的应用

 

        EOF表示end of file,即文件结尾。!=EOF表示没有到达文件结尾,即还有数据资料可以读取,EOF实际ASCII值为-1,即-1==EOF为真,而ASCII的范围为0~127,所以常用while(!=EOF)来表示文件不结束就循环。

        scanf在返回失败时,会返回一个EOF;一般语句正确执行都会返回一个1。

        例子如下:

int main()
{
	int i = 0;
	while (scanf("%d", &i) != EOF)   //可以实现循环输入
	{
		int ret = i & 1;
		if (ret == 1)
			printf("Odd\n");
		else
			printf("Even\n");
	}
	return 0;
}

        另一种实现循环输入的方法是写成while(~scanf("%d",&i))

        因为EOF=-1,则EOF的补码为11111111111111111111111111111111,所以EOF取反后为00000000000000000000000000000000,从而实现结束循环。

打印地址

        %p为十六进制形式的地址  %d为整型数据(十进制)%x为整形数据(十六进制)

        %p和%x的区别就在于%p不会省略数字,而%x可能会把高位的零省去。

        测试代码如下:

#include <stdio.h>
int main()
{
	int a = 9;
	for (int i = 0; i < 3;a++, i++)
	{
		printf("用p直接打印(不取地址):%p\n", a);
		printf("用p打印(取地址):%p\n", &a);
		printf("用x直接打印(不取地址):%x\n", a);
		printf("用x打印(取地址):%x\n", &a);
		printf("用d直接打印(取地址):%d\n", a);
		printf("用d打印(取地址):%d\n\n", &a);
	}
	return 0;
}

得到结果

         可见要打印地址需要满足两个条件:①使用%p ②取地址

输入字符串和输入字符

        ① 首先明确需要用%s来输入字符串,且需要将字符串输入字符数组中,有一下 要注意的点:

        *输入时候对scanf,&arr即可,就获得了数组的地址,写成&arr[100]这样是错误的,变成了取特定下标的地址了

        *输出时候对printf,arr即可,与上同理

        例子如下;

int main()
{
	char a[100];
	scanf("%s", &a);
	printf("%s", a);
	return 0;
}

        ②单个字符输入时候,缓冲区中会出现字符以及\n(字符串结尾),所以当选取单个字符使用时,需要将\n隔离开,否则缓冲区中留下的\n可能会干扰程序运行。

e.g.1
{
	char ch = 0;
	while (~scanf("%c"), &ch)
	{
		if (ch != 'U')
		{
			printf("Vowel\n");
			break;
		}
		else
			printf("Const\n");
        getchar();//getchar相当于进行下一次循环之前把缓冲区域的\n拿掉
	}
	return 0;
}

e.g.2
{
	char ch = 0;
	while (~scanf("%c\n"), &ch)//此处的\n相当于scanf取值时直接把字符ch和\n当成一个整体取走
	{
		if (ch != 'U')
		{
			printf("Vowel\n");
			break;
		}
		else
			printf("Const\n");
	}
	return 0;
}//此法仅限于打字符时候拿走\n,其他不一定管用

e.g.3
{
	char ch = 0;
	while (~scanf(" %c"), &ch)//%c前加空格,会跳过空白字符(\n就是一种空白字符 会被跳过)
	{
		if (ch != 'U')
		{
			printf("Vowel\n");
			break;
		}
		else
			printf("Const\n");
	}
	return 0;
}

gets函数

        gets是一个作用类似于scanf的输入函数。当输入随机长度的字符串时,需要先开辟足够空间的字符数组内存,但是输入的字符串不一定会占满内存,所以输入字符串就要用到gets函数。

        要将一整行字符串输入到字符数组中时,gets函数非常常用。

        注:VS 2019中 gets函数未定义,gets_s(首元素地址,空间长度)可发挥相同作用。

int main()
{
    char a[100] = {0};
    gets(a); //输入Hello!
    printf("%s",a);  //输出Hello!
    return 0;
}

printf的输入

        printf函数的输入是按照传入参数的类型决定的,若是%d就是四个字节,若是%lf就是八个字节,只有long long,double,float(float会被转化成double再传入)是八个字节。

int main()
{
  unsigned char a = 200;
  unsigned char b = 100;
  unsigned char c = 0;
  c = a + b;
  printf(“%d %d”, a+b,c);
  return 0;
}

        输出的结果是300 44,因为printf输入类型为都为%d,所以是四个字节,a是200(<256,200的十六进制是C8,没有越界),b是100(<256,十六进制是64,没有越界),相加得到300。而c的类型是char,a+b得到300超过了两个字节能表示的最大数字256,则十六进制的最高位会被砍掉,剩下了44,所以c本身的值就是44,最后按照整型输出也只有44。

        函数定义size_t strlen( const char *string );输入字符串地址,读取到\0时结束。

        当字符数组初始化为0时,对数组输出的结果为0。如下代码输出结果为0。

int main()
{
	char a[10] = { 0 };
	printf("数组a[10]的字符串长度为%d", strlen(a));
	return 0;
}

        当字符数组不完全初始化时,输出结果为已初始化的数量,如下,得到结果为5.

int main()
{
	char a[10] = { 1,2,3,4,5};
	printf("数组a[10]的字符串长度为%d", strlen(a));
	return 0;
}

        当字符完全初始化,但后面的初始化值为0时如下,结果为5.

int main()
{
	char a[10] = { 1,2,3,4,5,0,0,0,0,0};
	printf("数组a[10]的字符串长度为%d", strlen(a));
	return 0;
}

           下代码输出结果为2.所以对于字符数组而言,存储0相当于存储了\0?

int main()
{
	char a[10] = { 1,2,0,4,5,0,3,0,0,0};
	printf("数组a[10]的字符串长度为%d", strlen(a));
	return 0;
}

        可见strlen对于字符数组是碰到0就停止计数。

双引号表达式

        printf的声明如下:

int printf( const char *format [, argument]... );

        printf()括号中通常为["" ,地址],逻辑大致为传递一个地址,让函数去读取地址中的数据。

        看以下的一种情况:

char * str = "Hello world";
printf(str);
printf("Hello world");

        这里就涉及到了双引号表达式的问题。若引号内是字符串,则双引号表达式的结果是字符串首字符的地址。所以可以在char* str时候后面直接写双引号表达式,同理也可以在printf中直接使用指针str作为参数。

强制类型转换

        显示强制转换:TYPE a = (TYPE) b,如       

int main()
{
    int n = 257;
    char i = (char)n;
    printf("i=%d",i);//输出i=1
    return 0;
}
void check()
{
	int i = 1;
	char* n = (char*)&i;if (*n)
        //相当于if(*(char*)&i)
		printf("小端字节序\n");
	else
		printf("大端字节序\n");
}

        若不进行强制类型转换会报错,int不能直接赋给char,int*也不能直接赋给char*。

        隐式强制转换:

int main
{
    int n = 0;
    double i = 3.88;
    n = i;
    printf("n=%d",n);//输出n=3
    return 0;
}

系统判断为假的情况

Ⅰ:0

Ⅱ:EOF

Ⅲ:NULL

Ⅳ:'\0'

遍历数组时候用的多指针

         有的时候要遍历一个数组,会需要用一个指针储存某个特定的位置,用另一个指针向前遍历。简单说就是对一个数组使用多个指针的情况,目前来说是两个指针比较常见。

        比如说strstr函数,对字符串进行查找时候,若发现不是合适的起始点,就需要回到刚刚使用的起点位置,如果只有一个指针就无法记忆那个位置,对子字符串也是同理。设置一个光标指针和一个位置指针就可以比较清晰的解决问题,图解大致如下。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值