首页 > 其他分享 >cprimerplus代码相关汇总

cprimerplus代码相关汇总

时间:2024-01-24 21:13:12浏览次数:26  
标签:return int 代码 汇总 char cprimerplus printf include void

第一章初识C语言

重点内容

起源:1972,贝尔实验室。继承B语言。

特点:功能强大,应用范围广泛。

设计步骤:1.定义程序目标2.设计程序3.编写代码4.编译5.运行程序6.测试和调试程序7.维护和修改程序

本章小结

C 是强大而简洁的编程语言。它之所以流行,在于自身提供大量的实用编程工具,能很好地控制硬件。而且,与大多数其他程序相比,C程序更容易从一个系统移植到另一个系统。

C是编译型语言。C编译器和链接器是把C语言源代码转换成可执行代码的程序。

用C语言编译可能费力、困难,让你感到沮丧,但是它可以激发你的兴趣,让你兴奋、满意。我们希望你在愉快的学习过程中爱上C。

复习题

对于编程而言,可移植意味着什么?

解释源代码文件、目标代码文件和可执行文件有什么区别?

编程的7个主要步骤是什么?

编译器的任务是什么?

链接器的任务是什么?

编程练习

1.略

 

第二章 C语言概述

重点内容

first.c:

#include<stdio.h>//#include预处理指令

int main(void) {//main第一个被调用的函数

    int num;    //定义变量

        num = 1;

    //给变量赋值

    printf("I am a simple");//调用库函数

    printf("computer \n");

    printf("My favorite number is %d because it is first \n ",num);

    return 0;

}

注释:

/* 这是一条c注释 */

// 这是注释、

变量命名规则:

可以用小写字母、大写字母、数字和下划线,第一个字符必须是字母或下划线,不能是数字开头。

fathm_ft.c

#include<stdio.h>

int main(void) {

    int feet, fathoms;//等于int feet; int fathoms;

    fathoms = 2;

    feet = 6 * fathoms;//6乘以fathoms *==乘

    printf("There are %d feet in %d fathoms!\n",feet,fathoms);

    return 0;

}

two_func.c

#include<stdio.h>

void butler(void);//函数声明

int main(void) {

    printf("I will summon the butler function. \n ");

    butler();//调用函数

    printf("Yes,Bring me some tea and writeable DBDs. \n");

    return 0;

}

void butler(void) {//函数定义

    printf("You rang,sir?\n");

}

错误写法:

int n,int n2,int nn3;

本章小结

C程序由一个或多个函数组成。每个C程序必须包含一个main()函数,这是C程序要调用的第1个函数。

 

第三章 数据和C

scanf() 函数读取用户输入。

数据类型关键字:

int long short unsigned char float double

C90: signed void

C99:  _Bool  _Complex  _Imaginary

划分为两大基本类型: 整数类型浮点数类型

位、字节、字:

计算机最小存储单元(bit) 可以存储0或1。

字节(byte)最常用单位,1字节=8位

   1 byte  =  00000000(8个bit)

   那么二进制 00000000到11111111 转换十进制就是 0到255  

字(word)自然存储单位, 对于8位微型计算机,一个字相当于8位 , 而对于现在的32,64位计算机, 会增至32,64位

进制转换:

十进制111= (1*10^2 + 1*10^1 +1*10^0)  =  (100+10+1) =111

二进制111= (1*2^2 +1*2^1 +1*2^0 ) =  (4+2+1) =7

 

初始化变量:

int dogs,cats=94; //有效, 但是容易产生误解, 不要这样写

格式化输出,

%d对应int类型 ,八进制方式显示: %o,  十六进制方式显示:%x

整数类型:

shortint ;long int ; long long int ; unsigned int; signed ;

c标准对基本数据类型只规定了允许的最小大小。

print2.c

#include<stdio.h>

int main(void) {

    unsigned int un = 3000000000;

    short end = 200;

    long big = 65537;

    long long verybig = 12345678908642;

    printf("un =%u and not %d \n", un, un);

    printf("end=%hd and %d \n ",end,end);

    printf("big = %ld and not %hd\n",big,big);

    printf("verybig =%lld and not %ld \n ",verybig,verybig);

    return 0;

}

char 类型:

1字节,8位,也就是可以表示0到255 个数;

标准ASCII码范围:0到127  ,也就是一个char就可以表示的范围。 ASCII 编码的‘A’对应整数就是65 ;char A='A' 与char A=65 等价;

非打印字符

\a  警报\b 退格\f 换页\n 换行\r 回车\t 水平制表符\v 垂直制表符\\反斜杠\‘ 单引号\" 双引号\? 问号

\0oo八进制\xhh 十六进制

 

浮点型变量:

float  

double

打印输出格式:%f 十进制计数法打印。 %e 指数计数法打印。

long double  对应 %Lf  %Le

浮点数舍入错误:

#include<stdio.h>

 

int main(void) {

    float a, b;

b = 2.0e20 + 1.0;

a = b - 2.0e20;

    printf("%f \n",a);

    return 0;

}

没有得到正确的输出:计算机缺少足够的小数位来完成正确的运算。

类型大小:

#include<stdio.h>

int main(void) {

    printf("Type int has a size of %zd bytes \n",sizeof(int));

    printf("Type char has a size of %zd bytes \n ", sizeof(char));

    printf("Type long has a size of %zd bytes \n ", sizeof(long));

    printf("Type long long has a size of %zd bytes \n ", sizeof(long long));

    printf("Type double has a size of %zd bytes \n ", sizeof(double));

    printf("Type long double has a size of %zd bytes \n ",sizeof(long double));

    return 0;

}

第四章 字符串和格式化输入/输出

 

talkback.c:

#define  _CRT_SECURE_NO_WARNINGS

#include<stdio.h>

#include<string.h>

#define DENSITY 62.4

