Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C #49

Open
magicdawn opened this issue Nov 6, 2015 · 18 comments
Open

C #49

magicdawn opened this issue Nov 6, 2015 · 18 comments

Comments

@magicdawn
Copy link
Owner

Yeah C.

@magicdawn
Copy link
Owner Author

magicdawn commented Nov 6, 2015

char name[40];

// 1. wrong
// warning, but 可运行
scanf("%s", &name);

// 2. right, name= char* , already a pointer
scanf("%s", name);

int age;
scanf("%d", &age);

@magicdawn
Copy link
Owner Author

header reference

@magicdawn
Copy link
Owner Author

c primer plus

ch8

getchar() 缓冲区

  1. 完全缓冲, 等待缓冲区满, 读写数据, 清空缓冲区
  2. 行缓冲, 遇到 \n 换行符时, 读写数据, 清空缓冲区

键盘输入是标准的行缓冲.

EOF

stdio.h 通常 EOF=-1

某些Unix 系统使用Ctrl + D 来输入EOF内容, 某些使用 Ctrl + Z

  1. python repl, 使用 Ctrl + D & Ctrl + Z 都可以 exit
  2. OS X 使用 Ctrl + D 表示EOF, Ctrl + Z 直接退出

ch14

image

struct struct_name *ps; // 这样没有初始化
image

@magicdawn
Copy link
Owner Author

CFLAGS

option value example explain
-g -g Generate source-level debug information
-W all -Wall Enable the specified warning enable某一类型warning
-w supress all warnings 取消所有warning
-I ./deps -I./deps Add directory to include search path

@magicdawn
Copy link
Owner Author

lib usage guide

libuv

# 1. build `libuv.a`

# 2. include libuv header & add libuv.a to srcs
cc -I ./libuv/include my.c libuv.a -o my # 

@magicdawn
Copy link
Owner Author

sizeof

  • sizeof(type)
  • sizeof variable
/**
 * cc sizeof.c -o sizeof -w
 */

#include <stdio.h>

int main(){
  const int days[] = {
    31, 28, 31, 30, 31, 30,
    31, 31, 30, 31, 30, 31
  };

  printf("size = %d\n", sizeof days / sizeof days[0]); // 12
  printf("equals = %d\n", sizeof days[0] == sizeof(int)); //  1
  return 0;
}

@magicdawn
Copy link
Owner Author

运算符优先级

  • *p + 1, 取值运算符优先级较高, 先取值, 后加1



@magicdawn
Copy link
Owner Author

数组 as 函数参数

void fn(int *arr);
void fn(int arr[]);

// prototype
void fn(int*);
void fn(int[]);

@magicdawn
Copy link
Owner Author

const

const int x = 10; // x is a const
const int *px = 10; // *px is a const, px 是指向常量的指针, *px的值不能变
int* const px = 10; // px是常量指针, px 的指向不能变

// 将非常量地址(&x)赋值给指向常量的指针(px)是可行的
int x = 10;
const int *px = &x; // 可行, 因为 px是指向常量的指针, 不能通过指针去修改x

// 将常量数据y, 赋值给普通指针py是不合法的
const int y = 10;
int* py = &y; // 不合法, 因为这样之后可以使用 (*py)去修改y值, 但是y是const值
// 这两种形式一样: *px 为const, 即指向const的指针
const int *px = 10;
int const *px = 10; 

@magicdawn
Copy link
Owner Author

pointers

int x = 10;
const int* px = &x; // 取x的地址
const int* py = 10; // 指向10
#include <stdio.h>

int main(){

  int x = 10;
  const int *px = &x;

  printf("px = %lu\n*px = %d", px, *px);
  return 0;
}

/*
output: 
px = 140734675919640
*px = 10
*/

@magicdawn
Copy link
Owner Author

args

int main(int argc, char *argv[]);
// 等同于
int main(int argc, char **argv);

// argv是指向char类型的指针组成的数组
// argv[0] as char*

@magicdawn
Copy link
Owner Author

Linkage 链接性

  • external linkage 外部链接性的变量可以在一个多文件程序的任何地方使用.
  • internal linkage 内部链接性仅限文件内部使用
  • empty linkage 代码块内部使用
int num = 5;
static int num_internal = 10; // internal, 加了static, 本文件内部可见

Storage Duration 存储时期

  • static storage duration 静态存储时期, 在程序运行期间将一直存在
  • automatic storage duration 自动存储时期

在文件作用域有效的变量都具有静态存储时期

五种存储类

image

寄存器变量

  • 寄存器变量可以被存储在cpu寄存器中或更一般的速度更快的内存中. 从而可以比普通变量更快地被访问和操作.
  • 无法取得寄存器变量的地址
  • register int x = 10 只是一个请求, 而非一条命令. 可能达不成要求, 变成一个普通变量.

