C#学习笔记 (。・∀・)ノ゙
leetcode:
C#:94题、844题。
C实现:225题。
数据结构——堆栈(Stack)
就是栈,它代表了一个后进先出的对象集合。
Stack 类的方法和属性
下表列出了 Stack 类的一些常用的 属性:
属性 | 描述 |
---|---|
Count | 获取 Stack 中包含的元素个数。 |
下表列出了 Stack 类的一些常用的 方法:
序号 | 方法名 & 描述 |
---|---|
1 | public virtual void Clear(); 从 Stack 中移除所有的元素。 |
2 | public virtual bool Contains( object obj ); 判断某个元素是否在 Stack 中。 |
3 | public virtual object Peek(); 返回在 Stack 的顶部的对象,但不移除它。 |
4 | public virtual object Pop(); 移除并返回在 Stack 的顶部的对象。 |
5 | public virtual void Push( object obj ); 向 Stack 的顶部添加一个对象。 |
6 | public virtual object[] ToArray(); 复制 Stack 到一个新的数组中。 |
C#数组
在 C# 中声明一个数组,您可以使用下面的语法:
datatype[] arrayName;//声明数组的语法
double[] balance;//声明数组
double[] balance = new double[10];//初始化
int [] marks = new int[5] { 99, 98, 92, 97, 95};//创建并初始化
int [] marks = new int[] { 99, 98, 92, 97, 95};//省略数组大小
//赋值一个数组变量到另一个目标数组变量中。在这种情况下,目标和源会指向相同的内存位置:
int [] marks = new int[] { 99, 98, 92, 97, 95};
int[] score = marks;
当您创建一个数组时,C# 编译器会根据数组类型隐式初始化每个数组元素为一个默认值。例如,int 数组的所有元素都会被初始化为 0。
C语言结构体
为了定义结构,您必须使用 struct 语句。struct 语句定义了一个包含多个成员的新的数据类型,struct 语句的格式如下:
struct [structure tag]
{
member definition;
member definition;
...
member definition;
} [one or more structure variables];
structure tag 是可选的,每个 member definition 是标准的变量定义,比如 int i; 或者 float f; 或者其他有效的变量定义。在结构定义的末尾,最后一个分号之前,您可以指定一个或多个结构变量,这是可选的。下面是声明 Book 结构的方式:
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
} book;
访问结构的成员,我们使用成员访问运算符(.)。成员访问运算符是结构变量名称和我们要访问的结构成员之间的一个句号:
变量名.结构成员
C语言指针
每一个变量都有一个内存位置,使用:&变量名 表示该变量在内存中的地址。
指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。
在这里,type 是指针的基类型,它必须是一个有效的 C 数据类型,var-name 是指针变量的名称。用来声明指针的星号 * 与乘法中使用的星号是相同的。但是,在这个语句中,星号是用来指定一个变量是指针。以下是有效的指针声明:
type *var-name; //声明指针的格式
int *ip; /* 一个整型的指针 */
double *dp; /* 一个 double 型的指针 */
float *fp; /* 一个浮点型的指针 */
char *ch /* 一个字符型的指针 */
使用指针
使用指针时会频繁进行以下几个操作:定义一个指针变量、把变量地址赋值给指针、访问指针变量中可用地址的值。
在变量声明的时候,如果没有确切的地址可以赋值,为指针变量赋一个 NULL 值是一个良好的编程习惯。赋为 NULL 值的指针被称为空指针。
这些是通过使用一元运算符 * 来返回位于操作数所指定地址的变量的值。下面的实例涉及到了这些操作:
int var = 20; /* 实际变量的声明 */
int *ip; /* 指针变量的声明 */
ip = &var; /* 在指针变量中存储 var 的地址 */
int *ptr = NULL; //声明指针并赋空值
在大多数的操作系统上,程序不允许访问地址为 0 的内存,因为该内存是操作系统保留的。然而,内存地址 0 有特别重要的意义,它表明该指针不指向一个可访问的内存位置。但按照惯例,如果指针包含空值(零值),则假定它不指向任何东西。
如需检查一个空指针,您可以使用 if 语句,如下所示:
if(ptr) /* 如果 p 非空,则完成 */
if(!ptr) /* 如果 p 为空,则完成 */
下面用C语言简单实现栈:
typedef struct{
struct ListNode* next;
int value;
}ListNode;
typedef struct {
ListNode* top;
} MyStack;
/** Initialize your data structure here. */
MyStack* myStackCreate() {
MyStack* st=calloc(1,sizeof(MyStack));
return st;
}
/** Push element x onto stack. */
void myStackPush(MyStack* obj, int x) {
ListNode* pushx=malloc(sizeof(ListNode));
pushx->value=x;
pushx->next=obj->top;
obj->top=pushx;
}
/** Removes the element on top of the stack and returns that element. */
int myStackPop(MyStack* obj) {
ListNode* node=obj->top;
int val=node->value;
obj->top=node->next;
return val;
}
/** Get the top element. */
int myStackTop(MyStack* obj) {
return obj->top->value;
}
/** Returns whether the stack is empty. */
bool myStackEmpty(MyStack* obj) {
if(obj->top)
return 0;
return 1;
}
void myStackFree(MyStack* obj) {
while(obj->top)
{
ListNode* node=obj->top;
obj->top=node->next;
free(node);
}
free(obj);
}
C语言库函数:malloc
原型:extern void *malloc(unsigned int num_bytes);
用法:#include <alloc.h>
功能:分配长度为num_bytes字节的内存块
说明:如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。
当内存不再使用时,应使用free()函数将内存块释放。
p=(char *)malloc(100);
free(p);
C语言库函数:calloc
原型:extern void *calloc(int num_elems, int elem_size);
用法:#include <alloc.h>
功能:为具有num_elems个长度为elem_size元素的数组分配内存
说明:如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。当内存不再使用时,应使用free()函数将内存块释放。
p=(char *)calloc(100,sizeof(char));
free(p);
calloc和malloc的区别
主要的不同是malloc不初始化分配的内存,calloc初始化已分配的内存为0。
次要的不同是calloc返回的是一个数组,而malloc返回的是一个对象。
calloc等于malloc后在memset很可能calloc内部就是一个malloc再来一个memset清0。
所以malloc比calloc更高效.