int main() {

    float weight, volume;

    int size, letters;

    char name[40];

    printf("Hi! What`s your first name? \n");

    scanf("%s", name);//%s:字符串

    printf("%s ,what`s your weight in pounds?\n ",name);

    scanf("%f", &weight);//接收键盘输入

size = sizeof(name);//占用内存大小

letters = strlen(name);//strlen 计算字符串长度 , 忽略 结束字符'\0'

volume = weight / DENSITY;

    printf("Well , %s, your volume is %2.2f cubic feet.\n ",name,volume);

    printf("and we have %d bytes to store it.\n ", size);

    printf("strlen size is %d.\n ", letters);

 return 0;

}

 

C中的字符串一定以空字符结束,'\0' 代表空字符 , 是非打印字符,ASCII码为 0 ,不是数字0;

const 只读。

limits.h

常量

常量

含义

CHAR_BIT

char类型的位数

CHAR_MAX

char类型的最大值

CHAR_MIN

char类型的最小值

SCHAR_MAX

signed char 类型的最大值

SCHAR_MIN

signed char 类型最小值

UCHAR_MAX

unsigned char 类型的最大值

SHRT_MAX

short类型的最大值

SHRT_MIN

short类型的最小值

USHRT_MAX

unsigned short 类型的最大值

INT_MAX

int类型的最大值

INT_MIN

int类型的最小值

UINT_MAX

unsigned int 的最大值

LONG_MAX

long类型的最大值

LONG_MIN

long类型的最小值

ULONG_MAX

unsigned long 类型的最大值

LLONG_MAX

long long类型的最大值

LLONG_MIN

long long类型的最小值

ULLONG_MAX

unsigned long long 类型的最大值

 

float.h:

 

常量

含义

FLT_MANT_DIG

float类型的尾数位数

FLT_DIG

float类型的最少有效数字位数

FLT_MIN_10_EXP

带全部有效数字的float类型的最小负指数(以10为底)

FLT_MAX_10_EXP

float类型的最大正指数(以10为底)

FLT_MIN

保留全部精度的float类型最小正数

FLT_MAX

float类型的最大正数

FLT_EPSILON

1.00和比1.00大的最小float 类型值之间的差值

width.c

#include<stdio.h>

#define PAGES 959

int main(void){

    printf("*%d*\n",PAGES);

    printf("*%2d*\n",PAGES);//占2个宽度

    printf("*%10d*\n",PAGES);//占10个右对齐

    printf("*%-10d*\n",PAGES);//占10个左对齐

    return 0;

}

 

float类型值作为参数时,会被转换成double

第五章 运算符、表达式和语句

 

指数增长:

wheat.c

#include<stdio.h>

#define SQUARES 64

int main(void) {

    const double CROP = 2E16;

    double current, total;

    int count = 1;

    printf("squaregrainstotal");

    printf("fraction of \n ");

    printf("addedgrains");

    printf("world total \n ");

    total = current = 1.0;

    printf("%4d %13.2e %12.2e %12.2e\n",count,current,total,total/CROP);

    while (count<SQUARES)

    {

    count = count + 1;

    current = 2.0 * current;

    total = total + current;

    printf("%4d %13.2e %12.2e %12.2e\n",count,current,total,total/CROP);

    }

    printf("That`s all\n");

    return 0;

 

}

 

除法运算符:/

浮点数除法的结果是浮点数,整数除法的结果是整数。整数没有小数部分,整数除法中结果小数直接被丢弃(截断)。

混合整数和浮点数除法,结果是浮点数(会把俩个数都当作浮点数来计算)。

运算符优先级:

从高到低

运算符

结合律

()

从左往右   

+-(一元)

从右往左  

*     /

从左往右      

+    -   (二元)

从左往右

=

从右往左 ---》            a=b=c=3     先给c赋值

 

 

当运算符共享一个运算对象时,(1+2*3)+和*共享2,优先级决定求值顺序   。1*2+3*4,*号并没有共享一个运算对象,先算第一个1*2还是第二个3*4, 这个跟编译器有关, 不属于结合律。1*2/3  ,*和/ 运算符优先级相同,共享运算符对象3,因此根据结合律, 从左往右。

 

sizeof运算符:

size_t intsize=sizeof(int);

求模运算符:%

13%5=3;

 min_sec.c:

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>

#define SEC_PER_MIN60

int main(void) {

    int sec, min, left;

    printf("Convert seconds to minutes and seconds ! \n ");

    printf("Enter the number of seconds (<0 to quit):\n ");

    scanf("%d",&sec);

    while (sec>0)

    {

    min = sec / SEC_PER_MIN;

    left = sec % SEC_PER_MIN;

    printf("%d seconds is %d minutes,%d seconds . \n ",sec,min,left);

    printf("Enter next value (<=0 to quit):\n ");

    scanf("%d", &sec);

    }

    printf("Done!\n");

    return 0;

}

递增、递减运算符:++--

int i=0;

++i;//前缀模式  先增加1 后使用i

i++;//后缀模式  先使用i 在自增加1

只有“()”比递增递减运算符优先级高,因此,x*y++ ,相当与(x )*(y++) ,而y是先使用, 后递增

 

表达式与值:

表达式 -4+6 得到值 2;c=3+8 得到值 11  ;5>3 得到值 1  ; 6+(c=3+8) 得到值17

副作用:

可以理解为,代码最后都会编译转换为2进制, 每一行二进制代码,cpu当作一个运算或者表达式去计算值。

states=50; 求得值为 50 , 副作用将states值改为50 ;

序列点:

每行代码执行完(“;”结束),就是一个序列点,cpu执行二进制代码时,每次读取都会按一行代码的量去读取并执行, 该行执行完后,在读取下一行(序列点)时, 所有副作用也都生效完成。

类型转换:

convert.c

#include<stdio.h>

