C语言函数
2024-11-12 19:57:35 0 举报
AI智能生成
C语言的一些常见函数和关键字
作者其他创作
大纲/内容
标准输入输出函数
printf 函数:格式化输出
printf("\033c");//清屏操作
%d用于输出十进制整数,%f用于输出浮点数,%c用于输出单个字符,%s用于输出字符串
scanf 函数:格式化输入
scanf不会自动限制读取输入字符串的长度,如果要读取包含空格的字符串,可以使用fgets函数来代替scanf函数读取字符串,或者可以使用scanf("%[^\n]",&data);数组不需要取值符&。
%d用于读取十进制整数,%f用于读取浮点数,%c用于读取单个字符,%s用于读取字符串
gets 函数:读取字符串(不推荐使用)
gets () 函数曾在 C 语言里广泛用于从标准输入(一般是键盘)读取一行文本(不包含换行符)并存入指定字符数组。但需注意,它已被视作不安全,在很多现代 C 语言环境及标准库中已废弃或移除,原因是其无法防止缓冲区溢出,易引发安全漏洞。
#include<stdio.h>
int main(){
char str[100];
printf("Enter a string:"); // 从键盘上获取字符串,直到\n停止gets(str) ; printf("You entered:%s\n",str);
return 0;} //使用 gets () 函数时,若输入字符串长度超数组 str 大小(如超 100 字符),gets () 会继续读数据至遇换行符,这会导致缓冲区溢出,可能覆盖其他重要内存数据,引发程序崩溃或安全漏洞。
int main(){
char str[100];
printf("Enter a string:"); // 从键盘上获取字符串,直到\n停止gets(str) ; printf("You entered:%s\n",str);
return 0;} //使用 gets () 函数时,若输入字符串长度超数组 str 大小(如超 100 字符),gets () 会继续读数据至遇换行符,这会导致缓冲区溢出,可能覆盖其他重要内存数据,引发程序崩溃或安全漏洞。
puts 函数:输出字符串并换行
#include<stdio.h>
int main(){
char name[]=“张三”; printf("%s\n", name); puts(name); //只适用于字符数组的打印//把字符数组内的字符全部打印在终端上并进行换行 return 0;}
int main(){
char name[]=“张三”; printf("%s\n", name); puts(name); //只适用于字符数组的打印//把字符数组内的字符全部打印在终端上并进行换行 return 0;}
getchar 函数:读取单个字符
#include<stdio.h>
int main()[
char a,b,c; scanf("%c",&a);
getchar(); // 从输入缓冲区获取一个字符,我们知道这个字符就是回车‘\n’ scanf(%c",&b);
printf("a: %c\n", a);
printf("b:%c\n",b);
return 0; } //避免连续两个scanf函数输入是导致第二个函数变成回车‘\n’
int main()[
char a,b,c; scanf("%c",&a);
getchar(); // 从输入缓冲区获取一个字符,我们知道这个字符就是回车‘\n’ scanf(%c",&b);
printf("a: %c\n", a);
printf("b:%c\n",b);
return 0; } //避免连续两个scanf函数输入是导致第二个函数变成回车‘\n’
#include <stdio.h>
int main() {
int c;
while ((c = getchar())!= '\n') {
putchar(c);
}
return 0;
}//运用getcher函数可以输出一行字符串的方法
int main() {
int c;
while ((c = getchar())!= '\n') {
putchar(c);
}
return 0;
}//运用getcher函数可以输出一行字符串的方法
putchar 函数:输出单个字符
int i = 99; // 99是字符'c'的ASCII码
putchar(i);
由于 ASCII 码表中99对应的字符是c,所以这个putchar函数调用会输出字符c。
putchar(i);
由于 ASCII 码表中99对应的字符是c,所以这个putchar函数调用会输出字符c。
putchar 函数只能输出单个字符。不像 puts 函数能自动输出字符串并换行,也不如 printf 函数可通过格式控制输出多种类型数据。若要输出字符串或其他类型数据,得结合别的函数或者用循环来使用 putchar 函数。
字符串处理函数
strcpy 函数:字符串拷贝
#include<string.h> // 函数所需的头文件
char *strcpy(char *dest, const char *src); dest:复制字符数组名
src:被复制的字符数组名//可以是匿名数组
#include<string.h> // 函数所需的头文件
char *strcpy(char *dest, const char *src); dest:复制字符数组名
src:被复制的字符数组名//可以是匿名数组
#include <string.h>
char *strncpy(char*dest,const char *src,size_t n);
dest:复制字符数组名
src:被复制的字符数组名 n :被复制的字符数组的前n个字节
char *strncpy(char*dest,const char *src,size_t n);
dest:复制字符数组名
src:被复制的字符数组名 n :被复制的字符数组的前n个字节
strcmp 函数:字符串比较
strcmp()函数的使用
函数所需的头文件
#include<string.h>
函数的作用
strcmp -compare two strings
函数的原型(声明)1
int strcmp(const char *sl,const char *s2);
s1:比较字符数组1的数组名
s2:比较字符数组2的数组名
函数所需的头文件
#include<string.h>
函数的作用
strcmp -compare two strings
函数的原型(声明)1
int strcmp(const char *sl,const char *s2);
s1:比较字符数组1的数组名
s2:比较字符数组2的数组名
strncmp()函数的使用
#include <string.h>
int strncmp(const char *sl,const char *s2,size t n);
s1:比较字符数组1的数组名
s2:比较字符数组2的数组名
n:前n个字节
函数的执行结果
如果两个字符数组完全一致,则返回0
#include <string.h>
int strncmp(const char *sl,const char *s2,size t n);
s1:比较字符数组1的数组名
s2:比较字符数组2的数组名
n:前n个字节
函数的执行结果
如果两个字符数组完全一致,则返回0
//如果比较的对象是字符串s1和s2,如果s1>s2,结果为1,如果s1==s2,结果为0,如果s1<s2,结果为-1//如果比较的对象是字符数组,结果就是差值
strcat 函数:字符串拼接
#include <stdio.h>
#include <string.h>
int main(){
char dest[20]=“Hello,";char src[]="world!";
strcat(dest, src);printf("%s\n",dest); //输出:Hello, world! // strncat(dest, src, 4);// printf("%s\n",dest); //输出:Hello,worl 加n的区别就是后面拼接字符多少位,两者都要注意dest的空间是否足够 return 0;}
#include <string.h>
int main(){
char dest[20]=“Hello,";char src[]="world!";
strcat(dest, src);printf("%s\n",dest); //输出:Hello, world! // strncat(dest, src, 4);// printf("%s\n",dest); //输出:Hello,worl 加n的区别就是后面拼接字符多少位,两者都要注意dest的空间是否足够 return 0;}
strstr 函数:查找子串
#include <stdio.h>
#include <string.h>
int main(){
char s1[50]= "This is a simple string";char s2[10]="simpla";
// char *s2="simple"; //如果是simple,那么s2在s1中出现了,返回值就是&s1[10]
char *ptr; // 野指针
ptr =strstr(s1,s2); // 这个函数的使用就是在s1中寻找是否有s2 // 由于s2在s1中都没有出现,所以返回值为NULL
if(ptr == NULL)
printf("NULL\n");
else
printf("%s\n", ptr);
return 0;}
#include <string.h>
int main(){
char s1[50]= "This is a simple string";char s2[10]="simpla";
// char *s2="simple"; //如果是simple,那么s2在s1中出现了,返回值就是&s1[10]
char *ptr; // 野指针
ptr =strstr(s1,s2); // 这个函数的使用就是在s1中寻找是否有s2 // 由于s2在s1中都没有出现,所以返回值为NULL
if(ptr == NULL)
printf("NULL\n");
else
printf("%s\n", ptr);
return 0;}
该函数是C语言中用于字符串查找的一个标准库函数,它的作用是在一个字符串中查找另一个字符串的第一次出现,并返回指向该位置的指针。没找到返回NULL。
注意:
1.寻找子字符串,必须要完全一致 2.寻找子字符串,区分大小写
3.只会寻找第一个相同的子字符串,找到后立马结束
1.寻找子字符串,必须要完全一致 2.寻找子字符串,区分大小写
3.只会寻找第一个相同的子字符串,找到后立马结束
strtok 函数:字符串分割
#include <stdio.h>
#include:<string.h>
int main(){
char str[]="Hello,World,How,are,you?";
char p=',';
char *q;
q=strtok(str, &p);// 第-次调用 strtok
while (q != NULL){
printf(“%s\n", q); q= strtok(NULL,&p);}// 后续调用 strtok,传入 NULL
return 0;}
#include:<string.h>
int main(){
char str[]="Hello,World,How,are,you?";
char p=',';
char *q;
q=strtok(str, &p);// 第-次调用 strtok
while (q != NULL){
printf(“%s\n", q); q= strtok(NULL,&p);}// 后续调用 strtok,传入 NULL
return 0;}
分割字符串,空格为分割点
内存管理函数
memset 函数:内存设置
#include <stdio.h>
#include <string.h>
int main(){
char str[10]; // 使用memset函数将str数组的所有元素清零 memset(str,0,sizeof(str)); // 验证str数组的内容是否已经被清零(同上)0可以换其他东西,使其全部变成这个数。 for(int i=0;i< 10;i++){
printf("%d ",str[i]);}
printf("\n");
return 0;}
#include <string.h>
int main(){
char str[10]; // 使用memset函数将str数组的所有元素清零 memset(str,0,sizeof(str)); // 验证str数组的内容是否已经被清零(同上)0可以换其他东西,使其全部变成这个数。 for(int i=0;i< 10;i++){
printf("%d ",str[i]);}
printf("\n");
return 0;}
sizeof函数
是C中的一个操作符,用于获取一个对象或类型所占的内存字节数。
可以用的对象有类型、变量、数组、指针、结构体等。
可以用的对象有类型、变量、数组、指针、结构体等。
strlen函数
是C语言标准库中的一个函数,用于计算给定字符串(以'\0'结尾的字符数组)的长度,但不包括终止的空字符'\0'。 只能用于字符指针(char*)或字符数组,且该数组必须是以'\0'结尾的字符串。
动态内存分配
malloc 函数:分配内存
分配大小
内存对齐
free 函数:释放内存
只需要释放一次,避免重复释放
int*str = (int *)malloc(32); free(str); str =NULL;//释放后要让他变为空指针,不然会变成野指针。
calloc函数:申请内存
int*p = calloc (1000,sizeof(int)); //等于malloc加清空为0的操作
realloc函数:内存扩展
int *p[100]; int*d= realloc(p,1000); \\它会先复制p的内容,然后再申请一个空间为1000大小的空间,然后导入。
其他函数
goto函数
int main()
{
int i = 0;
start: // 标签定义
if (i < 5) {
printf("%d\n", i);
i++;
goto start; // 跳转到标签start处
}
return 0;
}
{
int i = 0;
start: // 标签定义
if (i < 5) {
printf("%d\n", i);
i++;
goto start; // 跳转到标签start处
}
return 0;
}
功能:goto 语句用于实现同一函数内无条件跳转至某个标签处执行。
适用情况:在多层嵌套循环中跳出到特定位置可能有用。
标签定义:是标识符后加冒号,要在函数内部且作用域内唯一。
跳转范围:只能在同一函数内部跳转,不能跨函数。
避免滥用:尽量少用,循环结构和条件语句可提供更清晰、结构化代码。
行为特点:无 “短路” 行为,会无条件跳转,不考虑之前代码是否执行完。
影响:使用 goto 语句可能降低代码的可读性与可维护性,应优先考虑更结构化的控制流语句。
适用情况:在多层嵌套循环中跳出到特定位置可能有用。
标签定义:是标识符后加冒号,要在函数内部且作用域内唯一。
跳转范围:只能在同一函数内部跳转,不能跨函数。
避免滥用:尽量少用,循环结构和条件语句可提供更清晰、结构化代码。
行为特点:无 “短路” 行为,会无条件跳转,不考虑之前代码是否执行完。
影响:使用 goto 语句可能降低代码的可读性与可维护性,应优先考虑更结构化的控制流语句。
bzero函数;数组清空
#include <stdio.h>
#include <string.h>
int main(){
int str[1000]; //假设我们想要将str数组的所有元素清零 bzero(str, sizeof(str)); // 验证str数组的内容是否已经被清零 for(int i=0;i<1000;i++){
printf("%d",str[i]); } //使用unsigned char避免负值输出
printf("\n");
return 0;}
#include <string.h>
int main(){
int str[1000]; //假设我们想要将str数组的所有元素清零 bzero(str, sizeof(str)); // 验证str数组的内容是否已经被清零 for(int i=0;i<1000;i++){
printf("%d",str[i]); } //使用unsigned char避免负值输出
printf("\n");
return 0;}
/*江意事项:
内存分配:
在使用bzero函数之前,确保已经为要清零的内存区域分配了足够的空间,对于局部变量(如数组),这通常不是问题,因为它们的大小在声明时就已经确定了。
然而,对于动态分配的内存(如使用malloc或calloc函数分配的内存,稍后就会讲到),确保在调用bzero之前已经成功分配了内存。
内存分配:
在使用bzero函数之前,确保已经为要清零的内存区域分配了足够的空间,对于局部变量(如数组),这通常不是问题,因为它们的大小在声明时就已经确定了。
然而,对于动态分配的内存(如使用malloc或calloc函数分配的内存,稍后就会讲到),确保在调用bzero之前已经成功分配了内存。
const关键字:只读
const int* ptr; // ptr 指向的内容(即 a 的值)不能被修改
int* const ptr ; // ptr 本身不能被修改,但 ptr 指向的内容(即 a 的值)可以
const int* const ptr = &a; // 既不能修改 ptr 本身,也不能修改 ptr 指向的内容
int* const ptr ; // ptr 本身不能被修改,但 ptr 指向的内容(即 a 的值)可以
const int* const ptr = &a; // 既不能修改 ptr 本身,也不能修改 ptr 指向的内容
const修饰数组和变量时必须初始化,且后面不可再修改
static关键字:修改可见性和生命周期
静态局部变量由 static 修饰局部变量而成,具有以下特点:
生命周期延长:从程序开始执行直至结束,不像普通局部变量在函数调用结束就销毁。
初始化特性:仅在首次进入其定义函数时初始化一次,后续函数多次调用也不再初始化。
作用域情况:作用域依旧限定在定义它的函数内部,外部无法对其进行访问。
生命周期延长:从程序开始执行直至结束,不像普通局部变量在函数调用结束就销毁。
初始化特性:仅在首次进入其定义函数时初始化一次,后续函数多次调用也不再初始化。
作用域情况:作用域依旧限定在定义它的函数内部,外部无法对其进行访问。
rand生成随机数
rand只是一个伪随机; 需要在前面加srand(time(NULL))或者 srand((ubsigbedint)time(NULL))设置随机因子; rand()%100; //使随机数在0~99之间,//在n-m之间就写%(m-n+1)+n;
volatile关键字
volatile 关键字的作用特点:
可见性:被声明为 volatile 的变量每次读取从主内存而非 CPU 缓存进行,保证不同线程对其操作的修改能被其他线程立即看到最新值。
有序性:确保不同线程对 volatile 变量读写操作的顺序不被编译器重排序,避免由此导致的问题。
禁止编译器优化:告诉编译器不对相关代码做优化,特别是不缓存 volatile 变量读写操作到寄存器,防止不正确优化。
volatile 关键字的使用场景:
多线程编程:多线程同时访问修改同一变量时,用 volatile 可避免因未修饰导致的线程间数据不一致问题。
中断服务函数:在嵌入式系统中,中断服务函数修改共享变量时,volatile 能确保修改对其他函数可见,避免因编译器缓存值到寄存器造成的数据不一致。
硬件寄存器访问:在嵌入式系统编程访问硬件寄存器时,用 volatile 修饰可确保每次读取到最新的硬件状态,因为硬件寄存器值可能随时被硬件改变。
可见性:被声明为 volatile 的变量每次读取从主内存而非 CPU 缓存进行,保证不同线程对其操作的修改能被其他线程立即看到最新值。
有序性:确保不同线程对 volatile 变量读写操作的顺序不被编译器重排序,避免由此导致的问题。
禁止编译器优化:告诉编译器不对相关代码做优化,特别是不缓存 volatile 变量读写操作到寄存器,防止不正确优化。
volatile 关键字的使用场景:
多线程编程:多线程同时访问修改同一变量时,用 volatile 可避免因未修饰导致的线程间数据不一致问题。
中断服务函数:在嵌入式系统中,中断服务函数修改共享变量时,volatile 能确保修改对其他函数可见,避免因编译器缓存值到寄存器造成的数据不一致。
硬件寄存器访问:在嵌入式系统编程访问硬件寄存器时,用 volatile 修饰可确保每次读取到最新的硬件状态,因为硬件寄存器值可能随时被硬件改变。
auto自动化变量
#include <stdio.h>
int main()
auto int x= 10;// 显式地使用auto关键字,但实际上是多余的等价: int x=10;
printf("x=%d\n",x)// 下面这个变量也是自动的,即使没有使用auto关键字 int y = 20; printf("y =%d\n",y); return 0;
int main()
auto int x= 10;// 显式地使用auto关键字,但实际上是多余的等价: int x=10;
printf("x=%d\n",x)// 下面这个变量也是自动的,即使没有使用auto关键字 int y = 20; printf("y =%d\n",y); return 0;
// 在这个例子中,x和 y 都是自动变量,因为它们在函数main的局部作用域内被声明。即使为x显式地使用了auto关键字,它也不会改变x的存储类别或生命周期。
// 总结来说,auto关键字在c语言中主要用于声明自动变量,但由于所有局部变量默认都是自动的,因此它在实际编程中很少被显式使用。
// 总结来说,auto关键字在c语言中主要用于声明自动变量,但由于所有局部变量默认都是自动的,因此它在实际编程中很少被显式使用。
register寄存器变量
子主题
0 条评论
下一页