网易博客转载C学习(1部分)

来源:互联网 发布:java打印等腰杨辉三角 编辑:程序博客网 时间:2024/05/21 11:01
C语言
scanf("%*[^\n]"); 
scanf("%*c");
对输入缓冲区清空,禁止输入非空格,禁止输入字符。
sizeof(int) = 4;sizeof(long int) = 4;sizeof(long long int)=8;sizeof(float)=4;sizeof(double) = 8;
char c1 = 'A';char c2 = 'B';sizeof(c1+c2) = 4; 因为在运算时,两个字符是先转换成int型运算,所以结果为4.sizeof(short+short) = 4.
for(;;); == while(1)
printf("%#X",x);//中间有#时,可以正常输出x值。0X*****
printf("a=%d, a=%d\n", a++, a--);按照编译器的不同,有不同的压栈方式,一般都是先算后面a--,再算前面的a++.
做逻辑运算时,只要前面的 &&  || 可以确定最终结果,将不再执行后面。
int a[2][3];   a[0][3]==a[1][0].
有函数类型的函数如果没有return  返回值一项,那么其会随意返回一个值。
在函数使用前要函数声明,如果没有声明就使用,会存在隐式类型转换,容易出问题。
srand(time(NULL)),只需要在程序中用一次,每次调用rand()产生的随机数就会不一样。
exit()和return在函数中是不一样的,exit()直接终止本应用程序的执行,return是返回到main中继续执行。exit针对进程退出,return针对一个函数的退出。
在编程时,最好养成良好的编程习惯,如从  0开始,先让初始化值为  -1,然后在运算前 +1.
如果有一个数组a,  a[i]=*(a+i)=i[a].
在内存中假设位置是从上到下,从小到大排列,那么低位存低位,高位存高位,且此数据的地址就是最低位,就是分配给它单元的最上面部分。
只要在静态区的数据,不管是全局的还是局部的static,它们的初始值都为 0, 而一旦分配了空间,下次直接使用,不用再分配空间。
在C++中可以对函数进行默认值,此默认值应该在此函数第一次出现的时候指定。
当对字符串输出时,就算字符串中有特殊符号比如%d等,只是将它当作字符串看待。但是当有格式控制符时,比如 \t ,还是会转换格式控制符。puts()自动换行。10.6表示输出的字符串占位10个,但是只输出6个字符。一般格式控制符中,.左边的数表示占多少位,右边的数表示输出多少个要输出的数据。
在函数中不要返回局部变量地址,不然其值会发生改变。因为局部变量在生命周期结束时,其空间释放,此时得到值不能正确得到。
当打印没有以\0结尾的字符串时,可以用格式控制符来控制,如 printf("%.*s\n",10,s2);或者printf("%10.5s\n",s2);
int a[10];int (*p)[10];p=&a;
从命令行输入的都是字符串形式。
const char str[]={"abcdefg"};表示数组中的值不能改变。如果这种形式值没有通过初始化赋值,在后面不能再给它赋值了。
要给char数组分配空间,才能用[0]  [1] strcpy 等。
程序加的注释在预编译的时候不会出现在预编译代码中。
在预编译中,MAXMIN两个写到一起是不行的,"MAX"也是错误的。后面是什么就会原封不动的替换。
#include 是将文件中内在粘贴到此,因此将它此句放到哪里无所谓,但是一般习惯放到程序最前面。
当用strcpy copy到char数组中的数目比实际的要大时,可以是段错误,也可以破坏其它数据。
strcpy后,也会把字符串的 \0 复制过去,因此当将一个字符串 copy 到另外一个时,会改变它的输出。sizeof(一个指向代码区的指针)=4.sizeof(一个字符数组长度).
当返回一个指针时,返回一个指向代码区的指针是可以的。不能返回一个栈区中的数组的数组首地址。
char str[4][20]   char *str[4] :应该尽可能多的用前者,因为后者是指针数组,数组中的任何一个元素都可以随意指向,万一指向代码区,不好修改。在后面一种方式中,不能用strcpy,因为没有分配空间。
写makefile文件时,若改变了某一个源文件,要首先编译这个源文件,然后再make,才可以,不然运行会出错。
生成的目标文件:依赖的文件
一个tab  具体指令
若在一个文件中定义了一个全局变量,则要在头文件中extern int g;就可以在此项目的其它文件中使用它了。
将一个const类型指针赋给非const指针时,会有warning产生,但是仍会运行正确。
//数组本身在栈,字符串本身在代码区
char * ss[3]={"aaa","bbb","ccc"};
#define PRINT(x) printf(#x"=%d\n",x);  1个#表示"  "号中的也要替换。
#define ID(n) id_##n  //此  ##  用在预定义中,则ID(1) id_1   则ID(2) id_2    则ID(3) id_3 
#define GEN_MAX(type) \(\表示换行)
type max_##type(type x,type y)  {return x>y?x:y;}
例子如下:
//不要在传宏参数时传++  -- 之类的表达式,不然可能会得出不正确的结果。
#include <stdio.h>
#include <string.h>
#define PRINTF(x) printf(#x"=%d\n",x);
#define ID(n) id##n
#define GEN_MAX(type) type max_##type(type a,type b){return a>b?a:b;}
int main()
{
  PRINTF(3)
  PRINTF(5)
  printf("%s\n","ID(1)");
  printf("%s\n","ID(3)");
  GEN_MAX(int);
  GEN_MAX(float);
}
#include <stdio.h>
#include <string.h>
#define ARM11
(#undef ARM11)
int main()
{
#ifdef ARM9
printf("ARM9\n");
#elif defined ARM11
printf("ARM11\n");
#elif defined ARM16
printf("ARM16\n");
#endif
}


#include <stdio.h>
//#include <string.h>
//int printf(const char *, ... );
int main()
{
  printf("%s\n",__TIME__);
  printf("%d\n",__LINE__);
  printf("%s\n",__DATE__);
  printf("%d\n",__STDC__);
  printf("%s\n",__FILE__);
}


不同类型函数要赋值给不同类型函数指针,不然会运行错误(尤其是涉及到小数时)。
sizeof(函数名) = 1.
typedef struct Data3{//8
 short s;
 char c;
 int i;
} Data3;   //SSCXIIII
typedef struct Data7{
 short s;
} Data7;//SS   2
typedef struct Data8{
 char str[10];
} Data8; //SSSSSSSSSS
要想验证,可以用指针移动+指针转换方法。
联合体经常用来查看一个指定数的另外一种存放方式。
调用函数时,要做强制类型指针转换, int b[3][4].   int *p; p = (int *)b;
当分配内存空间时,不要更改分配的内存空间的首地址,同一个内存空间也不要释放2次,不然会出现段错误。因为当分配时,内部都维护了一个分配释放标识,不然破坏这种标识,程序会出错。
当对指针进行操作时,如果已经释放了空间,那么要将指向这片空间的指针置为  NULL,防止为悬空指针(悬空指针为此指针指向的空间已经释放,但是此指针仍然指向这些空间)。
#include <stdlib.h> 里面有一个默认的排序算法:void qsort(void *base, size_t nmemb, size_t size,int(*compar)(const void *, const void *));
realloc():重新分配内存,它多分配的内存会保持原先分配的内存中的数据并且将其初值设为 0 。
int * restrict p:表示p是间接寻址,编译时要加上 -std=c99. register int x;(register只是一种请求,并不会真正分配在寄存器中)volatile(易变变量) int y;
当向文件中写入数据时,在指定位置输出会覆盖原来数据。
int a[3][4]={{23,45,11,21},{56,43,22,1},{45,32,14,53}};
  int **pa;
  pa = a;
  pa[0]=1;
此时a[0][0]=1.
scanf("%3d%3d", &x, &y);
scanf("%*d%d",&x);前一个表示禁止输入整数,后面表示输入整数。
scanf("%*[^\n]");scanf("%*c");表示对输入缓冲区清空。
#include <stdarg.h>
va_list v;
va_start(v,n);
va_arg(v,int);每次调用一次此函数,会从va_list中取一次数据。
每一个进程都默认地打开这三个文件
 FILE* stdin;//标准输入设备文件(键盘)
 FILE* stdout;//标准输出设备文件(显示器)
 FILE* stderr;//标准错误输出设备文件(显示器)
stdout和stderr的区别:
1.stdout带缓冲区,sederr不带缓冲区
2.stdout可以重定向,stderr不能重定向
3.什么时候stdout区会清空:
当输出换行时清空 当等待用户输入时清空 当调用fflush函数时清空  当程序运行结束时 缓冲区满时清空
当缓冲区清空时,缓冲区中的内容会送到显示器。
clock() 函数返回进程到此函数执行的时间。 /CLOCKS_PER_SEC表示是运行了多少秒。localtime(). mktime若进行了时间变化,要重新进行转换。
getc  ungetc
从一个文件中获取数字。
int main(int argc,char * argv[])
{
 FILE * fp = fopen("a.txt","r+");
  char c;int cnt = 0;
  while( (c = getc(fp)) != EOF )
  {
 if(isdigit( c )) //is digit
 {
   double f;
   ungetc(c,fp);
   fscanf(fp, "%lf", &f);
   printf("%lf\n",f);
 }
  }
  printf("cnt = %d\n",cnt);
  fclose(fp);
}   
0 0
原创粉丝点击