int main(void) {

    char ch;

    int i;

    float fl;

    fl = i = ch = 'C';

    printf("ch=%c , i=%d , fl=%2.2f\n",ch,i,fl);//ch=C  i=67(字符C的ascii码值)  fl=67.00 (int转float)

    ch = ch + 1;// 67+1  对应ascii码68, 对应char(1字节)‘D’

    i = fl + 2 * ch;//i=67.00+2*68   67.00+136  203.00f 转int =203

    fl = 2.0 * ch + i;//fl=2.0*68+203  136.00+203   = 339.00

    printf("ch=%c ,i=%d,fl=%2.2f\n",ch,i,fl);//ch=D  i=203  fl=339.00

    ch = 1107;//ch的大小是1字节八位,范围是0到255  1107超出范围 1107的二进制(10001010011) ch只能容纳8位,

    //-----截断后就是01010011(十进制83),对应字符‘S’,也可以1107%256=83, 255 二进制(11111111) 在加1 , 就溢出变为0 。

    printf("Now ch=%c \n",ch);

    ch = 80.89;//截断后=80, 对应‘P’

    printf("Now ch=%c \n",ch);

    return 0;

}

强制类型转换:

  int a=(int)5.44+(int)4.3;

 

第六章 C控制语句:循环

 

cmpflt.c

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>

#include<math.h>

int main(void) {

    const double ANSWER = 3.14159;

    double response;

    printf("What is the value of pi ?\n");

    scanf("%lf",&response);

    while (fabs(response-ANSWER)>0.0001)//fabs返回绝对值 。

    {

    printf("Try again!\n");

    scanf("%lf",&response);

    }

    printf("Close enough!\n");

    return 0;

}

truth.c:

#include<stdio.h>

int main(void) {

    int n = 3;

    while (n)//所有非0值 视为真

    {

    printf("%2d is true \n",n--);//执行3次

    }

    printf("%2d is false \n ",n);

    n = -3;

    while (n)

    {

    printf("%2d is true\n ",n++);//执行3次

    }

    printf("%2d is false \n ",n);

    return 0;

}

运算符优先级:

 

运算符(优先级由高到低)

结合律

()

从左往右

 - + ++ -- sizeof

从右往左

  *   /   %

从左往右

+  -

从左往右

< >  <= >=

从左往右

==  !=

从左往右

=

从右往左

其他赋值运算符:

+= 、-=、*=、/=、%=

逗号运算符:

for(int i=1,b=2;i<10;i++,b++){

}

第七章 C控制语句:分支和跳转

cypher1.c

#include<stdio.h>

#define SPACE ' '

int main(void) {

char ch;

while ((ch=getchar())!='\n')

{

    if (ch == SPACE)

putchar(ch);

    else

putchar(ch + 1);

}

putchar(ch);

return 0;

}

ctype.h

 

函数名

如果是下列参数, 返回真

isalnum()

字母或数字

isalpha()

字母

isblank()

空格、水平制表符或换行符或其他任何空白字符

iscntrl()

控制字符,Ctrl+B

isdigit()

数字

isgraph()

除空格之外的任意可打印字符

islower()

小写字母

isprint()

可打印字符

ispunct()

标点符号(除空格或字母数字字符以外的任何可打印字符)

isspace()

空白字符(空格、换行符、换页符、回车符、垂直制表符、水平制表符)

isupper()

大写字母

isxdigit()

十六进制字符

tolower()

如果是大写字母,返回小写,否则返回原参数

toupper()

如果是小写,返回大写, 否则返回原参数

wordcnt.c:

#include<stdio.h>

#include<ctype.h>

#include<stdbool.h>

#define STOP '|'

int main(void) {

    char c;

    char prev;

    long n_chars = 0L;

    int n_lines = 0;

    int n_words = 0;

    int p_lines = 0;

    bool inword = false;

    printf("Enter text to be analyzed (| to terminate ):\n");

    prev = '\n';

    while ((c=getchar())!=STOP)

    {

    n_chars++;

    if (c == '\n') {

    n_lines++;//遇到换行+1

    }

    if (!isspace(c) && !inword) {//如果c不是空格, 并且inword等于false

    inword = true;

    n_words++;//第一次执行从0 变为1, 下一次遇到空格才会+1

    }

    if (isspace(c) && inword) {

    inword = false;

    }

    prev = c;//如果在行的开头就输入了’|‘ 那么上一个字符一定是’\n‘ ,如果不是’\n‘,说明’|‘没有在一行中的开头位置

    

    }

    if (prev != '\n')p_lines = 1;

    printf("Characters =%ld, words=%d ,lines=%d ,",n_chars,n_words,n_lines);

    printf("partial lines=%d \n",p_lines);

    return 0;

}

条件运算符:

?:

循环辅助:

continue 和 break

animals.c

#include<stdio.h>

#include<ctype.h>

int main(void) {

    char ch;

    printf("Give me a letter of the alphabet,and I will give");

    printf("an animal name \n beginning with that letter\n");

    printf("Please type in a letter ; type # to end my act.\n");

    while ((ch=getchar())!='#')

    {

    if ('\n' == ch) continue;

    if (islower(ch)) {

    switch (ch)

    {

    case 'a':

    printf("argali, a wild sheep of Asia\n");

    break;

    case 'b':

    printf("babirusa,a wild pig of Malay \n");

    break;

    case 'd':

    printf("desman,aquatic,molelike critter \n");

    break;

    case 'e':

    printf("echidna,the spiny anteater\n ");

    break;

    case 'f':

    printf("fisher,brownish \n");

    break;

    

    default:

    printf("That`s a stumper!\n");

    

    }

    }else {

    printf("I recognize only lowercase letters.\n");

    while (getchar()!='\n')

    {

    continue;

    }

    printf("Please type another letter or a #.\n");

    }

    

    }

    printf("Bye\n");

}

swich case 多重标签:

case 'a':

case 'A':

.....break;

第8章 字符输入/输出和输入验证

 

缓冲区:

完全缓冲I/O:当缓冲区被填满时,才刷新缓冲区。

行缓冲I/O:出现换行符,刷新缓冲区。

scanf()会把换行符留在缓冲区,而getchar()不会跳过换行符。

 

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>

void display(char cr, int lines, int width);

int main(void) {

    int ch;

    int rows, cols;

    printf("Enter a character and two integers:\n");

    while ((ch=getchar())!='\n')

    {

    if (scanf("%d %d", &rows, &cols) != 2) {

    break;

    }

    while (getchar()!='\n')//会排除后边一些无效输入,还会将scanf留在缓冲区的换行读取了

{

continue;

}  

    display(ch, rows, cols);

    printf("Enter a character and two integers:\n");

    printf("Enter a newline to quit:\n");

    

    }

    printf("Bye.\n");

    return 0;

}

void display(char cr, int lines, int width) {

    int row, col;

    for ( row = 1; row <= lines; row++)

    {

    for ( col = 1; col <= width; col++)

    {

    putchar(cr);

    }

    putchar('\n');

    }

}

 

第九章 函数

 

recur.c:

#include<stdio.h>

void up_and_down(int);

int main(void) {

    up_and_down(1);

    return 0;

}

void up_and_down(int n) {

    printf("Level %d : n location %p \n",n,&n);

    if (n < 4)

        up_and_down(n + 1);

    printf("LEVEL %d:n location %p\n", n, &n);

}

递归图示:

 

factor.c:

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>

long rfact(int n);

int main(void) {

    int num;

    printf("This program calclates factorials \n ");

    printf("Enter a value in the range 0-12 (q to quit):\n");

    while (scanf("%d",&num)==1)

    {

    if (num < 0) {

    printf("No negative numbers,please \n");

    }

    else if (num > 12) {

    printf("Keep input under 13.\n");

    }

    else {

    

    printf("recursion:%d factorial=%ld\n",num,rfact(num));

    }

    printf("Enter a value in the range 0-12(q to quit):\n");

    }

    printf("Bye. \n");

    return 0;

}

long rfact(int n) {

    long ans;

    if (n > 0)

    ans = n * rfact(n - 1);

    else

    ans = 1;

    return ans;

}

假如n=4

 

 

递归缺点会消耗计算机内存资源,会有大量push、 pop;

第10章 数组和指针(重要)

 

数组初始化:

int ary1[]={1,2,3};

int ary2[4]={1};

int ary3[3]={1,2,3};

int ary4[3]={1,[2]=2};

int n=3;

int ary5[n]={0};

数组名=数组首元素地址

指针:

int  * intptr; 指向int 类型的指针。intptr+1,指向的地址增加一个(int)大小;

order.c:

#include<stdio.h>

int data[2] = { 100,200 };

int moredata[2] = { 300,400 };

int main(void) {

    int* p1, * p2, * p3;

    p1 = p2 = data;

    p3 = moredata;

    printf(" *p1=%d ,*p2=%d *p3=%d \n",*p1,*p2,*p3);

    printf("*p1++=%d,*++p2=%d,(*p3)++=%d\n",*p1++,*++p2,(*p3)++);

    printf("*p1=%d,*p2=%d,*p3=%d \n",*p1,*p2,*p3);

    return 0;

}

 

 

 

指针表示法和数组表示法:

ar[i]和*(ar+i)是等价的,无论ar是指针还是数组。但是只有指针变量时才可以使用++ ,-- 运算符。

ptr_ops.c:

#include<stdio.h>

int main(void) {

int urn[5] = { 100,200,300,400,500 };

    int* ptr1, * ptr2, * ptr3;

    

    ptr1 = urn;

    ptr2 = &urn[2];//指向元素300

    printf("pointer value,dereferenced pointer,pointer addredd:\n");

    printf("ptr1=%p,*ptr1=%d,&ptr1=%p\n", ptr1, *ptr1, &ptr1);//元素100的地址,100,ptr1指针的地址

    ptr3 = ptr1 + 4;//ptr3指向元素500

    printf("\n adding an int to a pointer: \n");

    printf("ptr1+4=%p,*(ptr1+4)=%d\n",ptr1+4,*(ptr1+4));//元素500的地址, 500

    ptr1++;//指向元素200

    printf("\nvalues after ptr1++:\n");

    printf("ptr1=%p,*ptr1=%d,&ptr1=%p\n",ptr1,*ptr1,&ptr1);//元素200的地址,200,ptr1指针的地址

    ptr2--;//指向元素200

    printf("\n values after --ptr2:\n");

    printf("ptr2=%p,*ptr2=%d,&ptr2=%p\n",ptr2,*ptr2,&ptr2);//元素200的地址, 200,ptr2指针地址

    --ptr1;//指向100

    ++ptr2;//指向300

    printf("\nPointers reset to original values:\n");

    printf("ptr1=%p,ptr2=%p\n",ptr1,ptr2);//100元素的地址  300元素的地址

    printf("\n subtracting one pointer from another:\n");

    printf("ptr2=%p,ptr1=%p,ptr2-ptr1=%td\n,",ptr2,ptr1,ptr2-ptr1);//指针相减得到它俩之间的元素个数 2

    printf("\n subtracting an int from a pointer : \n ");

    printf("ptr3=%p,ptr3-2=%p\n",ptr3,ptr3-2);//元素500的地址, 元素300的地址

    return 0;

 

 

}

 

 

指针和多维数组:

int zippo[4][2];

zippo=&zippo[0]   数字组首元素地址, 首元素l类型是 int[];

&zippo[0]=&zippo[0][0] ,  zippo[0]相当于int类型的指针  ,所以zippo[0]+1,指向下一个int元素 , 而zippo 相当于指向俩个int元素的数组的指针,zippo+1指向的是第三个int(zippo[1][0])元素.

zippo1.c:

#include<stdio.h>

int main(void) {

    int zippo[4][2] = {

    {2,4},

    {6,8},

    {1,3},

    {5,7}

    };

    printf("zippo=%p,zippo+1=%p\n",zippo,zippo+1);//数组首元素(int[])地址,+1跳过第一个元素{2,4},指向{6,8};

    printf("zippo[0]=%p, zippo+1=%p \n",zippo[0],zippo[0]+1);//数组首元素(int)地址,+1 跳过元素2,指向元素4;

    printf("*zippo=%p,*zippo+1=%p\n",*zippo,*zippo+1);//同上

    printf("zippo[0][0]=%d\n",zippo[0][0]);//2

    printf("*zippo[0]=%d\n", *zippo[0]);//2

    printf("**zippo=%d\n",**zippo);//2

    printf("zippo[2][1]=%d\n",zippo[2][1]);//3

    printf("*(*(zippo+2)+1)=%d\n", *(*(zippo + 2) + 1));//3

    return 0;

}

 