代码块作用域中的静态存储时期变量

在一个函数作用域中的静态变量只初始化一个, 并一直存在:

int fn(){
  int x = 1;
  static int y = 1;
  printf("x = %d, y = %d", x++, y++);
}

int main(){
  for(int i = 0; i < 3; i++){
    fn();
  }
  return 0;
}

// 输出
// x = 1, y = 1
// x = 1, y = 2
// x = 1, y = 3

外部链接性变量

// x.c
int x = 10; // 静态存储时期, 外部链接性

// y.c
extern int x; // 使用extern 表示是在其他文件声明的变量
int y = 20;

void someFn(){
  extern int y; // 在一个函数内再次声明 y 是extern的, 纯属画蛇添足, 但要明白可以这样用
}

外部变量只能使用常量表达式来初始化

extern int x;
int y = x + 10; // 不合法

类型限定词

  • const : const
  • volatile: 表明数据可通过程序修改外, 还可通过其他方式修改, 其目的是警示编译器在优化时不要做出相反的假设.
  • restrict: restrict限定的指针被认为是提供了对其所指向的数据块的唯一访问途径.

@magicdawn
Copy link
Owner Author

malloc & free

malloc

void* mallpc(int size)

int* px = (int*) malloc(sizeof(int));

malloc返回值是void* 类型, 需要手动转为需要的ptr类型

free

free(px);

@magicdawn
Copy link
Owner Author

struct

struct struct_name {
  int x,
  int y
}

即可定义一个struct, 名为struct_name

struct struct_name variable = { 1, 2 };
struct struct_name variable = { .x = 1, .y = 2 };

struct_name 可匿名, 这样

  • 只使用一次, 使用 struct { struct定义 } variable
  • 配合typedef 使用 typedef struct { struct定义 } complex 这样定义了一个complex类型
struct struct_name s1,s2;
struct struct_name* ps;

// 使用点号去获取成员
s1.x = s1.y = 10;

// pointer->member
// 指向结构体的指针使用 -> 访问成员
ps = &s1;
ps->x = ps->y = 10;

union

union point {
  int x;
  double y;
}

union同struct, 但是member之间互斥, 同一时间只有一个member能存在, 例如 x, y 不能同时存在, 分配空间时按照占用空间最大的member来分配

@magicdawn
Copy link
Owner Author

函数指针

char* toUpper(char*); // 一个转换字符串为大写的函数
char* (*pf) (char*); // pf为函数指针
pf = toUpper; // 给函数指针赋值

// 都是可行的
pf("hello world");
(*pf)("hello world"); 

结合typedef, 可以定义函数指针的类型

typedef (char* (*S_TO_S)(char*));
char* (S_TO_S fp){
  return fp("hello world");
}

@magicdawn
Copy link
Owner Author

预处理指令

指令 示例 意义
#define / #undef 宏定义
#ifdef / #ifndef
#if / #else / #elif / #endif
#pragma #pragma once 用于修改编译器的某些设置
#line #line 10 "cool.c" 用于重置报告错误时的, 文件名 和 行数信息
#error

define

// 带参数
#define SQUARE(x) (x*x);

// #运算符
// #为替换
#define PRINT(x) printf("#x = %d", x);
PRINT(y); // -> 展开为 printf("y = %d", y);

// ##为连接运算符
#define XNUM(n) x ## n;
XNUM(4) // -> x4

pragma once

只要在头文件的最开始加入这条杂注,就能够保证头文件只被编译一次. 是编译器相关的,有的编译器支持,有的不支持.

@magicdawn
Copy link
Owner Author

头文件

#include <stdio.h>; // 尖括号, 在标准目录中寻找文件
#include "abc.h"; // 双引号, 在当前目录寻找文件, 然后在标准目录中寻找文件

size_t

http://stackoverflow.com/questions/1119370/where-do-i-find-the-definition-of-size-t

说是 stdlib.hstddef.h 包含了 size_t 的定义. 通常为 unsigned int

@magicdawn
Copy link
Owner Author

大小端

#include <stdio.h>

int main(void) {
  short x[] = {1,2};
  printf("%x \n", (*(int*)x)); // 20001, 2在高字节处

  printf("-----------------\n");
  printf("sizeof short = %lu\n", sizeof(short));
  printf("sizeof int = %lu\n", sizeof(int));
  printf("addr x = %p, *x = %d\n", x, *x);
  printf("addr x+1 = %p, *(x+1) = %d\n", x+1, *(x+1));

  return 0;
}

// 00000000 0000001 00000000 00000002
// 0102
os.endianness(); // LE 低字节在低地址处

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant