C学习笔记
- 在 printf 中打印 十进制、八进制、十六进制
int num = 100;
printf("Oct = %o", num); // 八进制 144
printf("Hex = %x", num); // 十六进制 64
printf("Oct = %#o", num); // 八进制 以0开头 0144
printf("Hex = %#x", num); // 十六进制 以0x开头 0x64
// unsigned int 格式化输出用 %u
// short 格式化输出用 %hd / %d, 因为会在内部吧short提升为int
// long 格式化输出用 %ld
// long long 格式化输出用 %lld
// float double 格式化输出用 %f, 用指数形式表示 %e
// 字符串类型 %s
// 字符类型 %c
2. C 里面的字符数组
char name[50];
scanf ( ) 读取输入,在遇到第一个空格、制表符tab、换行符处停止读取。而不是读取整个语句
char name[40];
printf("enter your name: ");
scanf("%s", name); // wang hanjian
printf("%s", name); // wnag
-
C 中的 strlen ( ) 函数:返回字符串长度。
char name[40] = "wang"; // 40 sizeof(name) 变量 name 占据的内存大小 // 4 strlen(name) 字符串 name 的长度 printf("%d, %d", sizeof(name), strlen(name));
-
预处理 #define
// 宏 都用大写 #define PRAISE "WANG HAN JIAN!"
-
当 printf ( ) 一行写不完时:
- 分多个 printf() 打印;
- 在末尾用 \ 拼接;
- 每行用 “ ” 括起来;
- 返回值:打印字符串的长度(注意结尾的\0 +1)
-
scanf ( )
-
读结束标志:
- 从首个不是空白字符开始读,到遇到第一个空白字符
- 指定读取的字符数
%10c
-
当想把输入存入某个基本变量类型时,需要加个 & 取地址
-
若是存进字符串 (字符数组) 时,则不需要加 &
-
返回值:读入项目的个数
-
sizeof()
-
C 规定 sizeof 返回 size_t 类型的值,它是一个无符号整型。
typedef unsigned int size_t
-
-
字符数组与字符串
注:字符串末尾有 \0
-
缓冲区 buffer
-
文件结尾
-
计算机操作系统需要某种方式来判定每个文件起始和结束的位置。检测文件结尾:
一种方式是在文件中放置一个特殊的字符来标志结尾。
另一种方式是获取文件大小信息,读到满足大小信息,判定达到文件尾。
-
C的处理方法是让 getchar() 函数在达到文件结尾时返回一个特殊值 EOF(end of file)。
#define EOF (-1)
-
-
指针
-
指针加 1 的结果是对该指针增加 1 个 存储单元,向后移一个存储单元的指向
// 四种等价的函数声明 int sum(int *ar, int n); int sum(int *, int n); int sum(int ar[], int n); int sum(int [], int); arr[i] == *(arr + i)
-
指针的唯一算术运算就是以整数值大小增加或减少指针值。如
p+1
、p-2
等 -
*const int p : 不可以修改指针指向对象的值
-
int * const p : 不可以修改指针的指向
-
const int * const p : 指针的指向 与 指针指向的对象都不可以修改
-
数组名是不可以自增加的A++,数组名是定死在数组首元素地址,其指向不能被改变,所以它是一个不可改变的指针常量
-
-
内存四区
- 堆区(heap):一般由程序员手动申请与释放;
- 栈区(stack):由编译器自动分配释放,形参、局部变量等,函数执行完毕自动释放;
- 全局区(globe):用于存放全局变量和静态变量,里面细分有个常量区,一些常量存放于此。该区域程序结束后由操作系统释放;
- 代码区(code):用于存放程序代码,字符串常量也存放于此。
取地址:&A[i] or (A+i) 取值: A[i] or *(A+i)
-
输入输出函数
-
gets () 读键盘输入
不足:不检查目标数组是否能够容纳输入,会存在溢出的可能。
char name[51]; char* ptr; printf("what's your name? \n"); ptr = gets(name); // whj printf("%s == %s", name, ptr); // whj == whj
-
fgets () 读文件I/O
不足:fgets()会把换行符存储到字符串里。
char name[51]; char* ptr; printf("what's your name? \n"); ptr = fgets(name, 51, stdin); printf("%s == %s.", name, ptr);
-
puts ()
#define DEF "I'am a #define string" char str1[81] = "An array was initialized."; const char* str2 = "A pointer was initialized."; puts("I'am a argument to puts()."); // 双引号中的字符串常量被看作为地址 puts(DEF); puts(str1); puts(str2); puts(&str1[3]); puts(str2 + 4);
-
puts()是为了和gets()一起使用而设计的
fputs()是为了和fgets()一起使用而设计的
-
-
字符串函数
-
strlen() 函数
得到字符串长度。不包含结尾
\0
-
strcat() 函数
拼接字符串,将第二个字符串拷贝份添加到第一个字符串的结尾。
-
strncat() 函数
strcat() 函数的变种
参数三:指明最多允许添加的字符数目
-
strcmp() 函数
比较两个字符串是否相同,相同返回0,不相同返回1 / -1。
优点: 比较的是字符串,而不是数组地址
-
strncmp() 函数
strcmp() 函数的变种,可以比较两个字符串前n个字符是否相同
-
strcpy() 函数
将参数二的字符串拷贝给参数一。
返回值:是第一个参数
-
strncpy() 函数
strcpy() 函数的变种,将指定长度的字符串复制到字符数组中。
参数三:指明最大的可复制的字符数
-
sprintf() 函数
sprintf() 与 printf() 函数功能基本一致,只是它把结果输出到指定的字符串中。
char str[40]; sprintf(str, "%s %d %d", "Test", 1, 2); printf("%s", str); // Test 1 2
-
-
字符转转换为整型
-
atoi()、atol()、atof() 函数
int、long、double
// 需要包含头文件 #include <stdlib.h> atoi("1234"); // 1234 // 以整数开头 atoi("123abc"); // 123 // 不是数字开头 atoi("a123456"); // 0 double n = atol("1234567"); // 1234567.000000
-
-
C语言中的存储模型 / 存储类
-
存储模型
-
存储时期(storage duration)
就是变量在内存中保留的存储时间
-
作用域(scope)
. 链接(linkage)
变量的作用域和链接一起表明程序的哪些部分可以通过变量名来使用改变量
-
-
存储类
-
自动存储类
-
寄存器存储类
// 寄存器变量: 请求变为寄存器变量CPU里,可能编译器不会同意。 // 不能使用地址运算符 register int quick;
-
具有代码块作用域的静态存储类
// 静态变量: 默认初始化为 0 static int quick;
-
具有外部链接的静态存储类
// extern 把变量的声明放在所有函数之外,创建一个外部变量。 // 如果是在别的文件中定义,那就使用 extern 关键字再次声明使用它。注意:关键字extern的存在标志着这是一个引用声明而非定义声明 extern int Errupt; extern int Errupt = 10; /* 错误 */
-
具有内部链接的静态存储类
-
-
存储类说明符
auto、register、static、extern、typedef
-
-
malloc() 、free() 与 exit()
```c
#include <stdlib>
double* ptr = (double*)malloc(n * sizeof(double)); // 申请动态内存
if(ptr == NULL)
{
exit(EXIT_FAILURE);
}
free(ptr); // 手动释放
```
-
volatile 限定词
限定词volatile告诉编译器该变量除了可被程序改变以外还可被其他代理改变,他被用于硬件与其他并行运行的程序共享的数据。
volatile int loc; // loc是一个易变的位置 volatile int * ptr; // ptr指向一个易变的位置
-
restrict 限定词
通过允许编译器优化某几种代码增强计算支持。他只可用于指针。