C语言速成篇

来源:互联网 发布:安徽快三遗漏数据查询 编辑:程序博客网 时间:2024/05/29 07:03

本人最近学习ndk,涉及到C语言,所以写下这篇略显肤浅的笔记……大神请忽略此文……

一、HelloWorld

#include <stdio.h>   // 包含标准的输入输出的头文件, 类似java的导包#include <stdlib.h>  // 包含标准的库函数main() {    // 入口函数       printf("hello World\n");        system("pause");   // 调用系统命令,暂停程序,以便查看运行结果 }

二、数据类型

C语言的数据类型包括基本数据类型、构造类型、指针类型、空类型。其中基本数据类型包括数值类型和字符类型。数值类型又包括整型和浮点类型。基本数据类型如下:

  • char 1字节
  • short 2字节
  • int 4字节
  • float 4字节
  • long 4字节
  • double 8字节

有几个注意事项:

  • C语言中没有byte, 可以用char表示
  • C语言中没有String类型,可以用字符数组或char类型的指针
  • C语言中没有boolean, 可以用整数0表示false, 1表示true
  • signed和unsigned: 数据类型修饰符,用来修饰char, short, int, long 如signed int
  • signed int简称int,signed short简称short,signed long简称long。注意signed char不等于char,这是两种类型了。

    main() {      long long ago;  // sizeof获取某个数据类型的长度  printf("char的长度为:%d\n", sizeof(char));  printf("short的长度为:%d\n", sizeof(short));  printf("int的长度为:%d\n", sizeof(int));  printf("float的长度为:%d\n", sizeof(float));  printf("long的长度为:%d\n", sizeof(long));    // long的长度不会比int短  printf("double的长度为:%d\n", sizeof(double));  printf("long long的长度为:%d\n", sizeof(long long));   printf("signed int的长度为:%d\n", sizeof(signed int));   printf("unsigned int的长度为:%d\n", sizeof(unsigned int));   system("pause");    }

三、输入输出

%hd - short%d  -  int%ld – long%c  - char%f -  float%lf – double%u – 无符号数%x – 十六进制输出  %#x- 十六进制输出,并输出0x表示十六进制%o  - 八进制输出   %#o - 八进制输出,并输出0表示八进制%s – 字符串 

输入:

int count;//scanf会报一个不安全的错误,怎么办呢?//方法一:在引入头文件之前  #define _CRT_SECURE_NO_WARNINGS //宏定义//方法二:使用新函数scanf_fscanf_s("%d",&count);//&表示取变量内存地址,把接收的值赋给countprintf("count=%d\n",count);

输出:

char c = 'a';short s = 1;int i = -1;long l = 255;float f = 3.14;double d = 3.1415926;printf("c = %c\n", c);printf("s = %hd\n", s);printf("i = %d\n", i);printf("l = %ld\n", l);printf("f = %f\n", f);//默认输出6位有效数字printf("f = %.2f\n", f);// .2 输出两位有效数字 printf("d = %lf\n", d);  // 默认输出6位有效数字,会四舍五入printf("i = %u\n", i); // 无符号的数    printf("l = %#X\n\n", l); // 十六进制输出 0x

四、指针

指针就是地址,地址就是内存单元的编号;指针变量是存放地址的变量;指针与指针变量是两个概念,但现实中经常把指针变量说成指针。
指针使用中常见错误:
(1)野指针:没有赋值的指针,不能通过*修改对应内存的数据;
(2)数据类型不匹配:比如int类型的指针只能保存int变量的内存地址;

main() {          int i = 100;      printf("i的内存地址为:%#x\n", &i);      // 定义一个指针变量p,用来保存int变量i的内存地址      int* p;  // int *p    int * p;      // 把i的内存地址赋值给指针变量p      p = &i;      printf("i的内存地址为:%#x\n", p);      printf("i= %d\n", i);      printf("i= %d\n", *p);  // *p表示取p保存的内存地址所存放的值,其实就是i的值      //区分: p 和 &p 和*p      printf("%#x\n", p);    // i的内存地址      printf("%#x\n", &p);   // 指针变量p的内存地址      printf("%d\n", *p);    // i的值       system("pause");    }
#include <stdio.h>   #include <stdlib.h>  main() {           int i = 100;       int* p = &i;     // 一级指针,保存变量的内存地址       int** p2 = &p;   // 二级指针,保存一级指针的内存地址       int*** p3 = &p2; // 三级指针,保存二级指针的内存地址       printf("i = %d\n", i);       printf("i = %d\n", *p);             printf("i = %d\n", **p2);           printf("i = %d\n", ***p3);          system("pause");   }

指针的应用:

  • 交换变量值
#include <stdio.h>   #include <stdlib.h>  /** 交换两个数的值 */swap1(int i , int j){  // 形参         int temp = i;         i = j;         j = temp;}swap2(int* p, int* q){        int temp = *p;        *p = *q;        *q = temp;}main() {           int i = 100;       int j = 200;  // 实数       printf("i = %d\n", i);       printf("j = %d\n", j);       // swap1(i, j);     // 不会交换值       swap2(&i, &j);      // 会交换两个数的值       printf("i = %d\n", i);       printf("j = %d\n", j);             system("pause");   }
  • 返回多个值(更改变量值)
#include <stdio.h>   #include <stdlib.h>  fun(int* p, int* q) {      *p =7;      *q = 8;}main() {          int i =100;       int j =200;        printf("i = %d\n", i);       printf("j = %d\n", j);       fun(&i, &j);       printf("i = %d\n", i);       printf("j = %d\n", j);             system("pause");   }
  • 主函数中获取子函数变量的内存地址
#include <stdio.h>   #include <stdlib.h>  fun2(int** q) {      int i = 100;      printf("i的内存地址为:%#x\n", &i);          *q = &i;     }main() {           int i = 0;       int* p = &i;       fun2(&p);       // 变量还没来得及被回收,但马上被回收了       // printf("i的值为:%d\n", *p);       printf("i的内存地址为:%#x\n", p);       // 子函数执行完后,局部变量已经被回收       printf("i的值为:%d\n", *p);       system("pause");   }

指针与数组:

main() {           // char arr[] = {'a', 'b', 'c'};       char arr[] = "Hello";       printf("第1个元素的内存地址: %#x\n", &arr[0]);       printf("第2个元素的内存地址: %#x\n", &arr[1]);       printf("第3个元素的内存地址: %#x\n", &arr[2]);       int arr2[] = {1, 2, 3};       printf("第1个元素的内存地址: %#x\n", &arr2[0]);       printf("第2个元素的内存地址: %#x\n", &arr2[1]);       printf("第3个元素的内存地址: %#x\n", &arr2[2]);       // C语言中的数组越界了,不会报错       printf("第10个元素的值: %d\n\n\n", arr2[9]);        // 数组的首地址: 下面三种方式都是一样的       printf("数组的首地址: %#x\n", &arr[0]);       printf("数组的首地址: %#x\n", &arr);       printf("数组的首地址: %#x\n\n", arr);       // 通过指针变量操作数组       char* p = arr;        printf("第1个元素的值: %c\n", *p);       printf("第2个元素的值: %c\n", *(p+1));  // 往右偏移一个单位, 对于char就是1个字节       printf("第3个元素的值: %c\n\n", *(p+2));       printf("第1个元素的值: %c\n", p[0]);       printf("第2个元素的值: %c\n", p[1]);       printf("第3个元素的值: %c\n", p[2]);       int* q = arr2;        printf("第1个元素的值: %d\n", *q);       printf("第2个元素的值: %d\n", *(q+1)); // 往右偏移一个单位, 对于int就是4个字节       printf("第3个元素的值: %d\n\n", *(q+2));       // p - q;  // 没有意义       system("pause");   }

五、动态分配内存

栈内存:在栈中分配也叫静态分配;栈内存由系统自动那个分配自动回收;空间大小固定,超出会报栈溢出;速度快。
堆内存:在堆中分配也叫动态分配;堆内存需要调用malloc分配,调用free回收;内存有多大,堆就可以有多大;速度相对慢一些。

#include <stdio.h>   #include <stdlib.h>  #include <malloc.h>main() {         int count =  5;     // 在堆中创建连续的内存空间     int* p = malloc(sizeof(int) * count);      // 对分配出来的内存空间进行赋值     int i = 0;      for(; i < count; i++) {         // 对每个元素进行赋值         printf("第输入第%d个元素:", (i+1));               scanf_s("%d", &p[i]); // (p+i)              }      i = 0;  // 输出每一个元素     for(; i< count; i++) {          printf("第%d个元素为:%d\n", (i+1), p[i]); // *(p+i)      }     // 释放内存     free(p);     printf("第1个元素为:%d\n", p[0]); // 打印第一个元素     system("pause");     }

这里写图片描述

多次调用malloc这个函数分配的空间是不连续的,若要连续,需要用realloc,用法如下:

.......//省略int* p = malloc(sizeof(int) * count);// 再次分配内存,与上一次分配出来的内存连续// 参1: 上一次分配出来的内存空间的首地址// 参2: 总共要分配多少内存p = realloc(p, sizeof(int) * (count + newCount));printf("p = %#x", p);.......//省略

六、函数指针

函数指针是指向函数的指针变量,本质是一个指针变量,保存函数的内存地址。

#include <stdio.h>   #include <stdlib.h>  int add(int i , int j) {    return i+j;}main() {          // 定义一个函数指针,用来保存函数的首地址      int (*pf)(int, int);      // 把函数指针进行赋值, 把add函数的首地址赋值给函数指针pf      pf = add;      // 通过函数指针调用对应的函数      int result = pf(3, 5);      printf("result = %d\n", result);      system("pause");    }

七、结构体

结构体的长度不是简单地相加,有一个补齐规则:
(1)结构体的长度并不是所有成员长度相加,在编译时长度会进行补齐以方便位移。
(2)结构体长度补齐规则:
结构体成员的偏移量是成员长度的整数倍, 如果不是则补齐
结构体的总长度是所有成员长度的整数倍,如果不是则补齐;
(3)成员的偏移量即:成员的地址与结构体首地址的差值。

定义方式有三种:

  • 先定义结构体类型,再定义结构体类型变量
struct Student{  int age;  float score;  char sex;}main() {    struct Student s1; }
  • 定义结构体的同时定义结构体类型变量
struct Student2{ int age; float score; char sex;} s1;//也可以再定义如下变量:main() {    struct Student s2; }
  • 直接定义结构体类型变量
struct { int age; float score; char sex;} s1; 

例子:

#include <stdio.h>   #include <stdlib.h>  void study() {   printf("good good study...\n");}struct Student{  int age;      // 4      float score;  // 4     char sex;     // 1         double d;     // 8    // 定义函数指针  void (*studyP)();}main() {          // 结构体初始化      // 方式1:      struct Student s1 = {20, 100, 'f', 0, study};      // 方式2:      struct Student s2;      s2.age = 25;      s2.score = 90;      s2.sex = 'm';      s2.studyP = study; // 函数指针赋值      // 访问结构体的成员      printf("s1.age = %d\n", s1.age);      printf("s1.score = %f\n", s1.score);      printf("s1.sex = %c\n\n", s1.sex);      printf("s2.age = %d\n", s2.age);      printf("s2.score = %f\n", s2.score);      printf("s2.sex = %c\n\n", s2.sex);      // 结构体的长度:      printf("结构体的长度: s1 = %d\n", sizeof(s1));//24      // 调用函数指针(三种方式)      // 方式1:      s1.studyP();      // 定义结构体指针变量      struct Student* p;      p = &s1;      // 方式2:      (*p).studyP();      // 方式3      p->studyP();  // 转转换成(*p).studyP()      system("pause");    }

八、联合体

当多个数据需要共享内存时可以使用联合体,联合体的成员在赋值时会相互覆盖,因为它们首地址一样。

#include <stdio.h>   #include <stdlib.h>  union U{  float f;  // 4  int i;    // 4  char c;   // 1}main() {           union U u;       u.i = 100;       u.c = 'a';       printf("u.i = %d\n", u.i); //97       printf("联合体的长度: %d\n", sizeof(u));//4       system("pause");   }

九、关键字typedef

#include <stdio.h>   #include <stdlib.h>  // 给int起一个别名,叫做jinttypedef int jint;main() {              jint aa = 1;       printf("aa = %d\n", aa);       system("pause");   }
原创粉丝点击