指向数组的指针:int ary[]={1,2,3};int * arptr=ary;

指向多维数组的指针: int ary[][2]={{1,2},{3,4}}; int (*arptr)[]=ary;

 

复合字面量:

int *pt1=(int [2]){10,20};

 

第11章 字符串和字符串函数

 

字符串以空字符(\0)结尾。

puts()函数:输出字符串,并在末尾加上换行。

字符串字面量(字符串常量)自动在末尾增加‘\0’,表示结束。 属于静态存储,相当于(char*) 指针。

strptr.c:

#include<stdio.h>

int main(void){

    printf("%s ,%p, %c\n","We","are",*"space farers");

    return 0;

}

 

addresses.c:

 #define MSG "I`m special"

#include<stdio.h>

int main() {

    char ar[] = MSG;

    const char* pt = MSG;

    printf("address of \"I`m special\":%p \n","I`m special");//地址与MSG一致,字符串常量在内存中只保存一份

    printf("address ar:%p\n", ar);//复制了一份给了char数组。 所以地址不一样

    printf("address pt:%p\n", pt);//指针地址也与MSG一致

    printf("address pt:%p\n",MSG);//同上

    printf("address of \"I`m special\":%p \n", "I`m special");//同上

 

}

 

scanf()的“%s” 只能读取一个单词, 有时候需要读取一整行,这时候可以用gets()函数。gets()读取整行输入,直到遇到换行符,然后丢弃换行符,存储其余的字符,并在末尾增加一个空字符。

经常和puts()组合使用。puts()用于显示字符,并在末尾增加换行符。

gets()函数存在的问题: 不会检查接受字符数组的长度是否足够, 输入的字符过长会导致缓冲区溢出,从而会引起程序异常。

gets()的替代品:

fgets(),C11新增gets_s() 也可以替代。

fgets()和fputs()经常在一起使用。fgets()接受3个参数, 第2个表明读入的最大数量,第3个参数知名要写入的文件,如果是显示器, 使用stdout。读入错误返回null,成功返回第一个参数的地址。fgets()会保存换行。

fputs()不会在字符串末尾增加换行符。

fgets1.c:

#include<stdio.h>

#define STLEN 10

int main() {

    char words[STLEN];

    int i;

    puts("Enter strings(empty line to quit):");

    while (fgets(words,STLEN,stdin)!=NULL&&words[0]!='\n')

    {

    i = 0;

    

    while (words[i]!='\n'&&words[i]!='\0')//读取的字符最后如果是换行,那说明读取了一整行,如果是‘\0’,那就是没有读完。

    {

    i++;

    }

    if (words[i] == '\n')//如果整行读完,把换行替换结束符。

    words[i] = '\0';

    else

    while (getchar()!='\n')//如果没读取完, 那就继续读取, 直到遇到换行。

    {

    continue;

    }

    puts(words);

    }

    puts("done");

    return 0;

 

 

}

gets_s()与fgets()的区别:

gets_s()只从标准输入中读取数据,不需要第3个参数.

如果gets_s()读到换行符,会丢弃它而不是存储它。

如果gets_s()读到最大字符没有读到换行符,会执行一下几步。首页把目标数组中的首字符设置空字符,读取并丢弃随后的输入,直至读到换行符或文件结尾,然后返回空指针。接着调用依赖实现的“处理函数”,可能会中止或退出程序。

scanf() 函数返回一个整数值,该值等于scanf()成功读取的项数或EOF.

fputs()和puts()区别:

fputs()函数的第2个参数指明要写入数据的文件。 如果要打印在显示器上,可以stdout作为参数。

fputs()不会在输出的末尾增加换行符。

字符串函数:

strlen()计算字符串长度, 不包含‘\0’;

strcat()拼接字符串,接受2个字符串作为参数,把第2个字符串的备份附加在第1个字符串末尾,并把拼接后的新字符串作为第1个字符串,第2个字符串不变。

 strcat()无法检查第1个数组是否能容纳第2个字符串。如果第一个参数空间不够大,多出来的字符就会溢出,造成程序异常。

strncat()接受3个参数, 第3个参数指定了最大添加字符数。

strcmp()函数比较的是字符串,不是整个数组。如果第一个字符串位于第2个字符串的前面,strcmp返回负数;反之返回正数;相同返回0;

strncmp()第3个参数指定字符数。

strcpy(),strncpy()  拷贝字符串,strcpy和strcat都有同样的问题,它们都不能检查目标空间是否能容纳源字符串的副本。strncpy()更安全。

sprintf() 将数据写入字符串。

还有很多....

 

第12章 存储类别、链接和内存管理

 

作用域:

块作用域、函数作用域、函数原型作用域或文件作用域。

链接:

外部链接、内部链接或无链接。

存储期:

静态存储期、线程存储期、自动存储期、动态分配存储期。

分配内存:

malloc()和free()

calloc()

const类型限定符:

const float * pf;//pf是一个const指针。

float const pfc;//与const float  *pfc;相同

第13章 文件输入/输出

标准文件:

c程序会自动打开3个文件,它们被称为标准输入、标准输出和标准错误输出。

fopen()函数:

模式字符串

含义

r

以读模式打开文件

w

以写模式打开文件,把现有文件长度截为0,如果文件不存在,则创建一个新文件

a

以写模式打开文件,在现有文件末尾添加内容,如果文件不存在,则创建一个新文件

r+

以更新模式打开文件(读、写)

w+

以更新模式打开文件(读、写),如果文件存在,则将其长度截为 0;如果文件不存在,则创建一个新文件

a+

以更新模式打开文件(读、写),在现有文件的末尾添加内容,如果文件不存在则创建一个新文件;可以读整个文件,但是只能从末尾添加内容。

rb wb ab rb+ r+b wb+ w+b ab+ a+b

与上一个模式类似,但是以二进制模式而不是文件模式打开文件

wx wbx  w+x wb+x  w+bx

独占模式

 

以 ”w"模式打开,该文件内容都会被删除。

getc()和putc():

getc()和putc()与getchar()、putchar()类似,不同的是,getc和putc需要文件指针参数。

