一、你了解printf()吗?
你知道下面代码的输出结果吗?
objectivec
int a=123;
printf("%2d \n",a);
printf()
函数是 C 语言中用于格式化输出的标准函数,它允许你将数据以特定的格式输出到标准输出设备(通常是屏幕)。printf()
函数定义在 <stdio.h>
头文件中。它的基本语法如下:
objectivec
#include <stdio.h>
int main() {
// 输出字符串
printf("Hello, World!\n");
// 输出整数
int num = 10;
printf("The number is: %d\n", num);
// 输出浮点数
double pi = 3.14159;
printf("Pi is: %.2f\n", pi);//.2指的是保留小数点后两位小数
// 输出字符
char ch = 'A';
printf("The character is: %c\n", ch);
// 输出多个变量
int a = 5;
float b = 2.5;
printf("a = %d, b = %f\n", a, b);
// 输出宽度和精度
printf("Width 5, precision 2: %5.2f\n", pi);//5指的是输出的字符串字宽为五,默认输出结果靠右
// 输出十六进制
int hex = 255;
printf("Hexadecimal: %x\n", hex);
// 输出八进制
int oct = 255;
printf("Octal: %o\n", oct);
// 输出指针
int val = 10;
int *ptr = &val;
printf("Value: %d, Address: %p\n", val, (void*)ptr);
// 输出长整型
long l = 1234567890;
printf("Long integer: %ld\n", l);
// 输出无符号整数
unsigned int u = 4294967295;
printf("Unsigned int: %u\n", u);
// 输出长双精度浮点数
long double ld = 123456789.0123456789L;
printf("Long double: %Lf\n", ld);
return 0;
}
objectivec
Hello, World!
The number is: 10
Pi is: 3.14
The character is: A
a = 5, b = 2.500000
Width 5, precision 2: 3.14
Hexadecimal: ff
Octal: 377
Value: 10, Address: 00F3F8CC
Long integer: 1234567890
Unsigned int: 4294967295
Long double: 123456789.012346
请按任意键继续. . .
对于开始的题目,你是否有自己想法了呢?下面就让我们用一段C程序验证一下吧!
objectivec
#include <stdio.h>
int main() {
int a=123;
printf("%2d \n",a);
return 0;
}
输出结果如下:
objectivec
123
你是不是又有了自己的判断那我再考你一个,如果不确定就自己动手试一下吧!
objectivec
double a=123.123;
printf("%2f\n",a);
二、你知道常量指针吗?
看看下面这个C程序,输出结果是啥?
objectivec
#include <stdio.h>
int main() {
char s[]="asdf";
s+=2;
printf("%d\n",s[0]);
return 0;
}
objectivec
#include <stdio.h>
int main() {
char *s="asdf";
s += 2; // s 现在指向 'd'
printf("%c\n", s[0]); // 打印 'd'
return 0;
}
objectivec
#include <stdio.h>
int main() {
char *s="asdf";
printf("%c\n", s); // 打印 'd'
return 0;
}
三、 认识gets()函数、了解输入流
通过下面的程序我们了解一下啊gets()的用法和字符串流入计算机的方式
objectivec
#include <stdio.h>
int main() {
char a[20],b[]="The sky blue.";
int i;
for(i=0;i<7;i++)
scanf("%c",&b[i]);
gets(a);
printf("%s%s\n",a,b);
return 0;
}
运行程序后我们在键盘上输入fig flower is red.<回车>,程序通过for(i=0;i<7;i++; scanf("%c",&b[i]);b[]就获取到前七个字符"fig flo",新获取的字符将会原字符覆盖掉,通过gets(a),就将剩余部分的数据放入到了a[20]中。
objectivec
fig flower is red.
wer is red.fig flo blue.
请按任意键继续. . .
下面我们来介绍一下get()函数:
gets()
函数是 C 语言标准库中的一个函数,用于从标准输入(通常是键盘)读取一行文本。然而,gets()
函数在 C11 标准中已经被废弃了,因为它是不安全的,容易导致缓冲区溢出的安全问题。
尽管如此,了解 gets()
函数的用法对于学习历史和理解为什么它被废弃是有帮助的。以下是 gets()
函数的基本用法:
函数原型
char *gets(char *str);
参数
str
:指向字符数组的指针,用于存储输入的字符串。
返回值
- 成功时返回
str
指向的字符串。 - 失败时返回
NULL
。
用法示例
objectivec
#include <stdio.h>
int main() {
char buffer[100];
printf("Enter a line of text: ");
gets(buffer); // 读取一行文本
printf("You entered: %s\n", buffer);
return 0;
}
在这个示例中,我们定义了一个字符数组 buffer
来存储用户输入的文本。使用 gets()
函数读取一行文本,并将其存储在 buffer
中。然后,我们打印出用户输入的文本。
安全问题
gets()
函数不检查目标缓冲区的大小,因此如果用户输入的文本超过了缓冲区的大小,就会导致缓冲区溢出,可能会覆盖内存中的其他数据,导致程序崩溃或安全漏洞。
替代方案
由于 gets()
函数的不安全性,推荐使用 fgets()
函数作为替代。fgets()
函数允许指定缓冲区的大小,从而避免缓冲区溢出的问题。
objectivec
#include <stdio.h>
#include <string.h>
int main() {
char buffer[100];
printf("Enter a line of text: ");
fgets(buffer, sizeof(buffer), stdin); // 读取一行文本
// 去除可能读取的换行符
buffer[strcspn(buffer, "\n")] = 0;
printf("You entered: %s\n", buffer);
return 0;
}
objectivec
Enter a line of text: efgortuvhasqtvabn;lr uhgoei3pr ghjupw;aoe9irjufg [o0e3;r4i9ghjvnaw;o0i38er4ghjnva['pw-io94jfr['apiorw490e3ghjnieokrpjgmerpighjeoi8gvhjnfgv/vao;'iw34ift0rwgh4we0r tjug3[-]9tfjuwpr4gihqao9iu hjf9-[4ujfwp'-gtju53igtyhn038wqjfhrm 0[ mfju49 gt0yh58cm [t50y8 g9etcm[0 0cmu c9t ,u,tgyhuh0 r8egotyv89 ghgr oio
You entered: efgortuvhasqtvabn;lr uhgoei3pr ghjupw;aoe9irjufg [o0e3;r4i9ghjvnaw;o0i38er4ghjnva['pw-io94jfr['apio
请按任意键继续. . .
在这个替代示例中,我们使用 fgets()
函数读取一行文本,并指定缓冲区的大小。这样可以确保不会超出缓冲区的范围,从而提高程序的安全性。
总之,虽然了解 gets()
函数的用法是有益的,但在实际编程中应该避免使用它,而是使用更安全的 fgets()
函数。
四、静态变量?
大家看一看下面这一行程序,有没有觉得运行结果应该是4,7,10,13,的,有没有怀疑过自己的静态变量的知识点记错了。
这里一定要看清n=0;这一个语句。
objectivec
#include <stdio.h>
int a=2;
int f(int m){
static int n;
n=0;
n++;
a++;
return n+m+a;
}
int main() {
int k;
for(k=0;k<4;k++)
printf("%d,",f(k));
return 0;
}
objectivec
4,6,8,10,请按任意键继续. . .
在C语言中,静态变量(static
variable)是一种特殊的变量存储类别,它具有持久的存储期,这意味着静态变量的值在函数调用之间是持久的。静态变量的用途和特性如下:
- 持久性
静态变量在程序的整个运行期间都存在,它们的值在函数调用之间不会消失。这与自动变量(如局部变量)不同,后者在函数调用结束后其值会丢失。
- 初始化
静态变量在程序开始运行时初始化一次,如果未显式初始化,则默认为0。一旦初始化,它们的值在后续的函数调用中会保留,除非显式地修改它们。
- 作用域
静态变量的作用域通常与定义它们的函数或文件相同。如果静态变量在函数内部定义,则它只能在该函数内部访问。如果它在函数外部定义,则在整个文件中都可以访问。
- 链接性
静态变量的链接性可以是内部的(static
关键字)或外部的(默认)。具有内部链接性的静态变量只能在定义它们的文件中访问,而具有外部链接性的静态变量可以在其他文件中通过声明为 extern
来访问。
- 使用场景
- 函数内部:在函数内部定义静态变量通常用于跟踪函数调用的次数或维持函数的状态。
- 全局变量 :作为全局变量定义时,它们在整个程序中是可见的,但只能在定义它们的文件中访问,除非通过
extern
关键字在其他文件中声明。
示例代码
objectivec
#include <stdio.h>
void count_calls() {
static int count = 0; // 静态变量,用于计数函数调用次数
printf("This function has been called %d times.\n", ++count);
}
int main() {
count_calls(); // 输出: This function has been called 1 times.
count_calls(); // 输出: This function has been called 2 times.
count_calls(); // 输出: This function has been called 3 times.
return 0;
}
objectivec
This function has been called 1 times.
This function has been called 2 times.
This function has been called 3 times.
请按任意键继续. . .
在这个例子中,count_calls
函数中的 count
变量是一个静态变量,它用于跟踪函数被调用的次数。每次调用函数时,count
的值都会增加,并且其值在函数调用之间保持不变。
五、你真的认识赋值符号"="吗?
objectivec
int a,b,c=4;
a=(b=4)=c;
a=(b=4)=c;这个赋值语句是非法的,不能将常量赋给常量,也就是说等号左边必须是变量才能赋值