C语法速查笔记

1. 指针词库

指针仅仅是指向计算机中的某个地址, 并带有类型限定符,所以你可以通过它得到正确大小的数据

标识 含义
type *ptr type 类型的指针, 名为 ptr
*ptr ptr 所指向位置的值
*(ptr + i) (ptr 所指向位置加上 i)的值, 以字节为单位的话, 应该是 ptr 所指向的位置再加上 sizeof(type) * i
&thing thing 的地址
type *ptr = &thing 名为 ptr , type 类型的指针, 值设置为 thing 的地址
ptr++ 自增 ptr 指向的位置

2. 数组和指针

将array传入一个函数的时候, 传入的其实是一个指针, 对其求 sizeof 不能求出实际大小, 只能求出指针的大小 (数组退化)

没退化的时候可以求出对应的数组的元素的个数

int areas[] = {10, 12, 13, 14, 20};
printf("The size of an int: %ld\n", sizeof(int));

3. 数组的遍历

int ages[] = {23, 43, 12, 89, 2};
char *names[] = {
    "Alan", "Frank",
    "Mary", "John", "Lisa"
};

3.1 使用数组+下标访问

for(i = 0; i < count; i++)
{
    printf("%s has %d years alive.\n", names[i], ages[i]);
}

3.2. 使用指针访问

int *cur_age = ages;
char **cur_name = names;
for(i = 0; i < count; i++)
{
    printf("%s is %d years old.\n", *(cur_name+i), *(cur_age+i));
}

3.3 指针+下标

for(i = 0; i < count; i++)
{
    printf("%s is %d years old again.\n",
    cur_name[i], cur_age[i]);
}

3.4 指针+迭代

for(cur_name = names, cur_age = ages; (cur_age - ages) < count; cur_name++, cur_age++)
{
    printf("%s lived %d years so far.\n", *cur_name, *cur_age);
}

4. 结构体和指向它们的指针

struct Person {
    char *name;
    int age;
    int height;
    int weight;
};

初始化和销毁

struct Person *Person_create(char *name, int age, int height, int weight)
{
    struct Person *who = malloc(sizeof(struct Person));
    assert(who != NULL);
    who->name = strdup(name);
    who->age = age;
    who->height = height;
    who->weight = weight;
    
    return who;
}

void Person_destroy(struct Person *who)
{
    assert(who != NULL);
    free(who->name);
    free(who);
}

5. 函数指针

函数指针的格式

int (*POINTER_NAME)(int a, int b)

编写方式:

  1. 编写一个普通的函数声明: int callme(int a, int b)
  2. 将函数用指针语法包装: int (*callme)(int a, int b)
  3. 将名称改成指针名称: int (*compare_cb)(int a, int b)

赋值:

int (*tester)(int a, int b) = sorted_order;

调用:

printf("TEST: %d is same as %d\n", tester(2, 3), sorted_order(2,3));

6. 头文件处理

#ifndef _object_h
#define _object_h
// body
#endif

7. typedef 的使用

typedef enum {
    NORTH, SOUTH, EAST, WEST
} Direction;

typedef struct {
    char *description;
    int (*init)(void *self);
    void (*describe)(void *self);
    void (*destroy)(void *self);
    void *(*move)(void *self, Direction direction);
    int (*attack)(void *self, int damage);
} Object;

后面直接可以用 Direction, Object 来表示一个类型

8. 高级数据类型和控制结构

8.1 可用数据类型

类型 含义
int 储存普通的整数,默认为32位大小. int 在32或64位环境下为32位, 但它不应该被看作平台无关的. 如果需要用到平台无关的定长整数,请使用 int(n)_t
double 储存稍大的浮点数
float 储存稍小的浮点数
char 储存单字节字符
void 表示"无类型", 用于声明不返回任何东西的函数, 或者所指类型不明的指针, 例如 void *thing
enum 枚举类型,类似于整数,也可转换为整数,但是通过符号化的名称访问或设置

8.2 类型修饰符

