贡献者: addis
gcc
的 C 语言标准有 -std=c90
,c99
,c11
,c17
,c2x
若要使用 GNU 拓展,也可以用 gnu99
等。
__STDC_VERSION__
可以在程序中判断编译器的 C 标准。例如 199901L
就是 c99
标准,201112L
就是 c11
标准。L
表示 long int
的 literal。打印如 printf("C version: %ld\n", __STDC_VERSION__);
#include "string.h"
char s1[20] = "some string1";
char s2[20] = "some string2";
strlen(s1) // 字符串长度
strcpy(s1, s2) // 复制(s2 可以是 literal)
strcmp(s1, s2) // 比较
strcat(s1, s2) // 连接
strrev(s1) // 反转
#include<stdio.h>
void main()
{
char s[20];
scanf("%s",&s);
printf("%s\n",s);
}
具体的格式代码见这里。
int i = 1234;
printf("=== int ===\n");
printf("%6.5d\n", i); // " 01234"
printf("=== string ===\n");
string s = "abcdABCD";
printf("%s\n", s.c_str()); // "abcdABCD"
double x = 12.345;
printf("=== double 1 ===\n");
printf("%8.3f\n", x); // " 12.345"
printf("%10.3e\n", x); // " 1.235e+01"
printf("%g\n", x); // "12.345"
printf("%5.3g\n", x); // " 12.3"
double y = 0.000012345678;
printf("=== double 2 ===\n");
printf("%g\n", y); // "1.23457e-05"
printf("%10.3g\n", y); // " 1.23e-05"
如果不想输出到命令行而是输出到字符串,就用 int sprintf(char *str, const char *format, ...)
。返回写入的字符数。该函数返回写入到 str
的总字符数。
#include <stdio.h>
int main()
{
int x,y,z;
scanf("%d+\n,\n=%d",&x,&y);
z=x*y;
printf("x=%d,y=%d\n",x,y);
printf("xy=%d\n",z);
}
// 输入:
// 123+
// ,
// =234
// 输出:
// x=123,y=234
// xy=28782
引号内除了特殊字符,其它都需要输入一摸一样的,否则会出错。但是,1.变量前面可以多打任意多个空格和回车(后面不可以),2.任意多个空格或回车相连等效。
#include <stdio.h>
#include <string.h>
void main()
{
int i=1;
char str[5]={0};
while(i<=5)
{str[i]=getchar();i++;}
i=1;
while(i<=5)
{printf("%d ",str[i]);i++;}
printf("\n");
i=1;
while(i<=5)
{printf("%c",str[i]);i++;}
printf("\n");
}
union
和 struct
类似,但变量共用内存
struct 名称 {} // 声明变量: struct 名称 变量
enum 名称 {} // 声明变量: enum 名称 变量
union 名称 {} // 声明变量: union 名称 变量
typedef struct {} 名称 // 声明变量: 名称 变量
typedef enum {} 名称 // 同理
typedef union {} 名称 // 同理
两种定义方式的使用方法并不完全等效(该代码已使用 g++
和 gcc
的不同标准测试)。最简单的记忆方法就是第一种声明在使用时需要加 enum
,第二种声明不用。
enum B {B1, B2};
enum B b1; // GOOD in C++ and c
// B b2; // good in C++, error in c: unknown type name ‘B’
typedef enum B BB; // GOOD in C++ and c
// typedef B BBB; // good in C++, error in c
// ==========================
typedef enum {A1, A2} A;
A a1; // GOOD in C++ and c
// enum A a2; // error in C++ and c
// error: using typedef-name ‘A’ after ‘enum’
typedef A AA; // GOOD in C++ and c
// typedef enum A C; // error in C++, good in c
匿名 structure:
void myfun(struct {int a; double b;} param) {
/*...*/
}
int main() {
struct {
int i;
double d;
} var1{1,1.1}, var2{2,2.2};
myfun(var1);
myfun(var2);
}
注意匿名 structure 只能传给接受同样匿名 structure 的函数,不能给接受实名 structure 的函数,即使函数结构一样。
// 函数指针(每个括号左右都可以有空格)
double(*p1)(double) = sin; // 也可以用 &sin
,下同
// 定义函数指针类
typedef double(*Tpf)(double);
Tpf p3 = sin;
// 定义函数类
typedef double(Tf)(double);
Tf *p2 = sin; // 注意 `Tf my_fun;` 是非法的
// 作为类型参数
vector<double(*)(double)> arr{&sin, cos};
// 调用函数(dereference 可选)
cout << "sin(1) = " << arr[0](1) << endl;
cout << "cos(1) = " << (*arr[1])(1) << endl;
要获取函数指针,既可以用 函数名
也可以用 &函数名
。
见 C 语言文件处理笔记。
void *malloc(size_t size);
分配内存,如果失败返回 NULL
。
void free(void *ptr);
释放内存。
void *realloc(void *ptr, size_t new_size);
会保留之前的数据。如果可以延长内存就延长,如果不能就重新分配并复制。新分配的数据不会初始化。如果失败返回 NULL
。