ヒント:記事を書いた後、目次を自動的に生成できます。生成方法については、右側のヘルプドキュメントを参照してください。
記事のディレクトリ
序文
C言語で最も重要なことは、関数、配列、およびポインターです。ポインターはC言語の中心的なものであり、初心者にとっても最も不親切です。私は初めてポインターを学び、ポインターを回避するのがより難しいことに気付きました。 。する必要はありません。
1つ、機能
C言語での関数の分類:
1.ライブラリ関数
ライブラリ関数はコンパイルされた関数であり、呼び出すだけで済みますが、ライブラリ関数を使用する場合は、#includeに対応するヘッダーファイルをインクルードする必要があります。
2.カスタム機能
一部のコードセグメントはプログラム内で頻繁に呼び出されるため、カスタム関数は自分で作成した関数です。コードセグメントの重複を減らし、コードセグメントの使用率を向上させるために、これらの頻繁に使用される関数は、機能し、メインプログラムの外に置くと、すべての呼び出しに便利です。ただし、使用する前に宣言することを忘れないでください。
3.実際の参加パラメータ
関数に実際に渡されるパラメーターは、実パラメーターと呼ばれます。実際のパラメーターは、定数、変数、式、関数などです。実際のパラメーターがどのような量であっても、これらの値を仮パラメーターに転送するには、関数が呼び出されたときに特定の値が必要です。
仮パラメーターは、関数呼び出し中にのみインスタンス化(割り当てられたメモリー単位)されるため、関数名の後の括弧内の変数を参照します。したがって、これらは仮パラメーターと呼ばれます。関数呼び出しが完了すると、仮パラメーターは自動的に破棄されます。したがって、仮パラメータは関数でのみ有効です。
注:仮パラメーターへの変更は実際のパラメーターには影響しません。最も単純なコードの例を次に示します。
#include<stdio.h>
//void Swap(int *a, int *b)
//{
// int tmp = *a;
// *a = *b;
// *b = tmp;
//}
void Swap(int a, int b)
{
int tmp = a;
a = b;
b = tmp;
}
void main()
{
//实际参数
int a = 100;
int b = 200;
printf("Swap before a = %d, b = %d\n", a, b);
Swap(&a, &b);
printf("Swap After a = %d, b = %d\n", a, b);
}
関数が呼び出された後、2つの値は変更されていません。コメントアウトされた関数はこの関数を実現できます。変更アドレスを使用して、2つの数値間の変換を実現します。
4.ネストされた呼び出しと再帰関数
ネストされた呼び出しは、関数と関数の間で行うことができるネストされた呼び出しですが、関数がまだ宣言されていない場合、別の関数内で呼び出すことはできないことに注意してください。これらの関数を記述し、これらの関数を事前に配置して統合してください。声明、これは良い習慣であり、育成されなければなりません。
自身を呼び出す再帰関数プログラムのプログラミング手法は、再帰と呼ばれます。再帰は、プログラミング言語のアルゴリズムとして広く使用されています。プロセスまたは関数には、その定義または説明でそれ自体を直接または間接的に呼び出す方法があります。通常、大きくて複雑な問題を、解決する元の問題と同様の小さな問題に変換します。再帰的戦略のみ問題を解決するプロセスで必要な複数の反復計算を記述するために使用されます。これにより、プログラムコードの量が大幅に削減されます。再帰についての主な考え方は、物事を小さくすること
です。再帰には2つの必要条件
があります。制限があります。この制限が満たされると、再帰は続行されません。
各再帰呼び出しの後、この制限にますます近づきます。
例:フィボナッチ数を計算する1 1 2 3 5 8
#include<stdio.h>
size_t Fib(int n) //递归方式
{
if (n <= 2)
return 1;
else
return Fib(n - 1) + Fib(n - 2);
}
size_t Fib1(int n) //数组赋值方式
{
if (n <= 2)
return 1;
int fib1 = 1;
int fib2 = 1;
int fib;
//迭代 杜绝栈的溢出
for (int i = 3; i <= n; ++i)
{
fib = fib1 + fib2;
fib1 = fib2;
fib2 = fib;
}
return fib;
}
void main(){
int n;
scanf("%d", &n);
size_t result = Fib(n);
printf("result = %u\n", result);
size_t result1 = Fib1(n);
printf("result = %u\n", result1);
}
ここでは、再帰的と非再帰的の2つの方法が使用されます(オーバーフローの問題を考慮せずに)
例2:関数を書くreverse_string(char * string)(再帰的実装)
string reverse order
#include<stdio.h>
#include<string.h>
void reverse(char *string)//数组作为函数参数的时候,会退化为指针。
{
int len = strlen(string);//求出字符串的长度
if (*string) //不为空
{
char temp = *string;
*string = *(string + len - 1); //将最后一个字符给第一个,第一个保存在temp中,后面再赋值给最后一个
*(string + len - 1) = '\0';
reverse(string + 1); //递归的方式
*(string + len - 1) = temp;
}else
return;
}
int main()
{
char s[10] = "abcde";
reverse(s);
printf("%s\n", s);
return 0;
}
第二に、配列
配列は、同じタイプの要素のコレクションです。
例:整数配列のバブルソートを実装するには
#include<stdio.h>
void main(){
int arr[] = {
0, 1, 2, 6, 4, 8, 12, 3 };
int n = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i<n - 1; ++i) //用于控制比较的趟数
{
for (int j = 0; j<n - i - 1; ++j) //用于控制每一趟的排序
{
if (arr[j] > arr[j + 1])
{
//交换两个数
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
for (int k = 0; k < n; k++){
printf("%d\t", arr[k]);
}
}
スリー、ポインター
コンピュータサイエンスでは、ポインタ(ポインタ)はプログラミング言語のオブジェクトであり、アドレスを使用して、その値はコンピュータメモリの別の場所に格納されている値を直接指します。必要な可変単位はアドレスからわかるので、アドレスは変数単位を指していると言えます。したがって、視覚化されたアドレスは「ポインタ」と呼ばれます。
ポインタは変数であり、アドレスを格納するために使用される変数です。(ポインタに格納されている値はアドレスとして扱われます)。
1.ポインタとポインタタイプ
ポインターのタイプによって、ポインターを逆参照するときの権限(数バイトを操作できる)が決まります。例:char *の
ポインター逆参照は1バイトにしかアクセスできませんが、int *のポインターの逆参照は4バイトにアクセスできます。
ワイルドポインタは、ポインタが指す位置が不明であることを意味します(ランダム、不正確、および明示的に制限されていない)
2.ポインタ操作
ポインタポインタのみ
例:ポインタを引くことで文字列の長さを見つけることができます
#include<stdio.h>
//指针相减
void main()
{
char ar[5] = {
'a', 'b', 'c', 'd', 'e' };
char *end = &ar[5];
char *start = &ar[0];
int len = end - start;
printf("len = %d\n", len);
}
3.ポインター配列
ポインターの配列はポインターの配列です
総括する
関数、配列、ポインターに加えて、さらに重要な演算子もあります。これらはすべてネストされて使用されます。覚える必要はありません。コードを追加することで、慣れることができます。最後に、奇数のバイナリ出力と偶数の例が示されています。
//获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列
#include<stdio.h>
void main(){
int n;
scanf("%d", &n);
int ar[32] = {
0 };//定义一个数组,来存放给出数字的全部二进制位
for (int i = 0; i < 32; i+=2){
if (((n >> i) & 1) == 1)
ar[31 - i] = 1;
}
for (int j = 1; j < 32; j+=2){
if (((n >> j) & 1) == 1)
ar[31 - j] = 1;
}
printf("偶数位为:");
for (int i = 0; i <31; i += 2){
printf("%d", ar[i]);
}
printf("\n");
printf("奇数位为:");
for (int i = 1; i <32; i += 2){
printf("%d", ar[i]);
}
printf("\n");
}