修饰符 含义
unsigned 修改类型,使它不包含任何负数,同时上界变高
signed 可以储存正数和负数,符号修饰符只对 charint 有效, int 默认为 signed, char 根据实现则不定
long 对该类型使用较大的空间,使它能存下更大的数,通常使当前大小加倍
short 对该类型使用较小的空间,使它储存能力变小,但是占据空间也变成一半

8.3 类型限定符

限定符 含义
const 表示变量在初始化后不能改变
volatile 表示会做最坏的打算,编译器不会对它做任何优化
register 强制让编译器将这个变量保存在寄存器中,并且也可以无视它

8.4 类型转换

C使用了一种"阶梯形类型提升"的机制, 它会观察运算符两边的变量,并且在运算之前将较小边的变量转换为较大边. 这个过程按照如下顺序:

  1. long double
  2. double
  3. float
  4. long long
  5. long
  6. int (short, char)

shortchar 会在运算之前转换成 int . 同种类型的 unsignedsigned 运算, signed 保持字节不变转换成 unsigned

8.5 类型大小

stdint.h 为定长的整数类型定义了一些 typedef, 同时也有一些用于这些类型的宏

数据类型如下:

  1. int8_t, uint8_t
  2. int16_t, uint16_t
  3. int32_t, uint32_t
  4. int64_t, uint64_t

源码如下:

typedef __int8_t int8_t;
typedef __int16_t int16_t;
typedef __int32_t int32_t;
typedef __int64_t int64_t;#ifndef _BITS_STDINT_INTN_H
#define _BITS_STDINT_INTN_H 1

#include 

typedef __int8_t int8_t;
typedef __int16_t int16_t;
typedef __int32_t int32_t;
typedef __int64_t int64_t;

#endif /* bits/stdint-intn.h */


#ifndef _BITS_STDINT_UINTN_H
#define _BITS_STDINT_UINTN_H    1

#include 

typedef __uint8_t uint8_t;
typedef __uint16_t uint16_t;
typedef __uint32_t uint32_t;
typedef __uint64_t uint64_t;

#endif /* bits/stdint-uintn.h */

定义的最大最小值:

定义 含义
INT(N)_MAX N 位最大的int
INT(N)_MIN
UINT(N)_MAX
int_least(N)_t 至少 N 位的整数
INT_LEAST(N)_MAX

源码如下:

/* Minimum of signed integral types.  */
# define INT8_MIN       (-128)
# define INT16_MIN      (-32767-1)
# define INT32_MIN      (-2147483647-1)
# define INT64_MIN      (-__INT64_C(9223372036854775807)-1)
/* Maximum of signed integral types.  */
# define INT8_MAX       (127)
# define INT16_MAX      (32767)
# define INT32_MAX      (2147483647)
# define INT64_MAX      (__INT64_C(9223372036854775807))
// stdint.h
/* Signed.  */
typedef __int_least8_t int_least8_t;
typedef __int_least16_t int_least16_t;
typedef __int_least32_t int_least32_t;
typedef __int_least64_t int_least64_t;

/* Unsigned.  */
typedef __uint_least8_t uint_least8_t;
typedef __uint_least16_t uint_least16_t;
typedef __uint_least32_t uint_least32_t;
typedef __uint_least64_t uint_least64_t;


// types.h
typedef signed char __int8_t;
typedef unsigned char __uint8_t;
typedef signed short int __int16_t;
typedef unsigned short int __uint16_t;
typedef signed int __int32_t;
typedef unsigned int __uint32_t;
#if __WORDSIZE == 64
typedef signed long int __int64_t;
typedef unsigned long int __uint64_t;
#else
__extension__ typedef signed long long int __int64_t;
__extension__ typedef unsigned long long int __uint64_t;
#endif

/* Smallest types with at least a given width.  */
typedef __int8_t __int_least8_t;
typedef __uint8_t __uint_least8_t;
typedef __int16_t __int_least16_t;
typedef __uint16_t __uint_least16_t;
typedef __int32_t __int_least32_t;
typedef __uint32_t __uint_least32_t;
typedef __int64_t __int_least64_t;
typedef __uint64_t __uint_least64_t;

ref: https://learncodethehardway.org/c/

你可能感兴趣的:(C语法速查笔记)