scanf输入问题-输入缓冲区
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| int main(void) {
char ch; int i=0; int b; b=scanf("%c",&ch); while(b == 1) { printf("%d",i++); printf("?"); b=scanf("%c",&ch);\ } printf("Done\n"); return 0; }
```c a 0?a1?
|
原因是因为scanf()函数会把回车、空格、Tab或一些不合理输入的字符当作此次输入的结束标志,它不会把这些字符输入到想要保存此次输入数据的变量中,而是把这些字符遗留在了输入缓冲区,那么,当下一次想要从标准输入中读取一个字符时,这个遗留的字符就正好充当了此次的输入字符。
程序在输入a后输入了回车来结束此次输入,那么回车就遗留在了输入缓冲区,当需要给c输入字符时,它自动的充当了输入的字符,因此,程序没有给我们输入c的字符的机会。
C语言为了解决这种问题,为我们提供了一种很方便的清空输入缓冲区的方式—->>fflush()函数,fflush(stdin)它会把残留在输入缓冲区里的所有数据清空。头文件为stdio.h
或者使用
1 2
| while ((ch = getchar()) != '\n') continue;
|
C primer plus提供的输入程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| char s_gets(char *st, int n) { char * ret_val; int i = 0; ret_val = fgets( st, n, stdin); if(ret_val) { while(st[i]!= '\n' &&st[i]!= '\0') i++; if(st[i] == '\n') st[i] == '\0'; else while(getchar()!='\n') continue; } return ret_val; }
|
错题:位运算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #include <stdio.h> int fun(int i);
int main() { printf("%d\n",fun(2017)); return 0; }
int fun(int i) { int cnt = 0; while(i) { cnt++; i = i&(i-1); } return cnt; }
|
指针数组
1 2 3 4 5 6 7 8 9 10 11 12 13
| #include <stdio.h> int main() { char *str[3] ={"stra", "strb", "strc"}; char *p =str[0]; int i = 0; while(i < 3) { printf("%s ",p++); i++; } return 0; }
|
char指针数组可以指向多个字符,直到遇到空为止。p本来指向第一个字符,但是因为是指针,所以要遇到空为止才算读完第一个‘字符’,后面p+1指向第二个字符,同样也是遇到空为止,同理p+2 所以输出为stra,tra,ra。注意循环里面是p++所以从p0开始打印啦。
指针和自增自减的优先级
1 2 3 4 5 6 7 8 9 10 11 12
| int arr[] = { 1, 3668, 5, 7, 9}; printf("%d\n", *p++ ); printf("%d\n", *p++ ); printf("%d\n", (*p)++ ); printf("%d\n", (*p)++ );
|
extern关键字
在C语言中,修饰符extern用在变量或者函数的声明前,用来说明“此变量/函数是在别处定义的,要在此处引用”。extern声明不是定义,即不分配存储空间。
extern”C” 作用
C++语言在编译的时候为了解决函数的多态问题,会将函数名和参数联合起来生成一个中间的函数名称,而C语言则不会,因此会造成链接时无法找到对应函数的情况,此时C函数就需要用extern “C”进行链接指定,这告诉编译器,请保持我的名称,不要给我生成用于链接的中间函数名。
1 2 3 4 5 6 7 8 9
| #ifdef __cplusplus extern "C" { #endif
#ifdef __cplusplus } #endif
|
#if…#endif的作用
1 2 3 4 5 6
| #if 1 code 执行代码 #endif #if 0 code 屏蔽代码 #endif
|
同样可以“屏蔽”一段代码,你想把说明文字写在里面也可以,这些和“/* */”都一样,但不一样的是:第一它允许嵌套(层数上限由预处理器决定)、第二你随时可以把“#if 0”改成“#if 1”来取消对某段代码的“屏蔽。
结构体大小
结构体计算遵循对齐原则:
1)结构体变量首地址能够背其最宽基本类型成员的大小所整除;
2)结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有比那一起会在成员之间加上填充字节;
3)结构体的总大小为结构体最宽基本类型成员的大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。
偏移量指的是结构体变量中成员的地址和结构体变量地址的差。结构体大小等于最后一个成员的偏移量加上最后一个成员的大小。
eg:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #include<stdio.h> struct person { char fname; int age; double time; float old; }; int main() { struct person student; printf("%ld", sizeof(student));
return 0; }
|
内存对齐是什么
一文轻松理解内存对齐_程序员_C语言与CPP编程
为什么要用malloc何时用
1
| void *malloc(unsigned int num_bytes); //分配num_bytes字节的内存块
|
返回值是void指针,void* 表示未确定类型的指针,void *可以指向任何类型的数据,更明确的说是指申请内存空间时还不知道用户是用这段空间来存储什么类型的数据(比如是char还是int或者其他数据类型),可以通过类型强制转化转化为其他任意类型指针。如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定),否则返回空指针NULL。
malloc()是动态内存分配函数,用来向系统请求分配内存空间。当无法知道内存具体的位置时,想要绑定真正的内存空间,就要用到malloc()函数。因为malloc只管分配内存空间,并不能对分配的空间进行初始化,所以申请到的内存中的值是随机的,经常会使用memset()进行置0操作后再使用。
与其配套的是free(),当申请到的空间不再使用时,要用free()函数将内存空间释放掉,这样可以提高资源利用率,最重要的是—-就是因为它可以申请内存空间,然后根据需要进行释放,才被称为“动态内存分配”!
1 2 3 4 5 6 7 8 9 10
| int *p; p = (int*)malloc(sizeof(int) * 128); double *pd = (double*)malloc(sizeof(double) * 12); free(p); free(pd); p = NULL; pd = NULL; 指针用完赋值NULL是一个很好的习惯。
|
C语言中的联合
联合是在同一个内存空间中存储不同的数据类型(不能同时存在多个类型)。例如:
1 2 3 4 5 6
| union hold { int digit; double bigf1; char letter; };
|
以上声明的结构只能存储整型或浮点型或者字符型的变量,不能同时存在。
初始化联合
有三种方法初始化联合:
1、把一个联合初始化为另一个同类型的联合
2、初始化联合的第一个成员
3、使用指定初始化器(C99标准)
1 2 3 4 5 6 7
| union car first_car; first_car.car_name='A'; union car sec_car=first_car;
union car car_a={'B'};
union car car_b={.car_num=2};
|
用指针访问联合时候也是用->运算符。
1 2
| pu = &fit; x = pu ->digit;
|
传递结构体数组地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
| #include<stdio.h> #include<string.h> char * s_gets(char * st, int n); void menu(void); #define LIM 20 #define SIZE 81 #define MAXTITL 40 #define MAXAUTL 40 #define MAXBKS 100
struct book { char title [MAXTITL]; char author[MAXAUTL]; float value; }; int srt( struct book prt[], int n); int change(struct book pt[], int m);
int main(void) { struct book library[MAXBKS]; struct book *pst; int i; int t; pst = &library[0]; menu(); for( i = 0; i < MAXBKS; i++ ) { if(s_gets(library[i].title, MAXTITL) == NULL || library[i].title[0] == '\0') break; printf("输入作者\n"); s_gets(library[i].author, MAXAUTL); printf("输入价格\n"); scanf("%f", &library[i].value); printf("输入书名\n"); while(getchar() != '\n') continue; } srt(library, i); for(t = 0; t < i; t++) { printf("书名%s作者%s价格%.2f\n", library[t].title, library[t].author, library[t].value); } change(library, i); for(t = 0; t < i; t++) { printf("书名%s作者%s价格%.2f\n", library[t].title, library[t].author, library[t].value); }
return 0;
} char * s_gets(char * st, int n) { char * ret_val; char * find;
ret_val = fgets(st, n, stdin); if(ret_val) { find = strchr(st, '\n'); if(find) * find = '\0'; else while(getchar() != '\n') continue; } return ret_val;
} void menu(void) { printf("*************************************************************\n"); printf(" please enter the book title and author and value \n"); printf("*************************************************************\n"); printf("输入书名\n"); } int srt( struct book prt[], int n) { int i = 0; int j = 0; struct book quantity; for(i = 0; i < n-1; i++) { int flag = 1; for(j = 0; j < n-1-i; j++ ) { if(prt[j].value > prt[j+1].value) { quantity = prt[j]; prt[j] = prt[j+1]; prt[j+1] = quantity; flag = 0; } } if(flag == 1) break; } } int change(struct book pt[], int m) { int i = 0; int j = 0; struct book letter; for(i = 0; i < m-1; i++) { int flag = 1; for(j = 0; j < m-1-i; j++ ) { if((int)pt[j].title[0]>(int)pt[j+1].title[0]) { letter = pt[j]; pt[j] = pt[j+1]; pt[j+1] = letter; flag = 0; } } if(flag == 1) break; } }
|
union问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #include <stdio.h> union { int i; char a[2]; }*p, u; int main(void) { p = &u; p->a[0] = 0x39; p->a[1] = 0x38; printf("%d", sizeof(u)); printf("%d", p->i); }
|