fclose()关闭文件。

文件I/O:

fprintf() 、fscanf()、fgets()、 fputs().

随机访问:

fseek()打开文件指针直接移动到任意字节处、ftell()返回long类型值,表示文件当前位置;

SEEK_SET 文件开始处;SEEK_CUR:当前位置;SEEK_END 文件末尾;

fseek(fp,0L,SEEK_SET) //定位至文件开始处

fseek(fp,10L,SEEK_SET)//定位至文件中第10个字节

fseek(fp,2L,SEEK_CUR);//从文件当前位置前移2个字节

fseek(fp,0L,SEEK_END);定位至文件结尾

fseek(fp,-10L,SEEK_END);//从文件结尾处回退10个字节

fgetpos()和fsetpos()函数:

fseek()和tell()的问题是,把文件大小限制在Long类型能表示的范围。而fgetpos()和fsetpos()使用fpos_t类型,它不是基本类型,是文件定位类型。

成功返回0 , 失败返回非0.

ungetc(int c ,FILE *fp)函数:

把c指定的字符放回输入流中。

fflush()函数,刷新缓冲区

setvbuf()函数,创建缓冲区

fread()、fwrite()

 

第 14 章 结构和其他数据形式

book.c

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>

#include<string.h>

char* s_gets(char* st, int n);

#define MAXTITL 41

#define MAXAUTL 31

struct book

{

char title[MAXTITL];

char author[MAXAUTL];

float value;

};

int main(void) {

    struct book library;

    printf("Please enter the book title \n");

    s_gets(library.title,MAXTITL);

    printf("Now enter the author.\n");

    s_gets(library.author,MAXAUTL);

    printf("Now enter the value \n");

    scanf("%f",&library.value);

    printf("%s by %s:$%.2f\n", library.title, library.author, library.value);

    printf("%s:\"%s\"($%.2f)\n",library.author,library.title,library.value);

    printf("Done.\n");

    return 0;

}

char* s_gets(char* st, int n) {

    char* ret_val;

    char* find;

    ret_val = fgets(st,n,stdin);

    if (ret_val) {

    find = strchr(st, '\n');

    if (find)

    *find = '\0';

    else

    while (getchar()!='\n')

    {

    continue;

    }

    }

    return ret_val;

}

联合:

union,能在同一个内存中存储不同的数据类型(不是同时存储)。

枚举:

enum,实际上,enum常量是int类型。

typedef:

为某一类型自定义名称。

函数指针:

void ToUpper(char *);

void (*pf)(char *);

       pf=ToUpper;

第 15 章  位操作

取反: ~

按位与:&

按位或:|

按位异或:^

左移:<<

右移:>>

 

第 16 章 c预处理器和c库

预处理指令:

#define、#include、#ifdef、#else、#endif、#ifndef 、#if、#elif、#line、#error、#pargma

#define 中使用参数:

#define SQUARE(X) X*X

int x=5;

int z;

z=SQUARE(x);//替换为  z=5*5;

SQUARE(x+2);//替换为 x+2*x+2

预定义宏:

 

含义

__DATE__

预处理的日期

__FILE__

表示当前源代码文件名的字符串字面量

__LINE__

表示当前源代码文件中行号的整型常量

__STDC__

设置为1时,表示实现遵循C标准

__STDC_HOSTED__

本机环境设置为1;否则设置为0

__STDC_VERSION__

支持C99标准,设置为199901L;支持C11标准,设置为201112:

__TIME__

翻译代码的时间,格式为:“hh:mm:ss”

 

string.h中的memcpy()和memove():

void*  memcpy(void  restrict s1,const void * restict s2,size_t  n);

void* memmove(void *s1,const void  *s2,size_t n);

都是从s2指向的位置拷贝n字节到s1 指向的位置,而且返回s1的值。不同的是:memcpy()的参数带关键在restrict,即假设着来个内存区域之间没有重叠,memmove()没有这样的假设。

 

可变参数:stdarg.h

void f1(int n,...);

va_list ap;声明一个存储参数的对象

va_arg(ap,double);//检索第一个参数

va_end(ap);//清理工作

第 17 章 高级数据表示

 

链表

struct film{

char title[100];

int rating;

struct film * next;

}

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#include<stdlib.h>

#include<string.h>

#define TSIZE 45

struct film

{

char title[TSIZE];

int rating;

struct film* next;

};

char* s_gets(char* st, int n);

int main(void) {

    struct film* head = NULL;

    struct film* prev, * current;

    char input[TSIZE];

    puts("Enter first movie title:");

    prev = NULL;

    while (s_gets(input,TSIZE)!=NULL&&input[0]!='\0')

    {

    current = (struct film*)malloc(sizeof(struct film));

    

    

    if (head == NULL) {

    head = current;

    }

    else {

    prev->next = current;

    }

    current->next = NULL;

    strcpy(current->title,input);

    puts("Enter your rating <0-10> :");

    scanf("%d", ¤t->rating);

    while (getchar()!='\n')

    {

    continue;

    }

    puts("Enter next movie title(empty line to stop):");

    prev = current;

    }

    if (head == NULL) {

    printf("no data entered.");

    }

    else {

    printf("Here is the movie list :\n");

    }

    current = head;

    while (current!=NULL)

    {

    printf("Movie :%s Rating:%d\n", current->title, current->rating);

    current = current->next;

    }

    current = head;

    while (current!=NULL)

    {

    head = current->next;

    free(current);

    current = head;

    }

    printf("Bye!\n");

    return 0;

    }

    char* s_gets(char* st, int n) {

    char* ret_val;

    char* find;

    ret_val = fgets(st, n, stdin);

    if (ret_val) {

    find = strchr(st, '\n');

    if (find)*find = '\0';

    else

    while (getchar()!='\n')

    {

    continue;

    }

    }

    return ret_val;

}

list.h

#ifndef LIST_H_

#define LIST_H_

#include<stdbool.h>

#define TSIZE 45

struct film {

char title[TSIZE];

int rating;

};

typedef struct film Item;

typedef struct node {

Item item;

struct node* next;

}Node;

