柚子快報(bào)邀請(qǐng)碼778899分享:算法 初始C語(yǔ)言
柚子快報(bào)邀請(qǐng)碼778899分享:算法 初始C語(yǔ)言
一,printf的返回值
基本概念
在 C 語(yǔ)言中,printf函數(shù)的返回值是成功打印的字符數(shù)(不包括字符串結(jié)束符\0)。如果發(fā)生錯(cuò)誤,則返回一個(gè)負(fù)數(shù)。
示例說(shuō)明
以下是一個(gè)簡(jiǎn)單的示例代碼:
#include
int main() {
int num = 10;
int count = printf("The number is %d\n", num);
printf("The number of characters printed: %d\n", count);
return 0;
}
在這個(gè)示例中,printf("The number is %d\n", num);首先會(huì)打印出The number is 10(共 14 個(gè)字符,包括空格和換行符),然后將返回值(14)賦給count變量,最后再打印出這個(gè)返回值。
實(shí)際用途
可以利用printf的返回值進(jìn)行錯(cuò)誤檢測(cè)。例如:
#include
int main() {
int ret = printf("This is a test\n");
if (ret < 0) {
perror("printf error");
}
return 0;
}
這里通過(guò)檢查printf的返回值,如果為負(fù)數(shù)則表示發(fā)生了錯(cuò)誤(如輸出設(shè)備不可用等情況),然后使用perror函數(shù)輸出錯(cuò)誤信息。一道例題
輸出結(jié)果為4321,最內(nèi)層的printf打印43,中間的printf打印內(nèi)層printf的返回值2,外層函數(shù)打印中間的printf的返回值1,所以結(jié)果為4321.
二,各個(gè)進(jìn)制的表示形式
十進(jìn)制(Decimal)
十進(jìn)制是我們?nèi)粘I钪凶畛S玫倪M(jìn)制。它由 0 - 9 這十個(gè)數(shù)字組成,基數(shù)為 10。例如:123、45、0 等都是十進(jìn)制數(shù)。在 C 語(yǔ)言中,直接書(shū)寫(xiě)的整型常量如果沒(méi)有特殊的前綴或后綴,默認(rèn)就是十進(jìn)制數(shù)。
二進(jìn)制(Binary)
二進(jìn)制只有 0 和 1 兩個(gè)數(shù)字,基數(shù)為 2。在 C 語(yǔ)言中,二進(jìn)制數(shù)可以用0b或0B作為前綴來(lái)表示(C99 標(biāo)準(zhǔn)引入)。例如:0b1010表示十進(jìn)制的 10。
八進(jìn)制(Octal)
八進(jìn)制由 0 - 7 這八個(gè)數(shù)字組成,基數(shù)為 8。在 C 語(yǔ)言中,八進(jìn)制數(shù)用數(shù)字 0 作為前綴。例如:012表示十進(jìn)制的 10,因?yàn)椤?/p>
十六進(jìn)制(Hexadecimal)
十六進(jìn)制由 0 - 9 以及 A - F(或 a - f)這十六個(gè)字符組成,基數(shù)為 16。其中 A - F(a - f)分別表示 10 - 15。在 C 語(yǔ)言中,十六進(jìn)制數(shù)用0x或0X作為前綴。例如:0xA表示十進(jìn)制的 10,0xFF表示十進(jìn)制的 255。
三,結(jié)構(gòu)體的用法
結(jié)構(gòu)體的定義
結(jié)構(gòu)體是一種用戶(hù)自定義的數(shù)據(jù)類(lèi)型,用于將不同類(lèi)型的數(shù)據(jù)組合在一起。語(yǔ)法形式如下:
struct結(jié)構(gòu)體名{
數(shù)據(jù)類(lèi)型 成員1;
數(shù)據(jù)類(lèi)型 成員2;
//...
};
例如,定義一個(gè)表示學(xué)生信息的結(jié)構(gòu)體:
struct Student {
char name[20];
int age;
float score;
};
結(jié)構(gòu)體變量的聲明與初始化
聲明
可以在定義結(jié)構(gòu)體類(lèi)型之后聲明結(jié)構(gòu)體變量。例如:
struct Student stu1;
初始化
在聲明結(jié)構(gòu)體變量時(shí)進(jìn)行初始化,可以使用以下方式:對(duì)于普通結(jié)構(gòu)體:
struct Student stu1 = {"Tom", 18, 90.5};
對(duì)于嵌套結(jié)構(gòu)體:
struct Date {
int year;
int month;
int day;
};
struct Student {
char name[20];
int age;
struct Date birthday;
};
struct Student stu2 = {"Jerry", 20, {2003, 5, 10}};
結(jié)構(gòu)體成員的訪問(wèn)
使用.(點(diǎn))運(yùn)算符來(lái)訪問(wèn)結(jié)構(gòu)體變量中的成員。例如:
struct Student stu1 = {"Tom", 18, 90.5};
printf("Name: %s\n", stu1.name);
printf("Age: %d\n", stu1.age);
printf("Score: %.1f\n", stu1.score);
如果是指向結(jié)構(gòu)體的指針,則使用->(箭頭)運(yùn)算符來(lái)訪問(wèn)成員。例如:
struct Student stu1 = {"Tom", 18, 90.5};
struct Student *p = &stu1;
printf("Name: %s\n", p->name);
printf("Age: %d\n", p->age);
printf("Score: %.1f\n", p->score);
結(jié)構(gòu)體數(shù)組
可以定義結(jié)構(gòu)體數(shù)組來(lái)存儲(chǔ)多個(gè)結(jié)構(gòu)體變量。例如:
struct Student students[3];
// 初始化結(jié)構(gòu)體數(shù)組
students[0]= {"Alice", 19, 88.0};
students[1]= {"Bob", 20, 92.0};
students[2]= {"Cindy", 18, 85.0};
// 訪問(wèn)結(jié)構(gòu)體數(shù)組中的成員
for (int i = 0; i < 3; i++) {
printf("Student %d: Name = %s, Age = %d, Score = %.1f\n", i + 1, students[i].name, students[i].age, students[i].score);
}
結(jié)構(gòu)體作為函數(shù)參數(shù)
可以將結(jié)構(gòu)體變量或結(jié)構(gòu)體指針作為函數(shù)參數(shù)傳遞。當(dāng)傳遞結(jié)構(gòu)體變量時(shí),是值傳遞,會(huì)復(fù)制整個(gè)結(jié)構(gòu)體,效率較低。例如:
void printStudent(struct Student stu) {
printf("Name: %s\n", stu.name);
printf("Age: %d\n", stu.age);
printf("Score: %.1f\n", stu.score);
}
struct Student stu1 = {"Tom", 18, 90.5};
printStudent(stu1);
當(dāng)傳遞結(jié)構(gòu)體指針時(shí),是地址傳遞,效率較高。例如:
void printStudentPtr(struct Student *stu) {
printf("Name: %s\n", stu->name);
printf("Age: %d\n", stu->age);
printf("Score: %.1f\n", stu->score);
}
struct Student stu1 = {"Tom", 18, 90.5};
printStudentPtr(&stu1);
結(jié)構(gòu)體在動(dòng)態(tài)內(nèi)存分配中的應(yīng)用
可以使用malloc等函數(shù)動(dòng)態(tài)分配結(jié)構(gòu)體的內(nèi)存空間。例如
struct Student *p = (struct Student *)malloc(sizeof(struct Student));
if (p!= NULL) {
strcpy(p->name, "Jack");
p->age = 21;
p->score = 89.5;
printf("Name: %s\n", p->name);
printf("Age: %d\n", p->age);
printf("Score: %.1f\n", p->score);
free(p);
}
四,動(dòng)態(tài)內(nèi)存分布
malloc函數(shù)
基本用法
malloc函數(shù)用于在堆區(qū)動(dòng)態(tài)分配指定字節(jié)數(shù)的內(nèi)存空間。它的函數(shù)原型為:void *malloc(size_t size);,其中size是需要分配的字節(jié)數(shù),返回值是一個(gè)指向分配內(nèi)存空間起始地址的void *類(lèi)型指針。例如,分配一個(gè)可以存儲(chǔ)一個(gè)整數(shù)的內(nèi)存空間:
#include
#include
int main() {
int *p;
p = (int *)malloc(sizeof(int));
if (p!= NULL) {
*p = 10;
printf("The value stored in the allocated memory is: %d\n", *p);
free(p);
}
return 0;
}
注意事項(xiàng)
使用malloc后,必須檢查返回值是否為NULL,如果為NULL表示內(nèi)存分配失敗。分配的內(nèi)存空間在使用完畢后,應(yīng)該使用free函數(shù)釋放,以避免內(nèi)存泄漏。
calloc函數(shù)
基本用法
calloc函數(shù)用于在堆區(qū)動(dòng)態(tài)分配內(nèi)存空間,并且將分配的內(nèi)存空間初始化為 0。它的函數(shù)原型為:void *calloc(size_t num, size_t size);,其中num是元素個(gè)數(shù),size是每個(gè)元素的字節(jié)數(shù),返回值也是一個(gè)指向分配內(nèi)存空間起始地址的void *類(lèi)型指針。例如,分配一個(gè)可以存儲(chǔ) 5 個(gè)整數(shù)并且初始化為 0 的數(shù)組空間:
#include
#include
int main() {
int *p;
p = (int *)calloc(5, sizeof(int));
if (p!= NULL) {
for (int i = 0; i < 5; i++) {
printf("The value at index %d is: %d\n", i, p[i]);
}
free(p);
}
return 0;
}
與malloc的區(qū)別
除了初始化的區(qū)別外,calloc在分配內(nèi)存時(shí)可能會(huì)比malloc稍慢一些,因?yàn)閏alloc需要額外的操作來(lái)初始化內(nèi)存空間。
realloc函數(shù)
基本用法
realloc函數(shù)用于重新分配已經(jīng)分配的內(nèi)存空間的大小。它的函數(shù)原型為:void *realloc(void *ptr, size_t size);,其中ptr是之前由malloc、calloc或realloc分配的內(nèi)存塊的指針,size是重新分配后的字節(jié)數(shù)。例如,先分配一個(gè)較小的內(nèi)存空間,然后再根據(jù)需要重新分配更大的空間:
#include
#include
int main() {
int *p;
p = (int *)malloc(sizeof(int));
if (p!= NULL) {
*p = 10;
// 重新分配內(nèi)存空間,使其可以存儲(chǔ)3個(gè)整數(shù)
p = (int *)realloc(p, 3 * sizeof(int));
if (p!= NULL) {
p[1]=20;
p[2]=30;
for (int i = 0; i < 3; i++) {
printf("The value at index %d is: %d\n", i, p[i]);
}
free(p);
}
}
return 0;
}
注意事項(xiàng)
如果realloc無(wú)法按要求擴(kuò)展內(nèi)存空間(例如沒(méi)有足夠的連續(xù)內(nèi)存),它可能會(huì)返回NULL,并且原內(nèi)存空間的數(shù)據(jù)可能會(huì)丟失。所以在使用realloc時(shí),應(yīng)該先備份原數(shù)據(jù)。當(dāng)realloc的size參數(shù)為 0 時(shí),功能等效于free函數(shù)。
內(nèi)存釋放 -?free函數(shù)
基本用法
free函數(shù)用于釋放由malloc、calloc或realloc分配的內(nèi)存空間。它的函數(shù)原型為:void free(void *ptr);,其中ptr是要釋放的內(nèi)存塊的指針。例如:
int *p = (int *)malloc(sizeof(int));
if (p!= NULL) {
*p = 5;
// 使用完畢后釋放內(nèi)存
free(p);
p = NULL;
}
注意事項(xiàng)
釋放內(nèi)存后,應(yīng)該將指針賦值為NULL,以避免產(chǎn)生野指針。如果多次釋放同一個(gè)指針或者釋放不是動(dòng)態(tài)分配的內(nèi)存,會(huì)導(dǎo)致未定義行為。
五,字符串函數(shù)及其用法
strlen函數(shù)
功能
計(jì)算字符串的長(zhǎng)度,不包括字符串結(jié)束符'\0'。
函數(shù)原型
size_t strlen(const char *s);
示例用法
#include
#include
int main() {
char str[] = "Hello";
size_t len = strlen(str);
printf("The length of the string is: %zu\n", len);
return 0;
}
strlen返回值為無(wú)符號(hào)整型帶來(lái)的錯(cuò)誤
strcpy函數(shù)
功能
將一個(gè)字符串復(fù)制到另一個(gè)字符串中。
函數(shù)原型
char *strcpy(char *dest, const char *src);
示例用法
#include
#include
int main() {
char dest[20];
char src[] = "Hello";
strcpy(dest, src);
printf("The copied string is: %s\n", dest);
return 0;
}
注意事項(xiàng)
目標(biāo)字符串dest必須有足夠的空間來(lái)容納源字符串src,否則會(huì)導(dǎo)致緩沖區(qū)溢出。
strncpy函數(shù)
功能
與strcpy類(lèi)似,但可以指定最多復(fù)制的字符數(shù)。
函數(shù)原型
char *strncpy(char *dest, const char *src, size_t n);
示例用法
#include
#include
int main() {
char dest[20];
char src[] = "Hello World";
strncpy(dest, src, 5);
dest[5]='\0';
printf("The copied string is: %s\n", dest);
return 0;
}
注意事項(xiàng)
如果src的長(zhǎng)度小于n,dest中剩余的字節(jié)將被填充為'\0';如果src的長(zhǎng)度大于n,則dest將不會(huì)以'\0'結(jié)尾(除非手動(dòng)添加)。
strcmp函數(shù)
功能
比較兩個(gè)字符串。如果兩個(gè)字符串相等,則返回 0;如果第一個(gè)字符串小于第二個(gè)字符串,則返回負(fù)數(shù);如果第一個(gè)字符串大于第二個(gè)字符串,則返回正數(shù)。
函數(shù)原型
int strcmp(const char *s1, const char *s2);
示例用法
#include
#include
int main() {
char s1[] = "abc";
char s2[] = "abd";
int result = strcmp(s1, s2);
if (result < 0) {
printf("s1 is less than s2\n");
} else if (result > 0) {
printf("s1 is greater than s2\n");
} else {
printf("s1 is equal to s2\n");
}
return 0;
}
strncmp函數(shù)
功能
與strcmp類(lèi)似,但只比較前n個(gè)字符。
函數(shù)原型
int strncmp(const char *s1, const char *s2, size_t n);
示例用法
#include
#include
int main() {
char s1[] = "abcdef";
char s2[] = "abcd";
int result = strncmp(s1, s2, 4);
if (result < 0) {
printf("s1 is less than s2\n");
} else if (result > 0) {
printf("s1 is greater than s2\n");
} else {
printf("s1 is equal to s2\n");
}
return 0;
}
strcat函數(shù)
功能
將一個(gè)字符串連接到另一個(gè)字符串的末尾。
函數(shù)原型
char *strcat(char *dest, const char *src);
示例用法
#include
#include
int main() {
char dest[20] = "Hello";
char src[] = " World";
strcat(dest, src);
printf("The concatenated string is: %s\n", dest);
return 0;
}
注意事項(xiàng)
目標(biāo)字符串dest必須有足夠的空間來(lái)容納源字符串src和自身原來(lái)的內(nèi)容,否則會(huì)導(dǎo)致緩沖區(qū)溢出。該函數(shù)不能實(shí)現(xiàn)自己給自己追加,會(huì)導(dǎo)致死循環(huán)!
strncat函數(shù)
功能
與strcat類(lèi)似,但可以指定最多連接的字符數(shù)。
函數(shù)原型
char *strncat(char *dest, const char *src, size_t n);
示例用法
#include
#include
int main() {
char dest[20] = "Hello";
char src[] = " World";
strncat(dest, src, 5);
printf("The concatenated string is: %s\n", dest);
return 0;
}
注意事項(xiàng)
同樣要注意目標(biāo)字符串dest的空間是否足夠。該函數(shù)會(huì)在追加后的字符串末尾補(bǔ)\0
strstr函數(shù)
功能
在一個(gè)字符串中查找另一個(gè)字符串首次出現(xiàn)的位置。如果找到,則返回指向該位置的指針;如果未找到,則返回NULL。
函數(shù)原型
char *strstr(const char *haystack, const char *needle);
示例用法
#include
#include
int main() {
char haystack[] = "This is a test";
char needle[] = "is";
char *result = strstr(haystack, needle);
if (result!= NULL) {
printf("The substring was found at position: %ld\n", result - haystack);
} else {
printf("The substring was not found\n");
}
return 0;
}
柚子快報(bào)邀請(qǐng)碼778899分享:算法 初始C語(yǔ)言
參考閱讀
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。