9. 全局變量和局部變量的區別
定義:全局變量是定義在函數外部的變量,局部變量是定義在 函數內部的變量
存儲位置:全局變量存儲在全局區,局部變量存儲在棧區
作用域:全局變量可以在程序任意位置使用,局部變量只能在函數內部使用
生命周期:全局變量的生命周期為整個程序,程序結束空間釋放,局部變量生命周期為本函數,函數結束空間釋放
初始化:全局變量未初始化初 值為0,局部變量未初始化時值為隨機值
11.memcpy和strcpy的區別?
- 拷貝內容:
- memcpy:memcpy 是用于拷貝指定大小的數據塊(字節),它不會自動檢測字符串結束符('\0'),因此適用于拷貝任意數據,包括字符串和非字符串數據。
- strcpy:strcpy 是用于拷貝第一個以 '\0' 結尾的字符串,它會自動拷貝整個字符串,包括字符串結束符 '\0'。
- 參數:
- memcpy:memcpy 的函數原型為 void *memcpy(void *dest, const void *src, size_t n);,其中 dest 是目標地址,src 是源地址,n 是拷貝的字節數。
- strcpy:strcpy 的函數原型為 char *strcpy(char *dest, const char *src);,其中 dest 是目標字符串的地址,src 是源字符串的地址。
- 安全性:
- memcpy:memcpy 不會檢查目標地址是否足夠大,如果目標地址空間不夠大,可能會發生緩沖區溢出的問題,導致程序崩潰或數據損壞。因此,在使用 memcpy 時需要確保目標地址有足夠的空間來容納源數據。
- strcpy:strcpy 會自動添加符字串結束符 '\0',但如果源字符串太長,超出了目標字符串的空間,也會導致緩沖區溢出問題。因此,使用 strcpy 時應留足夠的空間來·容納源字符串。
- 性能:
- memcpy:memcpy 是按字節拷貝數據,因此在拷貝大塊數據時比較高效。
- strcpy:strcpy 需要遍歷整個源字符串直到遇到字符串結束符 '\0',因此在拷貝較長字符串時性能可能較差。
12. 什么是段錯誤?怎么解決段錯誤?
當程序嘗試訪問它沒有權限訪問的內存地址時
段錯誤通常是由以下幾種情況引起的:
- 訪問空指針: 當程序試圖訪問一個空指針所指向的內存地址時,就會發生段錯誤。例如,未初始化的指針或者指向已釋放的內存的指針。
- 數組越界: 當程序試圖訪問數組越界的元素時,就會發生段錯誤。例如,訪問數組下標小于 0 或者大于等于數組大小的元素。
- 非法內存訪問: 當程序試圖訪問未分配的內存區域,或者試圖訪問系 統保留的內存區域,就會發生段錯誤。
- 對只讀內存的寫操作:當程序試圖對只讀內存進行寫 操作時,例如對常量字符串進行修改,就會發生段錯誤。
要解決段錯誤問題,可以通過以下幾種方式:
- 檢查空指針: 在使用指針之前,先確保指針m不是空指針。可以使用條件語句或者斷言來檢查指針是否為空。
- 數組邊界檢查: 在訪問數組元素之前,先確保訪問的下標在合法的范 圍內。
- 動態內存管理: 在動態分配內存(例如使用 malloc、calloc、new m等函數)后,要確保在不再使用該內存時釋放它(例如使用 free、 delete 等函數)。
- 避免對只讀內存進行寫操作: 對于常量字符串或者是只讀內存區域,避免對其進行寫操作,可以使用 const 關鍵字來聲明指向只讀內存的 指針。
- 使用工具檢查: 可以使用一些工具,如 Valgrind,在程序運行時檢查內存錯誤,包括段錯誤、內存泄漏等。
13.什么是內存泄漏?什么是野指針?
內存泄漏(Memory Leak): 內存泄漏是指程序在動態分配內存后,未釋放不再使用的內存,導致這部分內存永遠無法被回收,從而造成內存的浪費。如果程序中存在內存泄漏,隨著程序的執行,內存占用會逐漸增加,最終可能導致程序崩潰或系統資源耗盡。內存泄漏的常見原因包括:
- 忘記釋放通過 malloc、calloc、new 等動態分配的內存。
- 在循環或迭代過程中,每次分配內存卻未及時釋放導致累積。
- 保存了指向動態分配內存的指針,但在后續程序中指針又指向其他位置從而丟失了釋放的機會。
野指針(Wild Pointer): 野指針是指指向未知或者無效內存地址的指針。野指針通常產生于以下幾種情況:
- 內存釋放后未置空:指針指向的內存已經被釋放,但指針沒有置為 nullptr 或 NULL。
- 指針越界訪問:?指針指向的內存已經被釋放,但程序繼續使用該指針指針未初始化:指針沒有初始化,即沒有賦予合法的地址,指針的初始值是隨機的。
編程題:
1.define比較兩個數的大小
#define MIN(a, b) ((a) < (b)?(a) : (b))
2.將字符串逆序輸出
void reverseString(char *str) { int length = strlen(str);char *start = str;char *end = str + length - 1;while (start < end) {char temp = *start;*start = *end;*end = temp;start++;end--;}
}int main() {char str[] = "Hello, World!";printf("原始字符串:%s\n", str);reverseString(str);printf("逆序輸出:%s\n", str);return 0;
}
3.冒泡排序
void bubbleSort(int arr[], int n) {int i, j;for (i = 0; i < n-1; i++) {// 每次循環將最大的元素冒泡到末尾,因此每輪循環只需比較前 n-i-1 個元素for (j = 0; j < n-i-1; j++) {if (arr[j] > arr[j+1]) {// 如果前一個元素大于后一個元素,則交換它們的位置int temp = arr[j]; //arr[j] ^= arr[j + 1];arr[j] = arr[j+1]; //arr[j + 1] ^= arr[j];arr[j+1] = temp; //arr[j] ^= arr[j + 1];}}}
}
4.strlen、strcpy、strcat、strcmp
size_t my_strlen(const char *str) { size_t len = 0;while (*str) {len++;str++;}return len;
}char *my_strcpy(char *dest, const char *src) {char *temp = dest; // 暫存dest字符串的首地址while (*src) {*dest = *src; dest++;src++;}*dest = '\0'; // 在目標字符串末尾加上 null 終止符return temp;
}char *my_strcat(char *dest, const char *src) {char *temp = dest; // 移動 dest 指針到目標字符串的末尾while (*dest) {dest++;}// 將源字符串復制到目標字符串的末尾while (*src) {*dest = *src;dest++; src++;}// 添加目標字符串的 null 終止符*dest = '\0';return temp;
}#include <stdio.h>int my_strcmp(const char *str1, const char *str2) {while (*str1 && *str2) {if (*str1 != *str2) {return *str1 - *str2;}str1++;str2++;} // 如果兩個字符串長度不等,返回長度差值return *str1 - *str2;
}int main() {const char *str1 = "apple";const char *str2 = "banana";int result = my_strcmp(str1, str2);if (result < 0) {printf("%s 小于 %s\n", str1, str2);} else if (result == 0) {printf("%s 等于 %s\n", str1, str2);} else {printf("%s 大于 %s\n", str1, str2);}return 0;
}
5.打印楊輝三角前10行
#include <stdio.h>
int main(int argc, char const *argv[])
{int a[10][10] = {0}, i, j;for (i = 0; i < 10; i++){a[i][0] = 1;for (j = 1; j <= i; j++)a[i][j] = a[i - 1][j] + a[i - 1][j - 1];}for (i = 0; i < 10; i++){for (j = 0; j <= i; j++)printf("%-5d", a[i][j]);putchar('\n');}return 0;
}運行上述代碼,將會輸出楊輝三角的前10行:Copy code
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
每一行的數字都代表一個組合數,它是由 C(n, k) 組成,其中 n 為行數減1,k 為列數減1。在這個例子中,C(n, k) = triangle[n][k]。
6.atoi函數自定義
7.定義一個函數計算一個字節里(byte)里面有多少bit被置1/
int count(int x+) { int num=0; for (int i = 0; i < 8; i++)//一個字節是8位 { if((x&(1<<i))!=0) num++; } return num; } |