typedef Node* List;

//初始化链表

void InitializeList(List* plist);

//确定链表是否为空

bool ListIsEmpty(const List* plist);

//确定链表是否已满

bool ListIsFull(const List* plist);

//确定链表中的项数,plist指向一个已初始化的链表

unsigned int ListItemCount(const List* plist);

//在链表的末尾添加项

bool AddItem(Item item, List* plist);

//把函数作用于链表中的每一项

void Traverce(const List* plist, void(*pfun)(Item item));

//释放已分配的内存(如果有的话)

void EmptyThenList(List* plist);

#endif // !LIST_H_

list.c

#include<stdio.h>

#include<stdlib.h>

#include"list.h"

 

static void CopyToNode(Item item, Node* pnode);

//初始化链表

void InitializeList(List* plist) {

*plist = NULL;

}

//确定链表是否为空

bool ListIsEmpty(const List* plist) {

if (*plist == NULL) {

return true;

}

return false;

}

//确定链表是否已满

bool ListIsFull(const List* plist) {

    Node* pt;

    bool full;

    pt = (Node*)malloc(sizeof(Node));

    if (pt == NULL) {

    full = true;

    }

    else {

    full = false;

    }

    free(pt);

    return full;

}

//确定链表中的项数,plist指向一个已初始化的链表

unsigned int ListItemCount(const List* plist) {

    unsigned int count = 0;

    Node* pnode = *plist;

    while (pnode!=NULL)

    {

    ++count;

    pnode = pnode->next;

    }

    return count;

}

//在链表的末尾添加项

bool AddItem(Item item, List* plist) {

    Node* pnew;

    Node* scan = *plist;

    pnew = (Node*)malloc(sizeof(Node));

    if (pnew == NULL)return false;

    CopyToNode(item, pnew);//将item的值赋给Node结构的pnew

    pnew->next = NULL;

    if (scan == NULL) {//如果是第一次添加,将pnew当作头节点

    *plist = pnew;

    }

    else {//不是第一次添加,将pnew添加到最后

    while (scan->next!=NULL)

    {

    scan = scan->next;

    }

    scan->next = pnew;

    }

    return true;

}

//把函数作用于链表中的每一项

void Traverce(const List* plist, void(*pfun)(Item item)) {

    Node* pnode = *plist;

    while (pnode!=NULL)

    {

    (*pfun)(pnode->item);

    pnode = pnode->next;

    }

    }

    //释放已分配的内存(如果有的话)

    void EmptyThenList(List* plist) {

    Node* psave;

    while (*plist!=NULL)

    {

    psave = (*plist)->next;

    free(*plist);

    *plist = psave;

    }

}

static void CopyToNode(Item item, Node* pnode) {

pnode->item = item;

}

films3.c

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include"list.h"

void showmives(Item item);

char* s_gets(char * st,int n);

int main(void) {

    List movies;

    Item temp;

    InitializeList(&movies);

    if (ListIsFull(&movies)) {

    fprintf(stderr, "No memory available!Bye!\n");

    exit(1);

    }

    puts("Enter first movie title:");

    while (s_gets(temp.title,TSIZE)!=NULL&& temp.title[0]!='\0')

    {

    puts("Enter your rating<0-10>:");

    scanf("%d",&temp.rating);

    while (getchar()!='\n')

    {

    continue;

    }

    if (AddItem(temp, &movies) == false) {

    fprintf(stderr, "Problem allocating memory\n");

    break;

    }

    if (ListIsFull(&movies)) {

    puts("The list is now full.");

    break;

    }

    puts("Enter next movie title(empty line to stop):");

    }

    if (ListIsEmpty(&movies)) {

    printf("No data entered.");

    }

    else {

    printf("Here is the movie list :\n");

    Traverce(&movies, showmives);

    }

    printf("You entered %d movies.\n", ListItemCount(&movies));

    EmptyThenList(&movies);

    printf("Bye!\n");

    return 0;

}

void showmives(Item item) {

    printf("Movie:%s Rating: %d \n", item.title, item.rating);

}

char* s_gets(char* st, int n) {

    char* ret_val;

    char* find;

    ret_val = fgets(st, n, stdin);

    if (ret_val) {

    find = strchr(st, '\n');

    if (find)

    *find = '\0';

    else

    {

    while (getchar()!='\n')

    {

    continue;

    }

    }

    }

    return ret_val;

}

 

队列:

新项只能添加到链表的末尾。只能从开头移除项,先进先出。

 

queue.h:

#ifndef _QUEUE_H_

#define _QUEUE_H_

#include<stdbool.h>

typedef int Item;

#define MAXQUEUE 10

typedef struct node {

Item item;

struct node* next;

}Node;

 

typedef struct queue {

Node* front;

Node* rear;

int items;

}Queue;

//初始化队列

void InitializeQueue(Queue* pq);

//检查队列是否已满

bool QueueIsFull(const Queue* pq);

//检查队列是否为空

bool QueueIsEmpty(const Queue* pq);

//确定队列中的项数

int QueueItemCount(const Queue* pq);

//在队列末尾添加项

bool Enqueue(Item item, Queue* pq);

//从队列的开头删除项

bool DeQueue(Item* pitem, Queue* pq);

//清空队列

void EmptyTheQueue(Queue* pq);

#endif // !_QUEUE_H_

queue.c:

#include<stdio.h>

#include<stdlib.h>

#include"queue.h"

static void CopyToNode(Item item, Node* pn);

static void CopyToItem(Node* pn, Item* pi);

 

//初始化队列

void InitializeQueue(Queue* pq) {

pq->front = pq->rear = NULL;

pq->items = 0;

}

//检查队列是否已满

bool QueueIsFull(const Queue* pq) {

return pq->items == MAXQUEUE;

}

//检查队列是否为空

bool QueueIsEmpty(const Queue* pq) {

return pq->items == 0;

}

//确定队列中的项数

int QueueItemCount(const Queue* pq) {

return pq->items;

}

//在队列末尾添加项

