操作环境如下:
操作系统:win10
工具:dev-c++ TDM-GCC 4.9.2 64-bit release
语言标准:C99
char, char*, char**, char*[]类型
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
// part 1
char c = 'a';
printf("c = %c, c: 0x%p;\n", c, &c);
// part 2
char *s1 = "hello world";
printf("s1 = %s, s1: 0x%p, s1[0] = %c, sizeof(s1) = %d, strlen(s1) = %d;\n", s1, s1, s1[0], sizeof(s1), strlen(s1));
char s2[10] = "thank you";
printf("s2 = %s, s2: 0x%p, s2[0] = %c, sizeof(s2) = %d, strlen(s2) = %d;\n", s2, s2, s2[0], sizeof(s2), strlen(s2));
s1 = "world hello";
printf("s1' = %s;\n", s1);
s1 = s2;
printf("s1'' = %s;\n", s1);
// error: s2 = "you thank";
// error :s2 = s1;
// part 3
char *s3[] = {"apple", "orange", "banana"};
printf("s3 = %s, s3: 0x%p;\n", s3, s3);
printf("s3[0] = %s, s3[0]: 0x%p, s3[0][0] = %c, s3[0][0]: 0x%p, sizeof(s3[0]) = %d, strlen(s3[0]) = %d;\n", s3[0], s3[0], s3[0][0], &s3[0][0], sizeof(s3[0]), strlen(s3[0]));
printf("s3[1] = %s, s3[1]: 0x%p, s3[1][0] = %c, s3[1][0]: 0x%p, sizeof(s3[1]) = %d, strlen(s3[1]) = %d;\n", s3[1], s3[1], s3[1][0], &s3[1][0], sizeof(s3[1]), strlen(s3[1]));
printf("s3[2] = %s, s3[2]: 0x%p, s3[2][0] = %c, s3[2][0]: 0x%p, sizeof(s3[2]) = %d, strlen(s3[2]) = %d;\n", s3[2], s3[2], s3[2][0], &s3[2][0], sizeof(s3[2]), strlen(s3[2]));
printf("sizeof(s3) = %d, sizeof(*s3) = %d, sizeof(**s3) = %d, strlen(*s3) = %d\n", sizeof(s3), sizeof(*s3), sizeof(**s3), strlen(*s3));
printf("&s3[0]: 0x%p, &s3[1]: 0x%p, &s3[2]: 0x%p\n", &s3[0], &s3[1], &s3[2]);
printf("*s3 = %s, *(s3 + 1) = %s, *(s3 + 2) = %s\n", *s3, *(s3 + 1), *(s3 + 2));
char **s4 = s3;
printf("s4 = %s, s4: 0x%p\n", s4, s4);
printf("*s4 = %s, *s4: 0x%p\n", *s4, *s4);
printf("**s4: 0x%p\n", **s4);
printf("sizeof(s4) = %d, sizeof(*s4) = %d, sizeof(**s4) = %d, strlen(*s4) = %d\n", sizeof(s4), sizeof(*s4), sizeof(**s4), strlen(*s4));
printf("&s4[0]: 0x%p, &s4[1]: 0x%p, &s4[2]: 0x%p\n", &s4[0], &s4[1], &s4[2]);
printf("*s4 = %s, *(s4 + 1) = %s, *(s4 + 2) = %s\n", *s4, *(s4 + 1), *(s4 + 2));
// part 4
char **s5 = (char **)malloc(sizeof(char **));
*s5 = "hello world";
printf("s5: 0x%p, *s5: 0x%p, *s5 = %s\n", s5, *s5, *s5);
*s5 = "thank you";
printf("s5': 0x%p, *s5': 0x%p, *s5' = %s\n", s5, *s5, *s5);
// part 5
char *s6;
char **s7 = &s6;
*s7 = "hello world";
printf("s6 = %s, s6: 0x%p\n", s6, s6);
s6 = "thank you";
printf("s6 = %s, s6: 0x%p\n", s6, s6);
while(getchar() != '\n') {}
return 0;
}
if…else 判断语句
#include <stdio.h>
int main ()
{
/* 局部变量定义 */
int a = 10;
/* 检查布尔条件 */
if( a == 10 )
{
/* 如果 if 条件为真,则输出下面的语句 */
printf("a 的值是 10\n" );
}
else if( a == 20 )
{
/* 如果 else if 条件为真,则输出下面的语句 */
printf("a 的值是 20\n" );
}
else if( a == 30 )
{
/* 如果 else if 条件为真,则输出下面的语句 */
printf("a 的值是 30\n" );
}
else
{
/* 如果上面条件都不为真,则输出下面的语句 */
printf("没有匹配的值\n" );
}
printf("a 的准确值是 %d\n", a );
return 0;
}
for 循环语句
#include <stdio.h>
int main ()
{
/* for 循环执行 */
int a=10;
for(;a<20;a=a+1)
{
printf("a的值:%d\n",a);
}
return 0;
}
C 数组
//声明数组、数组赋值、访问数组
#include <stdio.h>
int main ()
{
//声明数组:type arrayName [ arraySize ];
int n[ 10 ]; /* n 是一个包含 10 个整数的数组 ];*/
int i,j;
/* 初始化数组元素 */
for ( i = 0; i < 10; i++ )
{
n[ i ] = i + 100; /* 设置元素 i 为 i + 100 */
}
/* 输出数组中每个元素的值 */
for (j = 0; j < 10; j++ )
{
printf("Element[%d] = %d\n", j, n[j] );
}
return 0;
}
//获取数组长度
#include <stdio.h>
int main() {
int array[] = {1, 2, 3, 4, 5};
int length = sizeof(array) / sizeof(array[0]);//数组长度可以使用 sizeof 运算符来获取数组的长度
printf("数组长度为: %d\n", length);
return 0;
}
//使用宏定义,获取数组长度
#include <stdio.h>
#define LENGTH(array) (sizeof(array) / sizeof(array[0])) //使用宏定义
int main() {
int array[] = {1, 2, 3, 4, 5};
int length = LENGTH(array);
printf("数组长度为: %d\n", length);
return 0;
}
//数组名
#include <stdio.h>
//在 C 语言中,数组名表示数组的地址,即数组首元素的地址
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]); // 数组名arr被当作指针使用
}
}
/*我们可以使用&运算符来获取数组的地址,如下所示:
int myArray[5] = {10, 20, 30, 40, 50};
int *ptr = &myArray[0]; // 或者直接写作 int *ptr = myArray;
在上面的例子中,ptr 指针变量被初始化为 myArray 的地址,即数组的第一个元素的地址。
需要注意的是,虽然数组名表示数组的地址,但在大多数情况下,数组名会自动转换为指向数组首元素的指针。这意味着我们可以直接将数组名用于指针运算,例如在函数传递参数或遍历数组时: */
int main() {
int myArray[5] = {10, 20, 30, 40, 50};//包含 5 个元素
printArray(myArray, 5); // 将数组名传递给函数
return 0;
/*在上述代码中,printArray 函数接受一个整数数组和数组大小作为参数,我们将 myArray 数组名传递给函数,函数内部可以像使用指针一样使用 arr 数组名。 */
}
C 命令行参数
#include <stdio.h>
int main( int argc, char *argv[] )
{
if( argc == 2 )
{
printf("The argument supplied is %s\n", argv[1]);
}
else if( argc > 2 )
{
printf("Too many arguments supplied.\n");
}
else
{
printf("One argument expected.\n");
}
}
C 排序算法
冒泡排序
#include <stdio.h>
void bubble_sort(int arr[], int len) {
int i, j, temp;
for (i = 0; i < len - 1; i++)
for (j = 0; j < len - 1 - i; j++)
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
int main() {
int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 ,111, 2, 2};
int len = (int) sizeof(arr) / sizeof(*arr);
bubble_sort(arr, len);
int i;
for (i = 0; i < len; i++)
printf("%d ", arr[i]);
return 0;
}
选择排序
//选择排序(升序)
#include <stdio.h>
void selection_sort(int a[], int len)
{
int i,j,temp;
for (i = 0 ; i < len - 1 ; i++)
{
int min = i; // 记录最小值,第一个元素默认最小
for (j = i + 1; j < len; j++) // 访问未排序的元素
{
if (a[j] < a[min]) // 找到目前最小值
{
min = j; // 记录最小值
}
}
if(min != i)
{
temp=a[min]; // 交换两个变量
a[min]=a[i];
a[i]=temp;
}
/* swap(&a[min], &a[i]); */ // 使用自定义函数交換
}
}
/*
void swap(int *a,int *b) // 交换两个变量
{
int temp = *a;
*a = *b;
*b = temp;
}
*/
int main() {
int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 };
int len = (int) sizeof(arr) / sizeof(*arr);
selection_sort(arr, len);
int i;
for (i = 0; i < len; i++)
printf("%d ", arr[i]);
return 0;
}
哈希表
普通哈希表
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#define TABLE_SIZE 10
typedef struct {
char key[20];
int value;
} KeyValuePair;
typedef struct {
KeyValuePair table[TABLE_SIZE];
} HashTable;
unsigned int hash(const char* key) { // 声明char* key是一个指针,把常量字符串首个字符地址赋给key;指针放不下整个字符串时,常量字符串前必须加const。
unsigned int hashValue = 0;
for (int i = 0; key[i] != '\0'; i++) {
hashValue += key[i];
}
return hashValue % TABLE_SIZE;
}
void insert(HashTable* hashTable, const char* key, int value) {
unsigned int index = hash(key);
strcpy(hashTable->table[index].key, key);
hashTable->table[index].value = value;
}
void get(HashTable* hashTable, const char* key) {
bool flag;
int value;
unsigned int index = hash(key);
if (strcmp(hashTable->table[index].key, key) == 0 && hashTable->table[index].key[0] != '\0') {
value = hashTable->table[index].value;
flag=true;
}
else flag=false;
if(flag) printf("Value for %s:%d\n",key,value);
else printf("key %s not found.\n",key);
}
int main() {
HashTable hashTable;
memset(hashTable.table, 0, sizeof(hashTable.table));
insert(&hashTable, "apple", 1);
insert(&hashTable, "apple",88);
insert(&hashTable, "banana", 2);
insert(&hashTable, "orange", 3);
get(&hashTable,"apple");
get(&hashTable, "orange");
return 0;
}
哈希表-链地址法
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
// 哈希表节点结构
typedef struct Node {
int key;
int value;
struct Node* next;
} Node;
// 哈希表结构
typedef struct HashTable {
// 桶数组,里面有SIZE个链表
Node* buckets[SIZE];
} HashTable;
// 创建哈希表
HashTable* createHashTable() {
HashTable* hashtable = (HashTable*)malloc(sizeof(HashTable));
for (int i = 0; i < SIZE; i++) {
hashtable->buckets[i] = NULL;
}
return hashtable;
}
// 哈希函数
int hashFunction(int key) {
return key % SIZE;
}
// 向哈希表中插入键值对
void insert(HashTable* hashtable, int key, int value) {
int index = hashFunction(key);
// 创建新节点
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->key = key;
newNode->value = value;
newNode->next = NULL;
// 如果桶为空,则直接插入新节点
if (hashtable->buckets[index] == NULL) {
hashtable->buckets[index] = newNode;
} else {
// 否则,在链表末尾插入新节点
Node* current = hashtable->buckets[index];
while (current->next != NULL) {
current = current->next;
}
current->next = newNode;
}
}
// 根据键查找哈希表中的值
int search(HashTable* hashtable, int key) {
int index = hashFunction(key);
// 查找链表中对应的节点
Node* current = hashtable->buckets[index];
while (current != NULL) {
if (current->key == key) {
return current->value;
}
current = current->next;
}
// 若未找到,返回-1
return -1;
}
// 从哈希表中删除键值对
void delete(HashTable* hashtable, int key) {
int index = hashFunction(key);
// 查找链表中对应的节点
Node* current = hashtable->buckets[index];
Node* prev = NULL;
while (current != NULL) {
if (current->key == key) {
if (prev == NULL) {
// 若为头节点,直接修改桶指针
hashtable->buckets[index] = current->next;
} else {
// 否则修改前一个节点的指针
prev->next = current->next;
}
free(current);
return;
}
prev = current;
current = current->next;
}
}
// 销毁哈希表
void destroyHashTable(HashTable* hashtable) {
for (int i = 0; i < SIZE; i++) {
Node* current = hashtable->buckets[i];
while (current != NULL) {
Node* temp = current;
current = current->next;
free(temp);
}
}
free(hashtable);
}
int main() {
HashTable* hashtable = createHashTable();
// 插入键值对
insert(hashtable, 1, 10);
insert(hashtable, 11, 20);
insert(hashtable, 21, 30);
// 查找值
int value =search(hashtable, 11);
if(value) printf("Find key =11 ,value = %d\n",value);
else printf("key=11 not exist.\n");
// 销毁哈希表
destroyHashTable(hashtable);
return 0;
}
哈希表-开放地址法
// 线性探测法
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
// 哈希表节点结构
typedef struct {
int key;
int value;
} Node;
// 哈希表结构
typedef struct {
Node* data[SIZE];
} HashTable;
// 创建哈希表
HashTable* createHashTable() {
HashTable* hashtable = (HashTable*)malloc(sizeof(HashTable));
for (int i = 0; i < SIZE; i++) {
hashtable->data[i] = NULL;
}
return hashtable;
}
// 哈希函数
int hashFunction(int key) {
return key % SIZE;
}
// 向哈希表中插入键值对
void insert(HashTable* hashtable, int key, int value) {
int index = hashFunction(key);
// 寻找下一个可用的位置
while (hashtable->data[index] != NULL) {
index = (index + 1) % SIZE;
}
// 创建新节点
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->key = key;
newNode->value = value;
// 插入新节点
hashtable->data[index] = newNode;
}
// 根据键查找哈希表中的值
int search(HashTable* hashtable, int key) {
int index = hashFunction(key);
int originalIndex = index;
// 从哈希表中寻找对应的键值对
while (hashtable->data[index] != NULL) {
if (hashtable->data[index]->key == key) {
return hashtable->data[index]->value;
}
index = (index + 1) % SIZE;
// 如果回到原始位置,则说明未找到
if (index == originalIndex) {
break;
}
}
// 若未找到,返回-1
return -1;
}
// 从哈希表中删除键值对
void delete(HashTable* hashtable, int key) {
int index = hashFunction(key);
int originalIndex = index;
// 从哈希表中寻找对应的键值对
while (hashtable->data[index] != NULL) {
if (hashtable->data[index]->key == key) {
free(hashtable->data[index]);
hashtable->data[index] = NULL;
return;
}
index = (index + 1) % SIZE;
// 如果回到原始位置,则说明未找到
if (index == originalIndex) {
break;
}
}
}
// 销毁哈希表
void destroyHashTable(HashTable* hashtable) {
for (int i = 0; i < SIZE; i++) {
if (hashtable->data[i] != NULL) {
free(hashtable->data[i]);
}
}
free(hashtable);
}
int main() {
HashTable* hashtable = createHashTable();
// 插入键值对
insert(hashtable, 1, 10);
insert(hashtable, 11, 20);
insert(hashtable, 21, 30);
// 查找值
int value = search(hashtable, 1);
if (value != -1) {
printf("找到了,值为:%d\n", value);
} else {
printf("未找到该键\n");
}
// 删除键值对
delete(hashtable, 1);
// 再次查找
value = search(hashtable, 1);
if (value != -1) {
printf("找到了,值为:%d\n", value);
} else {
printf("未找到该键\n");
}
// 销毁哈希表
destroyHashTable(hashtable);
return 0;
}
哈希表-二次探测
// 二次探测
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
// 哈希表节点结构
typedef struct {
int key;
int value;
} Node;
// 哈希表结构
typedef struct {
Node* data[SIZE];
} HashTable;
// 创建哈希表
HashTable* createHashTable() {
HashTable* hashtable = (HashTable*)malloc(sizeof(HashTable));
for (int i = 0; i < SIZE; i++) {
hashtable->data[i] = NULL;
}
return hashtable;
}
// 哈希函数
int hashFunction(int key) {
return key % SIZE;
}
// 向哈希表中插入键值对
void insert(HashTable* hashtable, int key, int value) {
int index = hashFunction(key);
int step = 1;
// 寻找下一个可用的位置
while (hashtable->data[index] != NULL) {
index = (index + step * step) % SIZE;
step++;
}
// 创建新节点
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->key = key;
newNode->value = value;
// 插入新节点
hashtable->data[index] = newNode;
}
// 根据键查找哈希表中的值
int search(HashTable* hashtable, int key) {
int index = hashFunction(key);
int step = 1;
// 从哈希表中寻找对应的键值对
while (hashtable->data[index] != NULL) {
if (hashtable->data[index]->key == key) {
return hashtable->data[index]->value;
}
index = (index + step * step) % SIZE;
step++;
}
// 若未找到,返回-1
return -1;
}
// 从哈希表中删除键值对
void delete(HashTable* hashtable, int key) {
int index = hashFunction(key);
int step = 1;
// 从哈希表中寻找对应的键值对
while (hashtable->data[index] != NULL) {
if (hashtable->data[index]->key == key) {
free(hashtable->data[index]);
hashtable->data[index] = NULL;
return;
}
index = (index + step * step) % SIZE;
step++;
}
}
// 销毁哈希表
void destroyHashTable(HashTable* hashtable) {
for (int i = 0; i < SIZE; i++) {
if (hashtable->data[i] != NULL) {
free(hashtable->data[i]);
}
}
free(hashtable);
}
int main() {
HashTable* hashtable = createHashTable();
// 插入键值对
insert(hashtable, 1, 10);
insert(hashtable, 11, 20);
insert(hashtable, 21, 30);
// 查找值
int value = search(hashtable, 1);
if (value != -1) {
printf("找到了,值为:%d\n", value);
} else {
printf("未找到该键\n");
}
// 删除键值对
delete(hashtable, 1);
// 再次查找
value = search(hashtable, 1);
if (value != -1) {
printf("找到了,值为:%d\n", value);
} else {
printf("未找到该键\n");
}
// 销毁哈希表
destroyHashTable(hashtable);
return 0;
}
哈希表-双重哈希
// 双重哈希
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
// 哈希表节点结构
typedef struct {
int key;
int value;
} Node;
// 哈希表结构
typedef struct {
Node* data[SIZE];
} HashTable;
// 创建哈希表
HashTable* createHashTable() {
HashTable* hashtable = (HashTable*)malloc(sizeof(HashTable));
for (int i = 0; i < SIZE; i++) {
hashtable->data[i] = NULL;
}
return hashtable;
}
// 哈希函数1
int hashFunction1(int key) {
return key % SIZE;
}
// 哈希函数2
int hashFunction2(int key) {
return 1 + (key % (SIZE - 1));
}
// 向哈希表中插入键值对
void insert(HashTable* hashtable, int key, int value) {
int index = hashFunction1(key);
int step = hashFunction2(key);
// 寻找下一个可用的位置
while (hashtable->data[index] != NULL) {
index = (index + step) % SIZE;
}
// 创建新节点
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->key = key;
newNode->value = value;
// 插入新节点
hashtable->data[index] = newNode;
}
// 根据键查找哈希表中的值
int search(HashTable* hashtable, int key) {
int index = hashFunction1(key);
int step = hashFunction2(key);
// 从哈希表中寻找对应的键值对
while (hashtable->data[index] != NULL) {
if (hashtable->data[index]->key == key) {
return hashtable->data[index]->value;
}
index = (index + step) % SIZE;
}
// 若未找到,返回-1
return -1;
}
// 从哈希表中删除键值对
void delete(HashTable* hashtable, int key) {
int index = hashFunction1(key);
int step = hashFunction2(key);
// 从哈希表中寻找对应的键值对
while (hashtable->data[index] != NULL) {
if (hashtable->data[index]->key == key) {
free(hashtable->data[index]);
hashtable->data[index] = NULL;
return;
}
index = (index + step) % SIZE;
}
}
// 销毁哈希表
void destroyHashTable(HashTable* hashtable) {
for (int i = 0; i < SIZE; i++) {
if (hashtable->data[i] != NULL) {
free(hashtable->data[i]);
}
}
free(hashtable);
}
int main() {
HashTable* hashtable = createHashTable();
// 插入键值对
insert(hashtable, 1, 10);
insert(hashtable, 11, 20);
insert(hashtable, 21, 30);
// 查找值
int value = search(hashtable, 1);
if (value != -1) {
printf("找到了,值为:%d\n", value);
} else {
printf("未找到该键\n");
}
// 删除键值对
delete(hashtable, 1);
// 再次查找
value = search(hashtable, 1);
if (value != -1) {
printf("找到了,值为:%d\n", value);
} else {
printf("未找到该键\n");
}
// 销毁哈希表
destroyHashTable(hashtable);
return 0;
}
参考链接:
https://blog.csdn.net/weixin_43764974/article/details/131053431
https://www.runoob.com/cprogramming/c-sort-algorithm.html