SOME NOTES OF C LANGUAGE by logcic 77

目录

一:关于头文件等

二:关于数据类,内存等

三:关于循环 

四:关于函数

五:关于数组

六:关于指针

七:关于结构体、

八:关于文件

九:关于预处理

 一:关于头文件等

include<string.h>:      strlen(),strcmp(),strcpy(),strcat(),strstr(),strtok()memcpy(),memmove(),memset()

include<math.h>:      包含着函数sqrt()

include<time.h>,include<stdlib.h>:   可通过时间戳改变伪随机  

include<assert.h>:   包含着函数assert()

include<stdlib.h>:    包含着函数qsort(),atoi(),offsetof (),calloc()malloc()realloc()

include<Stddef.h>:  包含着函数offfsetof()

自定义函数include”name.h”

二:关于数据类,内存等

1:关键字static(静态):相当于全局变量,会保持固定,在函数或循环结束时它的值也会保留

                                    例:static int a=1; ++a;如果循环,不是 2,2,2 而是 2,3,4

2:关键字const(固定):修饰变量,称为常变量,不会被修改,但本质上依然为变量

                                     例:const int*p=&num; const 在*的左边(常量指针),表示指针指向的内容不能改变

                                          int* const p=&num; const 在*的右边(指针常量),表示指针指向的内容可以改变(不能将指针指向其他内容的地址)

3:整数的二进制表达方式

            原码:根据数值写出的二进制序列

            反码:原码的符号位不变,其他位按位取反 ,  0为'+',1为'-'

            补码:反码+1

            注: 内存的存储和计算的是使用的补码,而打印出来的是原码

4:char在vs编译器默认为signed char

   char为字符,   '\0'的ASCII码值为0,且’\0’与0是等价且ASCII是一样的

5:结构与存储方式

      链式结构:一个节点存的是(数据+下一节点地址)

栈区

局部变量,函数形参(使用完就销毁)

堆区

动态开辟的内存:malloc,calloc

静态区

全局变量static修饰的变量

                     栈区内存的使用习惯:先使用高地址空间,再使用低地址空间。

                    大端存储:数据低位放到高地址

                    小端存储:数据高位放到低地址

6:typedef的作用:

      对(关键字+类型名)的组合可以更改名字

      例如:struct  un

                {};

      改为:typedef struct un

               {} un;

      则un就等于struct un

7:

         |——位或 :有一为一

        &——位与:有零为零

        ^——异或:相同为零,相异为一

        a&&b,a=0后,即为假,不会继续计算

        a||b,若a为真则之后的也不会计算
8:逗号表达式从左往右计算,只看最后一个表达式

9:整形提升:

三:关于循环

          1:while(1):表示无限循环,退出条件在循环中出现的break

          2:for(;;i++)循环:continue后会执行i++;但break之后不会

四:关于函数

           1:自定义函数:

                          函数的声明,定义:返回类型+函数名+(函数参数);

                          函数的使用:+语句

  •   2:一些库函数:
                     strlen ( const char * str )不包括“\0”,只能计算字符串长度

  •                   sizeof( 表达式 / 类型说明符)包括“\0”计算内存长度

                  两者差别:sizeof是算符,strlen是函数。

                                    sizeof可以用类型做参数(strlen只能用 char*做参数, 且必须是以''\0''结尾的。)

                                    sizeof还可以用函数做参数,

  •                   int strcmp ( const char * str1, const char * str2 );

                           判断两字符串是否相同:1大于2,返回大于0的数
                                             1小于2,返回小于0的数
                                             1等于2,返回0
  •                   char * strcpy ( char * destination, const char * source );

                            将后一个字符串复制给前一个字符串,同时复制’\0’
                            注:要保证目的地的大小足以接受来源
  •                   char * strcat ( char * destination, const char * source );

                            追加字符串
  •                    const char * strstr(const char * str1, const char * str2 );

                             看前一个字符串是不是后一个字符串的母串
                             返回值为子串开始的地址
  •                    char * strtok ( char * str, const char * delimiters );

                            str要分解的字符串,delim为分隔符字符
  •                    void perror ( const char * str );

                                                  用来打印错误信息原因

                            例如:
fp = fopen("/home/book/test_file","r+");
if (NULL == fp)
perror("fopen error");