bool Enqueue(Item item, Queue* pq) {

    Node* pnew;

    if (QueueIsFull(pq)) {

    return false;

    }

    pnew = (Node*)malloc(sizeof(Node));

    if (pnew == NULL) {

    fprintf(stderr, "Unable to allocate memory!\n");

    exit(1);

    }

    CopyToNode(item, pnew);

    pnew->next = NULL;

    if (QueueIsEmpty(pq)) {

    pq->front = pnew;

    }

    else {

    pq->rear->next = pnew;

    }

    pq->rear = pnew;

    pq->items++;

    return true;

 

}

//从队列的开头删除项

bool DeQueue(Item* pitem, Queue* pq) {

    Node* pt;

    if (QueueIsEmpty(pq)) {

    return false;

    }

    CopyToItem(pq->front, pitem);

    pt = pq->front;

    pq->front = pq->front->next;

    free(pt);

    pq->items--;

    if (pq->items == 0) {

    pq->rear = NULL;

    }

    return true;

}

//清空队列

void EmptyTheQueue(Queue* pq) {

    Item dummy;

    while (!QueueIsEmpty(pq))

    {

    DeQueue(&dummy, pq);

    }

    }

    

    static void CopyToNode(Item item, Node* pn) {

    pn->item = item;

    }

    static void CopyToItem(Node* pn, Item* pi) {

    *pi = pn->item;

}

use_q.c:

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>

#include"queue.h"

int main(void) {

    Queue line;

    Item temp;

    char ch;

    InitializeQueue(&line);

    puts("Testing the Queue interface.Type a to add a value,");

    puts("type d to delete a value , and type q to quit.");

    while ((ch=getchar())!='q')

    {

    if (ch != 'a' && ch != 'd') {

    continue;

    }

    if (ch == 'a') {

    printf("Integer to add:");

    scanf("%d", &temp);

    if (!QueueIsFull(&line)) {

    printf("Putting %d into queue \n", temp);

    Enqueue(temp, &line);

    }

    else

    puts("Queue is full!");

    }

    else {

    if (QueueIsEmpty(&line)) {

    puts("Nothing to delete!");

    }

    else {

    DeQueue(&temp, &line);

    printf("Removing %d from queue\n", temp);

    }

    }

    printf("%d items in queue \n ", QueueItemCount(&line));

    puts("Type a to add ,d to delete , q to quit :");

    }

    EmptyTheQueue(&line);

    puts("Bye!");

    return 0;

 

}

 

标签:return,int,代码,汇总,char,cprimerplus,printf,include,void
From: https://www.cnblogs.com/hkf100/p/17985841

相关文章

  • [代码随想录] 第十三天
    226.翻转二叉树[https://leetcode.cn/problems/invert-binary-tree/description/]递归:递归三部曲:①确定递归函数的参数和返回值②确定终止条件③确定单层递归的逻辑/***Definitionforabinarytreenode.*publicclassTreeNode{*intval;*TreeNodeleft;*T......
  • 代码随想录 day29 非递减子序列 全排列 全排列 II
    非递减子序列cpp就业还是太难了还是转java吧好歹这个对双非还友好一些尝试写java的第一天本题关键是理解非递减子序列判断条件需要额外一个数组记录当前元素是否在本树层使用过记录在这个数组就说明用过了全排列本题系统的演示了怎么写全排列和最基本的组合问题的......
  • 百度地图开发使用汇总
    地图开发使用汇总百度官网:https://map.baidu.com/开发平台:https://lbsyun.baidu.com/高德官网:https://www.amap.com/开发平台:https://lbs.amap.com/腾讯官网:https://map.qq.com/开放平台:https://lbs.qq.com/百度地图基本操作应用类型:浏览器javascriptapi应用......
  • Java抛出异常且没有被捕捉的情况下,后面的代码还能运行吗?
    Java有try-catch-finally的异常处理机制,包括以下几种情况:1、不抛出异常,try里面的代码、finally里面的代码、finally以后的代码都将正常执行,而catch里面的代码不会执行。2、抛出异常且被catch捕获,try里面的代码部分执行,catch里面的代码、finally里面的代码、finally以后的代码都将......
  • 代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素。
    704.二分查找题目链接:https://leetcode.cn/problems/binary-search/文章讲解:https://programmercarl.com/0704.二分查找.html简单的二分查找法,核心是认识区间的意义,注意以下几点:middle=low+(low+high)/2;这种写法可以防止溢出。注意low和high的循环条件判断,如果是左闭右闭......
  • day25 代码随想录算法训练营 216. 组合总和 III
    题目:216.组合总和III我的感悟:还是按照之前的套路来。多了一个参数path_sum应该是有两处剪枝,1处横线剪枝,1处纵向剪枝?或者说1处求和剪枝?1处范围剪枝?【疑问】理解难点:不剪枝的已经模的差不多了,剪枝的再看看 自己听了一遍写的:[未剪枝]classSolution:defcombina......
  • Git提交代码注释规范
    feat(新功能):新增代码文件:新功能相关的代码文件、模块等。更新测试文件:添加新功能的测试用例。fix(修复):修改代码文件:包含有问题代码的文件。更新测试文件:修复问题的测试用例。docs(文档):Markdown文件:更新项目文档、README、帮助文件等。注释:更新代码中的注释,提供更详......
  • html 禁止f12调试代码 debugger
    setInterval(()=>{(function(a){return(function(a){return(Function('Function(arguments[0]+"'+a+'")()'))})(a)})('bugger')('de',0,0,(0,0));},1000);js代码放到HTMLscrip标签块中即可......
  • java代码通过百度获取第一条搜索结果代码以及注意事项
    导入依赖:<dependency><groupId>io.github.bonigarcia</groupId><artifactId>webdrivermanager</artifactId><version>4.4.3</version></dependency><de......
  • 深度解析Android APP加固中的必备手段——代码混淆技术
    AndroidAPP加固是优化APK安全性的一种方法,常见的加固方式有混淆代码、加壳、数据加密、动态加载等。下面介绍一下AndroidAPP加固的具体实现方式。混淆代码使用ipaguard工具可以对代码进行混淆,使得反编译出来的代码很难阅读和理解,官网下载ipaguard即可。加固混淆为了保......