打印结果:No such file or  directory
  •                    double sqrt  (double x)

                              用来对x进行开方
  •                     int atoi (const char * str);

                             如果str不能转换成 int 或者 str为空字符串,那么将返回 0 [1特别 注意,atoi输入的字符串对应数字存在大小限制若其过大可                    能报错-1。
  •                     Rand()
                              生成伪随机数

                              Int a=rand()>>srand(unsigned int)time(NULL),a=rand()
                              通过时间戳(当前时间-计算机诞生时间)生成真随机数
  •                     void qsort(void* base,                                      base中存放的是待排序数据中第一个对象的地址

                                  size_t num,                                                 排序数据元素的个数

                                   size_t size,                                               排序数据中一个元素的大小,单位是字节

                                  int (*cmp)(const void*,const void*)        是用来比较待排序数据中的2个元素的函数)

  •                   assert(expression)

                              断言:如果表达式expresion的值是假的(即0),它将首先向标准错误流stderr打印错误信息。
  •                   goto函数

例如: again:     (A)

       Printf……; (B) 

       Goto again; (C) 

       B- C -B -C -B -C- B -C……
  •                    printf函数:返回的是打印字符的个数

例如:prinf(“%d”,printf(“%d”,printf(“%d”,43)))

      打印结果:4321

3:一些内存函数

  •                     void * memmove(void * destination,const void * source, size_t num)

                                       (目的地;来源;拷贝总字节的大小)包括着'\0'
char s[]="Golden Global View";
memmove(s,s+7,strlen(s)+1-7);
printf("%s",s);
getchar();
return 0;
}
程序输出结果:Global View
  •                    void * memcpy ( void * destination, const void * source, size_t num )包括着'\0'

                                      (目的地;来源;字节数) 
                                       从源source所指的内存地址的起始位置开始拷贝n个字节到目标destin所指的内存地址的起始位置中。
  •                      void * memset ( void * ptr, int value, size_t num )包括着'\0'

                                         以字节为单位设置内存
                                         将ptr中当前位置后面的num个字节用 value 替换并返回 ptr 。
  •                                              offsetof (type,member)

                                           结构体各成员 计算偏移量,前为类型,后为成员

注意:函数声明在头文件中,使用在源文件

五:关于数组

1:二维数组的列不能省略                                                                     例如arr[][2]

2:数组名是数组首元素的地址!

                            但是有2个例外:

                            1. sizeof(数组名)——数组名表示整个数组,计算的是整个数组大小,单位是字节

                            2. &数组名——数组名表示整个数组,取出的是整个数组的地址

                                &a+1:取出的是紧接着数组最后一个元素地址的下一个地址。

 3:二维数组传参 :

                              void test(int arr[][5])二维数组传参,函数形参的设计只能省略第一个[]的数字。

                              因为对一个二维数组,可以不知道有多少行、但是必 须知道一行多少元素。这样才方便运算。

4:   使用arr[]=”hello world”等同于arr[]={“hello world”},存放字符串类型时可以省略{}

5:    printf ("%d\n",sizeof(a + 1));

                 解释:

                         a是二维数组的数组名,并没有取地址也没有单独放在sizeof内部,所以a就表示二维数组首元素的地址,即:第一行的地址

                         a +1就是二维数组第二行的地址

六:关于指针

1:指针的加减:

                       指针-指针得到的是两个指针之间的元素个数。即指针-指针为整数,指针-整数为指针。

2:数组指针  取出的是数组地址。

                       例如: int (*parr)[10]=&arr

                                   int(*p)[5]:p是一个指针,指向一个有五个元素的数组,类型为int

3:  指针数组存放指针的数组

                      例如:int*arr[10],存放的是int*的元素

4:例如:解释int(*arr[10])[5]:

                       先把int(*arr[10])视为存放数组指针的数组,相当于10个数组指针(就存在10个数组)指向的每个数组5个元素

5:函数指针 :int(*pf)(int,int)

6:int *p; p=a[0];  则p[0]=*p+0;

                           则cpp【-1】【-1】=*(*(cpp-1)-1),二维数组先加减再解引用

七:关于结构体

1:结构体类型名:

      {

        结构体内容;

       };

                  类型名指的是定义变量的例如:int a中的int

                  则有:struct book b1; struct book b2;

       或者:结构体类型名:

         {

           结构体内容

         }b1,b2;

        注意:可以创造匿名结构体类型:直接创建变量s

        例如:struct{int i;}s;

2:结构体内容也可以是结构体

3:如何自定义结构体内容struct b sb={3.14,{‘w’,100},‘q’}

4:1.结构体的第一个成员放在结构体变量在内存中存储位置的0偏移处开始

      2.从第2个成员往后的所有成员,都放在一个对齐数(成员的大小和默认对齐数的较小值)的整数的整数倍的地址处

      3.结构体的总大小是结构体的所有成员的对齐数中最大的那个对齐数的整数倍。

      4.默认对齐数为8     #pragma pack(8)

5:成员偏移量的计算:例:offsetof(struct s,c1)

6:联合体关键字(union)

           union 类型名

          {

          }变量名;

          联合体特点:内存空间共用;1:大小至少是最大类型的内存大小

                                                         2:当最大成员大小,不是最大对齐数的整数倍的时候,对齐到最大对齐数的整数倍

7:枚举:

           enum类型名

        {

         枚举类型的可能取值(常量)

         用逗号隔开

       }

               所谓定义的变量;则是将可能取值定义为该类型所代表的取值

8:位段(与结构体相似)

                 利用位段能够用较少的位数存储数据

                 位段的成员必须是 int ,unsigned int,signed int

                   位段的成员名后边有一个冒号和数字

例如:

           位段的内存大小开辟是由4个字节4个字节开辟的(32个比特位)

八:关于文件

 
     

 动态内存的三种开辟方式:

                malloc()

         

                calloc(个数,大小)

              例如:calloc(10,sizeof(int))

                 realloc:(地址,新空间的大小):新空间的大小包括原空间   realloc是调整空间大小的,

                                  不能拿原地址来赋值例:p=realloc(p,......)

       

文件:

打开文件:FILE*pf=(文件名(包括文件格式),操作模式r,w)(“test.dat”,”w”)

好习惯:if(NULL==pf)

{

               perror(“”)

               return 1

}

写文件:   例如:char* fgets(字符串/数组,读取个数包括‘\0’,文件)把文件数据读到数组里

关闭文件:fclose(pf)

                   pf=NULL

  1. int fgetc ( FILE * stream );

文件指针stream指向的文件中读取一个字符

char * fgets ( char * str, int num, FILE * stream );

str-- 这是指向一个字符数组的指针,该数组存储了要读取的字符串。

n-- 这是要读取的最大字符数(包括最后的空字符)。通常是使用以 str 传递的数组长度。

stream-- 这是指向 FILE 对象的指针,该 FILE 对象标识了要从中读取字符的流。

  1. int fputc ( int character, FILE * stream );

字符c写到文件指针fp所指向的文件的当前写指针的位置。

int fputs ( const char * str, FILE * stream );

向指定的文件写入一个字符串(不自动写入字符串结束标记符‘\0’)

int fscanf ( FILE * stream, const char * format, [argument...]);

根据数据格式(format),从输入流(stream)中读入数据,存储到argument中,遇到空格和换行时结束。

int fprintf ( FILE * stream, const char * format, (argument) );

)函数根据指定的格式(format),向输出流(stream)写入数据(argument)。 [1-2] 

size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

从file中读count个size大小的数据到ptr中

size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );

从ptr中读count个size大小的数据到file中

int sscanf ( const char * s, const char * format, (argument));

例如:sscanf("123456 ", "%4s", buf);在buf中读取字符串123456中的前四位,结果为1234

int sprintf ( char * str, const char * format, (argument) );

例如:把整数123 打印成一个字符串保存在s 中。

sprintf(s, "%d", 123); //产生"123"

int fseek ( FILE * stream, long int offset, int origin );

例如:fseek(fp,100L,0);把stream指针移动到离文件开头100字节处;

long int ftell ( FILE * stream );

作用为返回指针相对于起始位置的偏移量,偏倚几个字节返回几个字节。

使用fseek函数后再调用函数ftell()就能非常容易地确定文件的当前位置。

void rewind(FILE* stream);

作用为让指针回到起始位置。

九:关于预处理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值